Software for Liquid Argon time projection chambers
NOTE: TotalView is a commercial debugger whose license Fermilab used to pay, but it is being replaced by Allinea
The information on totalview is here in case licenses are available from another source.
Simply:
setup totalview
(the full setup line is for me: totalview v8_11_0 -f Linux64bit -z /grid/fermiapp/products/common/db
).
After setting up LArSoft environment for running (in the normal way) on a debug
version and setting up TotalView as well, start with executing:
totalview lar
It should ask immediately for run parameters. Type or copy in the “Arguments” tab something like:
bq. -c prodsingle.fcl -n 5
or anything the job you want to debug requires (noticeably, the input file).
If you want to change the arguments, you can get this window back from Process | Startup Parameters...
menu (or hit
Ready to go… where?
To run the program, just hit the Restart
button, or the Go
button (also in Process | Go
menu, and
Halt
(Process | Halt
menu, and Go
(Process | Go
menu, and Next
(Process | Next
menu, and Step
(Process | Step
menu, and Out
(Process | Out
menu, and If you are new to debuggers you might be surprised by the behaviour of “step”.
For example, hitting on a function call like `std::copy(from.begin(), from.end(), to.begin());` will step first into `from.begin()`, then into `from.end()`, `to.begin()` and, only when all the arguments are resolved, into `std::copy()` (I believe the actual order among the argument is not defined in C standard).
If a function is declared as `std::string upper(std::string s)`, stepping into a call to `upper("Test")` will first step into the conversion of a `char*` (`"Test"`) into a `std::string`.
Execution can be stopped at any point by the use of breakpoints. TotalView has them as a category of action points, actions triggered by some “event” in the program. A break point reacts to the event “starting to execute at that address” with a “Halt” action.
One aspect of debugging code managed by framework is that usually the code we want to debug is hidden in some library, and at the beginning of the run (before we hit “Go”) that code is not known to the debugger.
For example, I want to debug LArG4
module. The best way is to tell TotalView so by “Action Point | At Location” (
At that point, TotalView nicely shows the source code corresponding to the executable.
Actually, I find out I want to dig into Geant4. So I step through “LArG4::produce” into a g4b::G4Helper::G4Run
call, to find myself in the middle of assembly code. In fact, TotalView reads where the source code it from the library (it is in a format called DWARF, for the libraries in ELF format…), and the location stored in there is the one where the source was compiled the first time.
The packages in UPS ship with source code all right, and it’s only matter of telling TotalView to look at them instead of in the original location. So hit “File | Search Paths” (
$tree(${NUTOOLS_DIR}/source)
$tree(${GEANT4_DIR}/source/geant4.9.6.p02/source)
$tree(${ART_DIR}/source)
(one per line). TotalView can use environment directories, and things like NUTOOLS_DIR
are set up by UPS already. Enclosing them in $tree()
makes TotalView search not only that directory but also the subdirectories.
At that point the assembler code yields to some C code and everything is brighter.
To run totalview do
totalview lar -a <insert lar command line options here>
That will start a window that looks like
Click the “OK” button. Another window then appears,
If the display shows assembler code here, then add the ART source to the debugger’s search path: File->“Search Path” (“source” tab), viz:
Note the entry, $tree(${ART_DIR}/source). This will find recursively the sources in the ART product. If you are using a debug-compiled version of ART (the norm) then the assembler will switch to visible source as soon as you click, “OK.” Assuming totalview quits legally this will be saved in your totalview preferences at exit.
The entry ${PATH} is needed, as totalview uses the search path to find the executable, and does not use your environment’s PATH unless it’s on the list.
And click the “Go” button. It will load up shared object libraries as art calls for them. There is a useful “lookup function” feature in the View menu, which will find named functions and display their source after their libraries have been loaded. You can click on a line number with a box around it to set a breakpoint. You can also set breakpoints
Using the Action Point menu in this window. Specifically look under: Action Points->“At Location”, and enter them at the “Named:” prompt while having the “Function or line” box checked. The break points for exceptions are
__cxa_begin_catch
__cxa_end_catch
__cxa_throw
A trick if a bug crashes your program only a short amount of time after the library has been loaded and there isn’t enough time to halt the program and set a breakpoint: If you let the program run to completion, Totalview still has all the libraries loaded in, and you can set the breakpoint you want, and then push the “Restart” button to get the program to start again without reloading libraries.
Once the debugger finds a problem, one can click on the indicated location in memory to see what is stored in the problem variable. The “Tools” menu has useful “evalulate” and “expression list” features.
Sometimes when totalview exits, it leaves your terminal session in a state where your commands are not echoed back — it’s like typing in the dark. To fix this, try
stty echo
#
# TotalView user's configuration file
#
# This is a TotalView script written in TCL, which TotalView[CLI] executes at startup.
#
# add LArSoft standard directories to the search path
dset SOURCE_SEARCH_PATH ${SOURCE_SEARCH_PATH}:\$tree(/uboone/data/users/petrillo/LArSoft/develop/debug_e4/srcs):\$tree(\${ART_DIR}/source/art):\$tree(\${NUTOOLS_DIR}/source):\$tree(\${GEANT4_DIR}/source/geant4.9.6.p02/source)
Questions? ask Gianluca.