Difference between revisions of "Debugger Based Debugging"
Nilayvaish (talk | contribs) (Added separate page on debugging using a debugger) |
(Added SimObject::find entry to the table) |
||
(3 intermediate revisions by one other user not shown) | |||
Line 2: | Line 2: | ||
Ideally, looking at traces should at least allow you to narrow down the range of cycles in which you think something is going wrong. The fastest way to reach that point is to use a <code>DebugEvent</code>, which goes on gem5's event queue and forces entry into the debugger when the specified cycle is reached by sending the process a SIGTRAP signal. You'll need to to start gem5 under the debugger or have the debugger attached to the gem5 process for this to work. | Ideally, looking at traces should at least allow you to narrow down the range of cycles in which you think something is going wrong. The fastest way to reach that point is to use a <code>DebugEvent</code>, which goes on gem5's event queue and forces entry into the debugger when the specified cycle is reached by sending the process a SIGTRAP signal. You'll need to to start gem5 under the debugger or have the debugger attached to the gem5 process for this to work. | ||
− | You can create one or more DebugEvents when you invoke gem5 using the <code>"--debug-break=100"</code> parameter. You can also create new DebugEvents from the debugger prompt using the <code> | + | You can create one or more DebugEvents when you invoke gem5 using the <code>"--debug-break=100"</code> parameter. You can also create new DebugEvents from the debugger prompt using the <code>schedBreak()</code> function. The following example session illustrates both of these approaches: |
<pre> | <pre> | ||
Line 22: | Line 22: | ||
Continuing. | Continuing. | ||
− | (gdb) call | + | (gdb) call schedBreak(3000) |
(gdb) c | (gdb) c | ||
Continuing. | Continuing. | ||
Line 33: | Line 33: | ||
</pre> | </pre> | ||
− | gem5 includes a number of functions specifically intended to be called from the debugger (e.g., using the gdb 'call' command, as in the <code> | + | gem5 includes a number of functions specifically intended to be called from the debugger (e.g., using the gdb 'call' command, as in the <code>schedBreak()</code> example above). Many of these are "dump" functions which display internal simulator data structures. For example, <code>eventq_dump()</code> displays the events scheduled on the main event queue. Most of the other dump functions are associated with particular objects, such as the instruction queue and the ROB in the detailed CPU model. These include: |
{| border="1" cellpadding="10" class="wikitable" | {| border="1" cellpadding="10" class="wikitable" | ||
! function !! Effect | ! function !! Effect | ||
|- | |- | ||
− | | <code> | + | | <code>schedBreak(<tick>)</code> || Schedule a SIGTRAP to occur at <code><tick></code> |
|- | |- | ||
| <code>setDebugFlag("<flag>")</code> || Enable a debug flag from the debugger | | <code>setDebugFlag("<flag>")</code> || Enable a debug flag from the debugger | ||
Line 46: | Line 46: | ||
|- | |- | ||
| <code>takeCheckpoint(<tick>)</code> || Create a checkpoint at cycle <code><tick></code> | | <code>takeCheckpoint(<tick>)</code> || Create a checkpoint at cycle <code><tick></code> | ||
+ | |- | ||
+ | | <code>SimObject::find("system.qualified.name")</code> || Returns the pointer to the object with the specified name | ||
|} | |} | ||
− | + | Additional gdb-accessible features for debugging coherence protocols in the classic memory system are documented [[Classic Memory System#Debugging | here]]. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
==Debugging Python with PDB== | ==Debugging Python with PDB== |
Latest revision as of 10:58, 16 August 2018
If traces alone are not sufficient, you'll need to inspect what gem5 is doing in detail using a debugger (e.g., gdb). You definitely want to use the gem5.debug binary if you reach this point.
Ideally, looking at traces should at least allow you to narrow down the range of cycles in which you think something is going wrong. The fastest way to reach that point is to use a DebugEvent
, which goes on gem5's event queue and forces entry into the debugger when the specified cycle is reached by sending the process a SIGTRAP signal. You'll need to to start gem5 under the debugger or have the debugger attached to the gem5 process for this to work.
You can create one or more DebugEvents when you invoke gem5 using the "--debug-break=100"
parameter. You can also create new DebugEvents from the debugger prompt using the schedBreak()
function. The following example session illustrates both of these approaches:
% gdb m5/build/ALPHA/gem5.debug GNU gdb 6.1 Copyright 2002 Free Software Foundation, Inc. [...] (gdb) run --debug-break=2000 configs/run.py Starting program: /z/stever/bk/m5/build/ALPHA/gem5.debug --debug-break=2000 configs/run.py M5 Simulator System [...] warn: Entering event queue @ 0. Starting simulation... Program received signal SIGTRAP, Trace/breakpoint trap. 0xffffe002 in ?? () (gdb) p curTick $1 = 2000 (gdb) c Continuing. (gdb) call schedBreak(3000) (gdb) c Continuing. Program received signal SIGTRAP, Trace/breakpoint trap. 0xffffe002 in ?? () (gdb) p _curTick $3 = 3000 (gdb)
gem5 includes a number of functions specifically intended to be called from the debugger (e.g., using the gdb 'call' command, as in the schedBreak()
example above). Many of these are "dump" functions which display internal simulator data structures. For example, eventq_dump()
displays the events scheduled on the main event queue. Most of the other dump functions are associated with particular objects, such as the instruction queue and the ROB in the detailed CPU model. These include:
function | Effect |
---|---|
schedBreak(<tick>) |
Schedule a SIGTRAP to occur at <tick>
|
setDebugFlag("<flag>") |
Enable a debug flag from the debugger |
clearDebugFlag("<flag>") |
Disable a debug flags from the debugger |
eventqDump() |
Print out all events on the event queue |
takeCheckpoint(<tick>) |
Create a checkpoint at cycle <tick>
|
SimObject::find("system.qualified.name") |
Returns the pointer to the object with the specified name |
Additional gdb-accessible features for debugging coherence protocols in the classic memory system are documented here.
Debugging Python with PDB
You can debug configuration scripts with the Python debugger (PDB) just as you would other Python scripts. You can enter PDB before your configuration script is executed by giving the --pdb
argument to the gem5 binary. Another approach is to put the following line in your configuration script (e.g., fs.py or se.py) wherever you would like to enter the debugger:
import pdb; pdb.set_trace()
Note that the Python files under src
are compiled in to the gem5 binary, so you must rebuild the binary if you add this line (or make other changes) in these files. Alternatively, you can set the M5_OVERRIDE_PY_SOURCE environment variable to "true" (see src/python/importer.py
).
See the official PDB documentation for more details on using PDB.