Backtrace

Differences between revisions 1 and 27 (spanning 26 versions)
Revision 1 as of 2006-05-01 19:18:28
Size: 643
Editor: ottawa-hs-64-26-167-206
Comment:
Revision 27 as of 2008-05-15 14:43:21
Size: 4522
Editor: acrab
Comment:
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
A backtrace shows a listing of which program functions are still active. Since functions are nested when they are called, the program must record where it left one function, to jump into an inner one. It does this on the stack, which we dump for the backtrace.

By getting a backtrace at the point of a bug, a developer may be able to isolate where that bug is, because it will narrow down to the function, or even the line, that caused the erroneous behaviour.

When using KDE the KDE Crash Handler will intercept debugging information. However, it is possible to disable the KDE Crash Handler when you are launching an application by passing the --nocrashhandler argument to the application. For example, 'kget --nocrashhandler' instead of 'kget'.

= Generation =
[[Anchor(generation)]]
Line 3: Line 11:
 1. Make sure the GNU Debugger is installed. {{{
sudo apt-get install gdb
}}}
Line 4: Line 15:
gdb <program> gdb <program> 2>&1 | tee gdb-<program>.txt
Line 6: Line 17:
(gdb) set pagination 0
Line 7: Line 19:
}}} }}} (If the program must run as root, use {{{sudo gdb}}} instead of just {{{gdb}}} above.)
Line 10: Line 22:
(gdb) thread apply all bt }}} (gdb) backtrace full
(gdb) info registers
(gdb) thread apply all backtrace
(gdb) quit
}}}
 1. Attach the complete output from GDB, contained in gdb-<program>.txt, in your bug report. You will find the file in your home directory /home/<username>/.
Line 12: Line 29:
 1. If the output gets very long, you might want to use: {{{
(gdb) set logging file backtrace.txt
= Already running programs =

You can ask GDB to attach to a program that's already running. This is useful for debugging things that start up, but crash when you perform a particular task.

 1. Make sure the GNU Debugger is installed. {{{
sudo apt-get install gdb
}}}

 1. Find the process ID of <program>: {{{
pidof <program>
}}}

 1. Start `gdb`: {{{
gdb 2>&1 | tee gdb-<program>.txt
(gdb) handle SIG33 pass nostop noprint
(gdb) set pagination 0
(gdb) attach <PID>
}}} (If the program is running as root, use {{{sudo gdb}}} instead of just {{{gdb}}} above.)

 1. Continue the <program>: {{{
(gdb) continue
}}}

 1. The program will continue running. Perform any actions necessary to reproduce the crash

 1. Retrieve a backtrace of the crash: {{{
(gdb) backtrace full
(gdb) info registers
(gdb) thread apply all backtrace
(gdb) quit
}}}

 1. Attach the complete output from GDB, contained in gdb-<program>.txt, in your bug report.

Note that you can also set logging to a file like this: {{{
(gdb) set logging file gdb-<program>.txt
Line 15: Line 66:
}}} beforehand. }}}
Line 17: Line 68:
 1. Include the complete output from GDB in your bug report. = Core Files =

You are also able to retrace a core file if you have one produced. (I believe these are disabled by default)

 1. Load the core file into the debugger {{{
 gdb -c CoreDump <corefile> 2>&1 | tee gdb-<program>.txt
}}}

 2. Retrieve a backtrace of the crash: {{{
(gdb) backtrace full
(gdb) info registers
(gdb) thread apply all backtrace
(gdb) quit
}}}

 3. Attach the complete output from GDB, contained in gdb-<program>.txt, in your bug report. You will find the file in your home directory /home/<username>/.

= Other resources =
 * [http://live.gnome.org/GettingTraces Another useful how-to]

= Summary in script form =

You can automate backtrace collection [#generation as described above] using this Bourne shell script:

  * save it somewhere in your $PATH
  * make it executable

{{{
#!/bin/sh

#---------------------------------------------------------------------
usage() {
    cat<<EOF
Usage: ${0} program_name [program_args]

Trace a given program using gdb.

EOF
}

log() {
    echo "${*}" 1>&2
}

die() {
    usage
    log 'error:' ${*}'.'
    exit 1
}


#---------------------------------------------------------------------
test "x${*}" = "x" && die 'no process given'

LOG="/tmp/gdb-`basename ${1}`.txt"
log "outputting trace to '${LOG}'"

exec gdb -batch-silent \
    -ex 'set logging overwrite on' \
    -ex "set logging file ${LOG}" \
    -ex 'set logging on' \
    -ex 'handle SIG33 pass nostop noprint' \
    -ex 'set pagination 0' \
    -ex 'run' \
    -ex 'backtrace full' \
    -ex 'info registers' \
    -ex 'thread apply all backtrace' \
    -ex 'quit' \
    --args ${*} \
    < /dev/null

}}}
----
CategoryBugSquad

A backtrace shows a listing of which program functions are still active. Since functions are nested when they are called, the program must record where it left one function, to jump into an inner one. It does this on the stack, which we dump for the backtrace.

By getting a backtrace at the point of a bug, a developer may be able to isolate where that bug is, because it will narrow down to the function, or even the line, that caused the erroneous behaviour.

When using KDE the KDE Crash Handler will intercept debugging information. However, it is possible to disable the KDE Crash Handler when you are launching an application by passing the --nocrashhandler argument to the application. For example, 'kget --nocrashhandler' instead of 'kget'.

Generation

Anchor(generation) Please ensure you have packages with debug symbols installed. You can do this by following the instructions at DebuggingProgramCrash.

  1. Make sure the GNU Debugger is installed.

    sudo apt-get install gdb
  2. Start the program under control of gdb:

    gdb <program> 2>&1 | tee gdb-<program>.txt
    (gdb) handle SIG33 pass nostop noprint
    (gdb) set pagination 0
    (gdb) run <arguments, if any>

    (If the program must run as root, use sudo gdb instead of just gdb above.)

  3. The program will start. Perform any actions necessary to reproduce the crash
  4. Retrieve a backtrace of the crash:

    (gdb) backtrace full
    (gdb) info registers
    (gdb) thread apply all backtrace
    (gdb) quit
  5. Attach the complete output from GDB, contained in gdb-<program>.txt, in your bug report. You will find the file in your home directory /home/<username>/.

Already running programs

You can ask GDB to attach to a program that's already running. This is useful for debugging things that start up, but crash when you perform a particular task.

  1. Make sure the GNU Debugger is installed.

    sudo apt-get install gdb
  2. Find the process ID of <program>:

    pidof <program>
  3. Start gdb:

    gdb 2>&1 | tee gdb-<program>.txt
    (gdb) handle SIG33 pass nostop noprint
    (gdb) set pagination 0
    (gdb) attach <PID>

    (If the program is running as root, use sudo gdb instead of just gdb above.)

  4. Continue the <program>:

    (gdb) continue
  5. The program will continue running. Perform any actions necessary to reproduce the crash
  6. Retrieve a backtrace of the crash:

    (gdb) backtrace full
    (gdb) info registers
    (gdb) thread apply all backtrace
    (gdb) quit
  7. Attach the complete output from GDB, contained in gdb-<program>.txt, in your bug report.

Note that you can also set logging to a file like this:

(gdb) set logging file gdb-<program>.txt
(gdb) set logging on

Core Files

You are also able to retrace a core file if you have one produced. (I believe these are disabled by default)

  1. Load the core file into the debugger

     gdb -c CoreDump <corefile> 2>&1 | tee gdb-<program>.txt
  2. Retrieve a backtrace of the crash:

    (gdb) backtrace full
    (gdb) info registers
    (gdb) thread apply all backtrace
    (gdb) quit
  3. Attach the complete output from GDB, contained in gdb-<program>.txt, in your bug report. You will find the file in your home directory /home/<username>/.

Other resources

Summary in script form

You can automate backtrace collection [#generation as described above] using this Bourne shell script:

  • save it somewhere in your $PATH
  • make it executable

#---------------------------------------------------------------------
usage() {
    cat<<EOF
Usage: ${0} program_name [program_args]

Trace a given program using gdb.

EOF
}

log() {
    echo "${*}" 1>&2
}

die() {
    usage
    log 'error:' ${*}'.'
    exit 1
}


#---------------------------------------------------------------------
test "x${*}" = "x" && die 'no process given'

LOG="/tmp/gdb-`basename ${1}`.txt"
log "outputting trace to '${LOG}'"

exec gdb -batch-silent \
    -ex 'set logging overwrite on' \
    -ex "set logging file ${LOG}" \
    -ex 'set logging on' \
    -ex 'handle SIG33 pass nostop noprint' \
    -ex 'set pagination 0' \
    -ex 'run' \
    -ex 'backtrace full' \
    -ex 'info registers' \
    -ex 'thread apply all backtrace' \
    -ex 'quit' \
    --args ${*} \
    < /dev/null


CategoryBugSquad

Backtrace (last edited 2022-12-20 22:15:16 by sergiodj)