Segfault
Interpreting segfault messages
For segfault message,
segfault at 10 ip 00007f9bebcca90d sp 00007fffb62705f0 error 4 in libName.so.4.5.2[7f9beb83a000+f6f000]
A segfault due to following a null pointer trying to find code to run (that is, during an instruction fetch).
Error description,
- 'address' (after the 'at') the location in memory the code is trying to access (Here 0x10, which is offset from a pointer, to be set to a valid value but which is instead pointing to 0)
- 'ip' instruction pointer location when the segfault happened, ie. where the code which is trying to do this lives (Here 0x00007f9bebcca90d)
- 'sp' stack pointer (Here 0x00007fffb62705f0
- error An architecture specific error code for page faults (it is not 'errno'). Below on x86.
/*
* Page fault error code bits:
*
* bit 0 == 0: no page found 1: protection fault
* bit 1 == 0: read access 1: write access
* bit 2 == 0: kernel-mode access 1: user-mode access
* bit 3 == 1: use of reserved bit detected
* bit 4 == 1: fault was an instruction fetch ... a user-mode read resulting in no page being found
*/
error = 4 : The cause was a user-mode write resulting in no page being found.
error = 6 : The cause was a user-mode read resulting in no page being found. (also known as a null pointer dereference).
- 'object name' - object crash in program/library (Here libQtWebKit.so.4.5.2)
- 'base address' - in bracket after program/library name. (Here 0x7f9beb83a000)
- 'object size' - (Here 0xf6f000)
For a program, not a shared library
- Get function name in which segfault/crash is happening.
# addr2line -e SegfaultingProgram [-fCi] instruction_pointer_at_segfault
- Better, get a debug-instrumented build, and reproduce the problem under a debugger such as gdb.
2nd approach for a program
- Get the PID of crashed application (using ‘ps’ command)
- Dump application’s map file
# cat /proc/<pid>/maps > temp_app.map
- search for instruction_pointer_at_segfault in temp_app.map, to know exact crashed SegmentProgram or library
- Dump program’s object file
# objdump -d SegfaultingProgram > temp_prog.map
-d, --disassemble Display assembler contents of executable sections
-D, --disassemble-all Display assembler contents of all sections
-t, --syms Display the contents of the symbol table(s)
-T, --dynamic-syms Display the contents of the dynamic symbol table
- Seach for instruction_pointer_at_segfault from segfault error message within temp_prog.map. This will give function (with it’s assembly code) in which segfault/crash is happening.
For a shared library
- Unfortunately, it may not be possible to know where the libraries were placed in memory by the dynamic linker after-the-fact. Reproduce the problem under gdb.
Steps to decode segfault error
- Get offset into that object 'basse address' - 'ip address' = offset
- Then run addr2line on it:
addr2line -e [program/library path] -fCi [offset or instruction_pointer_at_segfault]
(Here path= /usr/lib64/qt45/lib/libQtWebKit.so.4.5.2, offset= 0x00007f9bebcca90d - 0x7f9beb83a000 = 0x49090D)
It gives list of function calls
GDB TUI mode
(Source: https://undo.io/resources/presentations/cppcon-2015-greg-law-give-me-15-minutes-ill-change/)
# gdb --tui <target binary> [corefile]
(gdb) start
(gdb) list TUI mode
(gdb) Ctrl + X + A Real TUI (Text UI) of source code
(gdb) next
(gdb) Ctrl + L Refresh screen
(gdb) Ctrl + X + 2 Source code with assembly
(gdb) Ctrl + X + 2 General Purpose Registers as well
(gdb) tui float reg Floating Registers
(gdb) Ctrl + X + 1 To go back
(gdb) Ctrl + P In order to go to previous command
(gdb) Ctrl + N In order to go to next command
Python Interpreter built in gdb (version 7 and after)
(gdb) python Multiple lines of python
(gdb) python [single line of python]
Python Pretty Printers can be used to print structures