Skip to content

Commit 7988eb5

Browse files
committed
14.12小节完成
1 parent 1f2f473 commit 7988eb5

File tree

1 file changed

+106
-100
lines changed

1 file changed

+106
-100
lines changed

source/c14/p12_debugging_basic_program_crashes.rst

Lines changed: 106 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -5,122 +5,128 @@
55
----------
66
问题
77
----------
8-
Your program is broken and you’d like some simple strategies for debugging it.
8+
你的程序奔溃后该怎样去调试它?
99

1010
|
1111
1212
----------
1313
解决方案
1414
----------
15-
If your program is crashing with an exception, running your program as python3 -i
16-
someprogram.py can be a useful tool for simply looking around. The -i option starts
17-
an interactive shell as soon as a program terminates. From there, you can explore the
18-
environment. For example, suppose you have this code:
15+
如果你的程序因为某个异常而奔溃,运行 ``python3 -i someprogram.py`` 可执行简单的调试。
16+
``-i`` 选项可让程序结束后打开一个交互式shell。
17+
然后你就能查看环境,例如,假设你有下面的代码:
1918

20-
# sample.py
19+
.. code-block:: python
2120
22-
def func(n):
23-
return n + 10
21+
# sample.py
2422
25-
func('Hello')
23+
def func(n):
24+
return n + 10
2625
27-
Running python3 -i produces the following:
28-
29-
bash % python3 -i sample.py
30-
Traceback (most recent call last):
31-
File "sample.py", line 6, in <module>
3226
func('Hello')
33-
File "sample.py", line 4, in func
34-
return n + 10
35-
TypeError: Can't convert 'int' object to str implicitly
36-
>>> func(10)
37-
20
38-
>>>
39-
40-
If you don’t see anything obvious, a further step is to launch the Python debugger after
41-
a crash. For example:
42-
43-
>>> import pdb
44-
>>> pdb.pm()
45-
> sample.py(4)func()
46-
-> return n + 10
47-
(Pdb) w
48-
sample.py(6)<module>()
49-
-> func('Hello')
50-
> sample.py(4)func()
51-
-> return n + 10
52-
(Pdb) print n
53-
'Hello'
54-
(Pdb) q
55-
>>>
56-
57-
If your code is deeply buried in an environment where it is difficult to obtain an inter‐
58-
active shell (e.g., in a server), you can often catch errors and produce tracebacks yourself.
59-
For example:
60-
61-
import traceback
62-
import sys
63-
64-
try:
65-
func(arg)
66-
except:
67-
print('**** AN ERROR OCCURRED ****')
68-
traceback.print_exc(file=sys.stderr)
69-
70-
If your program isn’t crashing, but it’s producing wrong answers or you’re mystified by
71-
how it works, there is often nothing wrong with just injecting a few print() calls in
72-
places of interest. However, if you’re going to do that, there are a few related techniques
73-
of interest. First, the traceback.print_stack() function will create a stack track of
74-
your program immediately at that point. For example:
75-
76-
>>> def sample(n):
77-
... if n > 0:
78-
... sample(n-1)
79-
... else:
80-
... traceback.print_stack(file=sys.stderr)
81-
...
82-
>>> sample(5)
83-
File "<stdin>", line 1, in <module>
84-
File "<stdin>", line 3, in sample
85-
File "<stdin>", line 3, in sample
86-
File "<stdin>", line 3, in sample
87-
File "<stdin>", line 3, in sample
88-
File "<stdin>", line 3, in sample
89-
File "<stdin>", line 5, in sample
90-
>>>
91-
92-
Alternatively, you can also manually launch the debugger at any point in your program
93-
using pdb.set_trace() like this:
94-
95-
import pdb
96-
97-
def func(arg):
98-
...
99-
pdb.set_trace()
27+
28+
运行 ``python3 -i sample.py`` 会有类似如下的输出:
29+
30+
::
31+
32+
bash % python3 -i sample.py
33+
Traceback (most recent call last):
34+
File "sample.py", line 6, in <module>
35+
func('Hello')
36+
File "sample.py", line 4, in func
37+
return n + 10
38+
TypeError: Can't convert 'int' object to str implicitly
39+
>>> func(10)
40+
20
41+
>>>
42+
43+
如果你看不到上面这样的,可以在程序奔溃后打开Python的调试器。例如:
44+
45+
::
46+
47+
>>> import pdb
48+
>>> pdb.pm()
49+
> sample.py(4)func()
50+
-> return n + 10
51+
(Pdb) w
52+
sample.py(6)<module>()
53+
-> func('Hello')
54+
> sample.py(4)func()
55+
-> return n + 10
56+
(Pdb) print n
57+
'Hello'
58+
(Pdb) q
59+
>>>
60+
61+
如果你的代码所在的环境很难获取交互shell(比如在某个服务器上面),
62+
通常可以捕获异常后自己打印跟踪信息。例如:
63+
64+
.. code-block:: python
65+
66+
import traceback
67+
import sys
68+
69+
try:
70+
func(arg)
71+
except:
72+
print('**** AN ERROR OCCURRED ****')
73+
traceback.print_exc(file=sys.stderr)
74+
75+
要是你的程序没有奔溃,而只是产生了一些你看不懂的结果,
76+
你在感兴趣的地方插入一下 ``print()`` 语句也是个不错的选择。
77+
不过,要是你打算这样做,有一些小技巧可以帮助你。
78+
首先,``traceback.print_stack()`` 函数会你程序运行到那个点的时候创建一个跟踪栈。例如:
79+
80+
::
81+
82+
>>> def sample(n):
83+
... if n > 0:
84+
... sample(n-1)
85+
... else:
86+
... traceback.print_stack(file=sys.stderr)
10087
...
88+
>>> sample(5)
89+
File "<stdin>", line 1, in <module>
90+
File "<stdin>", line 3, in sample
91+
File "<stdin>", line 3, in sample
92+
File "<stdin>", line 3, in sample
93+
File "<stdin>", line 3, in sample
94+
File "<stdin>", line 3, in sample
95+
File "<stdin>", line 5, in sample
96+
>>>
97+
98+
另外,你还可以像下面这样使用 ``pdb.set_trace()`` 在任何地方手动的启动调试器:
99+
100+
.. code-block:: python
101+
102+
import pdb
101103
102-
This can be a useful technique for poking around in the internals of a large program
103-
and answering questions about the control flow or arguments to functions. For instance,
104-
once the debugger starts, you can inspect variables using print or type a command such
105-
as w to get the stack traceback.
104+
def func(arg):
105+
...
106+
pdb.set_trace()
107+
...
108+
109+
当程序比较大二你想调试控制流程以及函数参数的时候这个就比较有用了。
110+
例如,一旦调试器开始运行,你就能够使用 ``print`` 来观测变量值或敲击某个命令比如 ``w`` 来获取追踪信息。
106111

107112
|
108113
109114
----------
110115
讨论
111116
----------
112-
Don’t make debugging more complicated than it needs to be. Simple errors can often
113-
be resolved by merely knowing how to read program tracebacks (e.g., the actual error
114-
is usually the last line of the traceback). Inserting a few selected print() functions in
115-
your code can also work well if you’re in the process of developing it and you simply
116-
want some diagnostics (just remember to remove the statements later).
117-
A common use of the debugger is to inspect variables inside a function that has crashed.
118-
Knowing how to enter the debugger after such a crash has occurred is a useful skill to
119-
know.
120-
Inserting statements such as pdb.set_trace() can be useful if you’re trying to unravel
121-
an extremely complicated program where the underlying control flow isn’t obvious.
122-
Essentially, the program will run until it hits the set_trace() call, at which point it will
123-
immediately enter the debugger. From there, you can try to make more sense of it.
124-
If you’re using an IDE for Python development, the IDE will typically provide its own
125-
debugging interface on top of or in place of pdb. Consult the manual for your IDE for
126-
more information.
117+
不要将调试弄的过于复杂化。一些简单的错误只需要观察程序堆栈信息就能知道了,
118+
实际的错误一般是堆栈的最后一行。
119+
你在开发的时候,也可以在你需要调试的地方插入一下 ``print()``
120+
函数来诊断信息(只需要最后发布的时候删除这些打印语句即可)。
121+
122+
调试器的一个常见用法是观测某个已经奔溃的函数中的变量。
123+
知道怎样在函数奔溃后进入调试器是一个很有用的技能。
124+
125+
当你想解剖一个非常复杂的程序,底层的控制逻辑你不是很清楚的时候,
126+
插入 ``pdb.set_trace()`` 这样的语句就很有用了。
127+
128+
实际上,程序会一直运行到碰到 ``set_trace()`` 语句位置,然后立马进入调试器。
129+
然后你就可以做更多的事了。
130+
131+
如果你使用IDE来做Python开发,通常IDE都会提供自己的调试器来替代pdb。
132+
更多这方面的信息可以参考你使用的IDE手册。

0 commit comments

Comments
 (0)