开发者

GDB print to file instead of stdout

开发者 https://www.devze.com 2023-03-04 05:50 出处:网络
I am running GDB and want to examine one of those unfortunate god objects. It takes many pages (and I have a 24" monitor turned sideways!) to see the whole thing.

I am running GDB and want to examine one of those unfortunate god objects. It takes many pages (and I have a 24" monitor turned sideways!) to see the whole thing.

For ease of use, I'd like GDB to print the object to a file instead of the screen so that I can open it in vi and move around with ease.

With all of GDB's versatility, there must be a way to do this, rig开发者_Python百科ht?


You need to enable logging:

(gdb) set logging on

Now GDB will log to ./gdb.txt. You can tell it which file to use:

(gdb) set logging file my_god_object.log

And you can examine the current logging configuration:

(gdb) show logging


Extending on @qubodup's answer

gdb core.3599 -ex bt -ex quit |& tee backtrace.log

the -ex switch runs a gdb command. So the above loads the core file, runs bt command, then quit command. Output is written to backtrace.log and also on the screen.

Another useful gdb invocation (giving stacktrace with local variables from all threads) is

gdb core.3599 -ex 'thread apply all bt full' -ex quit


I've found that you can redirect the output from gdb to a file via the run command:

(gdb) run > outfile


From https://sourceware.org/gdb/onlinedocs/gdb/Logging-Output.html:

You may want to save the output of gdb commands to a file. There are several commands to control gdb's logging.

set logging on

Enable logging.

set logging off

Disable logging.

set logging file file

Change the name of the current logfile. The default logfile is gdb.txt.

set logging overwrite [on|off]

By default, gdb will append to the logfile. Set overwrite if you want set logging on to overwrite the logfile instead.

set logging redirect [on|off]

By default, gdb output will go to both the terminal and the logfile. Set redirect if you want output to go only to the log file.

show logging

Show the current values of the logging settings.


A simple method to log gdb to a file while still seeing the output (which eases writing commands) is to use tee:

gdb command |& tee gdb.log


Although there are many good answers here, I still have to post the only thing that worked for me:

[niko@my-laptop]# gdb MyBinary 2>&1 log.txt

This was the only way to get gdb and binary output into the same log.txt file, while also seeing it on the console.

EDIT:

Caution: Output seems to be partially not synced among the gdb output and the binary output. Can someone confirm? You might want to check whether your telnet/ssh client has a function to log the output that you see in your console.


You've had multiple answers here. They are corrects. I just want to add a command that will help you to collect all the output at once. This really helpful when your collecting a huge backtrace. Before doing any logging configuration, do this:

(gdb)set height 0

I found it on this article: https://askaralikhan.blogspot.com/2016/05/gdb-all-threads-bt-to-file.html?showComment=1584614942454#c4584028195226351332


I had a backtrace that was so long (over 100k lines) that holding down the enter key was taking too long. I found a solution to that:

Andreas Schneider's bt command writes a backtrace to file without any user interaction – just prefix your command with bt .

Here, I've turned it into a script:

#!/usr/bin/env bash
ex=(
    -ex "run"
    -ex "set logging overwrite on" 
    -ex "set logging file gdb.bt" 
    -ex "set logging on" 
    -ex "set pagination off"
    -ex "handle SIG33 pass nostop noprint"
    -ex "echo backtrace:\n"
    -ex "backtrace full"
    -ex "echo \n\nregisters:\n"
    -ex "info registers"
    -ex "echo \n\ncurrent instructions:\n"
    -ex "x/16i \$pc"
    -ex "echo \n\nthreads backtrace:\n"
    -ex "thread apply all backtrace"
    -ex "set logging off"
    -ex "quit"
)
echo 0 | gdb -batch-silent "${ex[@]}" --args "$@"


Redirection of a gdb's command output to a file can be made by using Python (my version of gdb is 8.1.1):

(gdb) python
>with open("/path/to/file/bt.txt", "w") as outfile:
> outfile.write(gdb.execute("bt", to_string=True))
>end

For convenience this functionality can be added as a command to gdb by adding into .gdbinit:

python
import argparse

class RedirOutput(gdb.Command):
    def __init__(self):
        super().__init__("rdr", gdb.COMMAND_USER, gdb.COMPLETE_COMMAND)

    def invoke(self, argstr, from_tty):
        parser = argparse.ArgumentParser()
        parser.add_argument('command', nargs='+')
        parser.add_argument('-o', "--outfile", required=True, help="output file")

        nm = parser.parse_args(argstr.split())

        with open(nm.outfile, "w") as output_file:
            try:
                output_file.write(gdb.execute(' '.join(nm.command), to_string=True))
            except Exception as e:
                print(str(e))

RedirOutput()
end

Variants of usage:

### Inside gdb
(gdb) rdr info -o /absolute/path/info.txt
(gdb) rdr info registers eax -o ./eax.txt
(gdb) rdr bt -o ./bt.txt

Note: if saving in a file is needed for subsequent opening in vim or less for more convenient viewing and paging, then the "file step" is redundant, because gdb's output can be redirected right to these programs, see redirection to less.

0

精彩评论

暂无评论...
验证码 换一张
取 消