杰瑞科技汇

Python debug symbol 如何生成与使用?

Of course! Let's break down Python debug symbols, a crucial topic for debugging.

Python debug symbol 如何生成与使用?-图1
(图片来源网络,侵删)

First, a key clarification: The concept of "debug symbols" in Python is fundamentally different from what you might find in compiled languages like C++ (using .pdb or .dSYM files) or Go.

  • In C/C++: The compiler generates separate debug symbol files that map machine code back to your source code (variables, line numbers, etc.). The debugger loads these files to provide a rich debugging experience.
  • In Python: Python is an interpreted language. The interpreter always has access to the source code because it needs it to run the program. The "debug symbols" are your .py source files themselves.

However, Python has a powerful, built-in debugger that works directly with your source code. This guide will focus on how to use it effectively.


The Core Python Debugging Tool: pdb

Python's standard debugger is pdb, which is a command-line tool. It allows you to step through your code line by line, inspect variables, set breakpoints, and more.

How to Use pdb

You have two primary ways to start a debugging session.

Python debug symbol 如何生成与使用?-图2
(图片来源网络,侵删)

Method 1: Post-mortem Debugging (After a Crash)

This is the most common use case. Your script crashes with a traceback, and you want to inspect the state of the program at the moment it failed.

You can start a post-mortem session by running the Python interpreter with the -m pdb flag on your script.

Example Script (crashy_script.py):

import time
def process_data(data):
    print(f"Processing data: {data}")
    # This will cause a TypeError
    result = data + " is processed"
    return result
def main():
    user_input = "Hello"
    time.sleep(2) # Simulate some work
    processed = process_data(user_input)
    print(processed)
    print("Script finished successfully.")
if __name__ == "__main__":
    main()

Running it with pdb:

Python debug symbol 如何生成与使用?-图3
(图片来源网络,侵删)
python -m pdb crashy_script.py

The Debugging Session:

When you run the command above, pdb will start and run your script until it hits an exception. It will then pause and drop you into the (Pdb) prompt.

$ python -m pdb crashy_script.py
> /path/to/your/crashy_script.py(11)<module>()
-> if __name__ == "__main__":
(Pdb) c  # 'c' for continue. Let it run until it crashes.
Processing data: Hello
Traceback (most recent call last):
  File "/path/to/your/crashy_script.py", line 9, in process_data
    result = data + " is processed"
TypeError: can only concatenate str (not "int") to str
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/usr/lib/python3.10/pdb.py", line 1707, in main
    pdb._run(main_script)
  File "/usr/lib/python3.10/pdb.py", line 1680, in _run
    self.run(code)
  File "/usr/lib/python3.10/bdb.py", line 595, in run
    exec(code, globals)
  File "/path/to/your/crashy_script.py", line 13, in <module>
    main()
  File "/path/to/your/crashy_script.py", line 11, in main
    processed = process_data(user_input)
  File "/path/to/your/crashy_script.py", line 9, in process_data
    result = data + " is processed"
TypeError: can only concatenate str (not "int") to str
> /path/to/your/crashy_script.py(9)process_data()
-> result = data + " is processed"
(Pdb)

Now you are at the point of failure. You can inspect variables:

(Pdb) p data  # 'p' for print. Print the value of 'data'
'Hello'
(Pdb) p data + " is processed"
'Hello is processed'
(Pdb) l  # 'l' for list. Show the current source code.
  4
  5     def process_data(data):
  6         print(f"Processing data: {data}")
  7         # This will cause a TypeError
  8         result = data + " is processed"
  9  ->     return result
 10
 11     def main():
 12         user_input = "Hello"
 13         processed = process_data(user_input)
 14         print(processed)
(Pdb) w  # 'w' for where. Show the stack trace.
  /path/to/your/crashy_script.py(9)process_data()
-> result = data + " is processed"
> /path/to/your/crashy_script.py(13)main()
-> processed = process_data(user_input)
> /path/to/your/crashy_script.py(15)<module>()
-> main()
(Pdb) q  # 'q' for quit. Exit the debugger.

Method 2: Interactive Debugging (Setting Breakpoints)

You can insert a breakpoint directly into your code to pause execution at a specific line.

Modified Script (interactive_script.py):

import time
import pdb # Import the pdb module
def process_data(data):
    print(f"Processing data: {data}")
    pdb.set_trace() # <-- This is the breakpoint!
    result = data + " is processed"
    return result
def main():
    user_input = "Hello"
    time.sleep(2)
    processed = process_data(user_input)
    print(processed)
    print("Script finished successfully.")
if __name__ == "__main__":
    main()

Now, when you run the script normally, it will pause at pdb.set_trace().

python interactive_script.py

The Debugging Session:

$ python interactive_script.py
Processing data: Hello
--Return--
> /path/to/your/interactive_script.py(9)process_data()
-> result = data + " is processed"
(Pdb)

You are now at the breakpoint. You can use all the same commands (p, l, w, c, q, etc.).


Essential pdb Commands

Here are the most common and useful commands:

Command Alias Description
break b Set a breakpoint. b 10 sets a breakpoint at line 10. b function_name sets a breakpoint at the start of a function.
continue c Continue execution until the next breakpoint or the program finishes.
list l List source code around the current line.
next n Execute the current line and move to the next one in the same function.
step s Execute the current line. If it's a function call, step into that function.
return r Continue execution until the current function returns.
pp "Pretty Print". A more readable version of p, great for complex data structures like dictionaries or lists.
print p Print the value of an expression.
quit q Exit the debugger. The program will be terminated.
where w Print the stack trace, showing you how you got to the current line.
help h Get help on any command. h break for help on the break command.

Modern Alternatives to pdb

While pdb is powerful, its command-line interface can be clunky. Modern development often uses graphical debuggers integrated into IDEs.

VS Code (Visual Studio Code)

VS Code has an excellent, built-in debugger that is much more user-friendly.

  1. Install the Python Extension: Make sure you have the official Python extension from Microsoft installed.
  2. Set Breakpoints: Click in the gutter (left-hand margin) next to the line numbers where you want to pause. A red dot will appear.
  3. Start Debugging:
    • Open the "Run and Debug" view (Ctrl+Shift+D or Cmd+Shift+D).
    • Click the "Run and Debug" play icon.
    • Select "Python File" from the dropdown.
  4. Debugging: The program will start and pause at your breakpoints. You can use the debug toolbar at the top to:
    • Continue/Step Over/Step Into/Step Out: Same as pdb.
    • View Variables: A "VARIABLES" panel on the left shows all local and global variables in the current scope.
    • View Call Stack: A "CALL STACK" panel shows the stack trace.
    • View Watch: You can add variables to a "WATCH" panel to monitor their values as you step through the code.

This is the recommended approach for most developers due to its visual nature and ease of use.

PyCharm

PyCharm is a dedicated Python IDE with a world-class debugger.

  1. Set Breakpoints: Just like in VS Code, click in the gutter to set breakpoints.
  2. Start Debugging: Right-click in the editor and select "Debug 'your_script_name'".
  3. Debugging: PyCharm opens a dedicated "Debug" tool window at the bottom, which is packed with features:
    • Frames and Variables view.
    • Watches view.
    • Console to execute Python expressions.
    • A powerful "Evaluate Expression" feature.

ipdb

ipdb is a drop-in replacement for pdb that uses the powerful IPython library. It provides syntax highlighting, tab completion, and a much better command-line experience.

Installation:

pip install ipdb

Usage: Replace import pdb with import ipdb and pdb.set_trace() with ipdb.set_trace(). Or, use the -m ipdb flag:

python -m ipdb your_script.py

Summary

Method What It Is Best For
pdb Python's built-in, command-line debugger. Quick and dirty debugging, server environments without a GUI, automated debugging in scripts.
VS Code / PyCharm Debugger Graphical, interactive debuggers in IDEs. Everyday development. The most powerful and user-friendly way to debug complex applications.
ipdb An enhanced pdb with IPython features. Developers who prefer the terminal but want a better experience than the basic pdb.

For any serious Python development, learning to use the debugger in your IDE (like VS Code or PyCharm) is one of the most valuable skills you can acquire. It will dramatically speed up your debugging process.

分享:
扫描分享到社交APP
上一篇
下一篇