用 GDB 排查 Python 程序故障
admin
2023-07-30 21:56:23
0

某Team在用Python开发一些代码,涉及子进程以及设法消除僵尸进程的需求。实践中他们碰上Python程序非预期退出的现象。最初他们决定用GDB调试Python解释器,查看exit()的源头。我听了之后,觉得这个问题应该用别的调试思路。帮他们排查这次程序故障时,除去原始问题,还衍生了其他问题。
这次的问题相比西安研发中心曾经碰上的Python信号处理问题,有不少基础知识、先验知识是共用的,此处不做再普及,感兴趣的同学可以翻看我以前发过的文章。

下文是一次具体的调试、分析记录。为了简化现场、方便调试,已将原始问题、衍生问题浓缩成DebugPythonWithGDB_6.py、DebugPythonWithGDB_7.py。

$ vi DebugPythonWithGDB_6.py

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 #!/usr/bin/env python# -*- encoding: utf-8 -*-?import sys, os, signal, subprocess, shlex, traceback?def on_SIGCHLD ( signum, frame ) :????print \”[on_SIGCHLD\”????sys.stdout.write( \”signum??= %u\\n\” % signum )????traceback.print_stack( frame )????print os.waitpid( 1, os.WNOHANG )????\”\”\”????try :????????print os.waitpid( -1, os.WNOHANG )????except OSError :????????sys.stdout.write( \’Line[%u]: OSError\\n\’ % sys.exc_info()[2].tb_lineno )????\”\”\”????print \”on_SIGCHLD]\”?def do_more ( count ) :????print \'[do_more() begin %u]\’ % count????os.system( r\’printf \”Child?? = %u\\n\” \” />;/bin/sleep 1\’ )    \”\”\”    #    # 这里存在竞争条件,可以增加触发OSError异常的概率    #    os.system( r\’printf \”Child   = %u\\n\” ;/bin/sleep 1\' )</span></div><div class=????os.system( r\’printf \”Child?? = %u\\n\” \” />;/bin/sleep 1\’ )    os.system( r\’printf \”Child   = %u\\n\” ;/bin/sleep 1\' )</span></div><div class=????os.system( r\’printf \”Child?? = %u\\n\” \” />;/bin/sleep 1\’ )    \”\”\”    print \'[do_more() end %u]\’ % count def main ( prog, args ) :    if 0 == len( args ) :        print \’Usage: %s \’ % prog    else :        sys.stdout.write( \”Parent  = %u\\n\” % os.getpid() )        #        # 本例中,即使有下列代码,Ctrl-C仍然无效。        #        signal.signal( signal.SIGINT, signal.SIG_DFL )        #        # signal.signal( signal.SIGCHLD, signal.SIG_IGN )        #        signal.signal( signal.SIGCHLD, on_SIGCHLD )        #        count   = 0        while True :            #            # 本例中父进程只是一个调度框架,不需要与子进程进行通信,因此不            # 需要特别处理\”stdin=None, stdout=None, stderr=None\”。            #            child   = subprocess.Popen  \\            (                #                # 不要直接用args[0].split(),它在处理单、双引号时不是我们                # 期望的行为。考虑这种例子,ls -l \”/tmp/non exist\”                #                shlex.split( args[0] ),                #                # all file descriptors except 0, 1 and 2 will be closed                # before the child process is executed                #                close_fds   = True,                cwd         = \”/tmp\”            )            sys.stdout.write( \”Child   = %u\\n\” % child.pid )            #            # child.send_signal( signal.SIGTERM )            # child.terminate()            #            child.kill()            #            # child.wait()            #            do_more( count )            count  += 1 if \’__main__\’ == __name__ :    try :        main( os.path.basename( sys.argv[0] ), sys.argv[1:] )    except KeyboardInterrupt :        pass

123456789101112131415161718192021222324252627282930313233 $ python DebugPythonWithGDB_6.py \’python -c \”import time;time.sleep(3600)\”\’Parent  = 10244Child   = 10245[do_more() begin 0][on_SIGCHLDsignum  = 17  File \”DebugPythonWithGDB_6.py\”, line 81, in     main( os.path.basename( sys.argv[0] ), sys.argv[1:] )  File \”DebugPythonWithGDB_6.py\”, line 76, in main    do_more( count )  File \”DebugPythonWithGDB_6.py\”, line 20, in do_more    print \'[do_more() begin %u]\’ % count(10245, 9)on_SIGCHLD]Child   = 10246[on_SIGCHLDsignum  = 17  File \”DebugPythonWithGDB_6.py\”, line 81, in     main( os.path.basename( sys.argv[0] ), sys.argv[1:] )  File \”DebugPythonWithGDB_6.py\”, line 76, in main    do_more( count )  File \”DebugPythonWithGDB_6.py\”, line 21, in do_more    

相关内容

热门资讯

Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...
Apache Doris 2.... 亲爱的社区小伙伴们,我们很高兴地向大家宣布,Apache Doris 2.0.0 版本已于...
python清除字符串里非数字... 本文实例讲述了python清除字符串里非数字字符的方法。分享给大家供大家参考。具体如下: impor...