Make GDB print control flow of functions as they are called

前端 未结 5 684
广开言路
广开言路 2020-12-14 03:09

How do I make gdb print functions of interest as they are called, indented according to how deep in the stack they are?

I want to be able to say something like (made

相关标签:
5条回答
  • 2020-12-14 03:15

    Use the right tool for the job ;)

    How to print the next N executed lines automatically in GDB?

    0 讨论(0)
  • 2020-12-14 03:20

    You may call gdb in batch mode (using -x option), break where you need and ask for backtrace (bt), then you filter the result using grep or egrep.

    Indents are more difficult, however bt output is ordered so you have current function at the top of the trace and main at very bottom.

    So you create file with commands:

    br <function name where to break>
    run
    bt
    kill
    quit
    

    then run gdb <program> -x<command file>

    Filter strings that starts with #<digit> - you get stack trace.

    0 讨论(0)
  • 2020-12-14 03:22

    There's rbreak cmd accepting regular expression for setting breakpoints. You can use:

    (gdb) rbreak Foo.*
    (gdb) rbreak Bar.*
    (gdb) break printf
    

    See this for details on breakpoints.

    Then use commands to print every function as it's called. E.g. let α = the number of the last breakpoint (you can check it with i br if you missed), then do:

    (gdb) commands 1-α
    Type commands for breakpoint(s) 1-α, one per line.
    End with a line saying just "end".
    >silent
    >bt 1
    >c
    >end
    (gdb) 
    

    Some elaboration: silent suppresses unnecessary informational messages, bt 1 prints the last frame of backtrace (i.e. it's the current function), c is a shortcut for continue, to continue execution, and end is just the delimiter of command list.

    NB: if you trace library functions, you may want to wait for lib to get loaded. E.g. set a break to main or whatever function, run app until that point, and only then set breakpoints you wanted.

    0 讨论(0)
  • 2020-12-14 03:31

    Did you see litb's excellent anwser to a similar post here ?

    He uses readelf to get interesting symbols, gdb commands to get the trace, and awk to glue all that.

    Basically what you have to change is to modify his gdb command script to remove the 1 depth from backtrace to see the stack and filter specific functions, and reformat the output with an awk/python/(...) script to present it as a tree. (I admit I'm too lazy to do it now...)

    0 讨论(0)
  • 2020-12-14 03:37

    In your case I would turn to the define command in gdb, which allows you to define a function, which can take up to 10 arguments.

    You can pass in the names of functions to "trace" as arguments to the function you define, or record them all in the function itself. I'd do something like the following

    define functiontrace
    if $arg0
        break $arg0
        commands
            where
            continue
            end
        end
    
    if $arg1
    ...
    

    Arguments to a user-defined function in gdb are referenced as $arg0-$arg9. Alternatively, you could just record every function you wanted to trace in the function, instead of using $arg0-9.

    Note: this will not indent as to depth in the stack trace, but will print the stack trace every time the function is called. I find this approach more useful than strace etc... because it will log any function you want, system, library, local, or otherwise.

    0 讨论(0)
提交回复
热议问题