set follow-fork-mode <mode>
mode should be parent(default) or child.
If you set mode to child, the new process is debugged after a fork.
show follow-fork-mode
displays the current mode.
Source: Forks - Debugging with GDB
set follow-fork-mode <mode>
mode should be parent(default) or child.
If you set mode to child, the new process is debugged after a fork.
show follow-fork-mode
displays the current mode.
Source: Forks - Debugging with GDB
Core dump is not generated on Ubuntu(14.04 LTS) in some cases.
Sometimes it can be generated. It seems to depend on the program.
Like below ulimit is OK.
$ ulimit -c unlimited $ ulimit -a core file size (blocks, -c) unlimited data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 15739 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 15739 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited
I examined where the core dump is generated.
$ sudo sysctl -a | grep core_pattern kernel.core_pattern = |/usr/share/apport/apport %p %s %c %P
On Ubuntu(14.04 LTS) core_pattern uses apport by default.
In case core dump was successfully generated, core dump was generated in current directory.
In case core dump was not generated, an error occurred on apport.
/var/log/apport.log
ERROR: apport (pid 3480) Tue May 12 18:48:31 2015: called for pid 3479, signal 6, core limit 18446744073709551615 ERROR: apport (pid 3480) Tue May 12 18:48:31 2015: ignoring implausibly big core limit, treating as unlimited ERROR: ERROR: apport (pid 3480) Tue May 12 18:48:31 2015: Unhandled exception: Traceback (most recent call last): File "/usr/share/apport/apport", line 357, in <module> (info['ExecutablePath'], info['ProcCmdline'])) File "/usr/share/apport/apport", line 99, in error_log apport.error('apport (pid %s) %s: %s', os.getpid(), time.asctime(), msg) File "/usr/lib/python3/dist-packages/apport/__init__.py", line 44, in error sys.stderr.write(msg % args) UnicodeEncodeError: 'ascii' codec can't encode character '\ufffd' in position 143: ordinal not in range(128) ERROR: apport (pid 3480) Tue May 12 18:48:31 2015: pid: 3480, uid: 0, gid: 0, euid: 0, egid: 0 ERROR: apport (pid 3480) Tue May 12 18:48:31 2015: environment: environ({})
Because an error occurred on apport, core dump was not generated.
This error seems to be Python's UnicodeEncodeError but I'm not sure, so I decided not to use apport in core_pattern.
# echo 'core.%e.%p' > /proc/sys/kernel/core_pattern
$ ulimit -c unlimited $ cat segfault.c #include <stdio.h> int main(void) { char *s = "hello, world!"; *s = 'H'; return 0; } $ gcc -Wall -g -o segfault segfault.c $ ./segfault Segmentation fault (core dumped) $ ls core.segfault.3423 segfault segfault.c
Any configuration changes made using the echo command disappear when the system is restarted.
To make configuration changes take effect after the system is rebooted, edit /etc/sysctl.conf.
Source: E.4. Using the sysctl Command
/etc/sysctl.conf
kernel.core_pattern = core.%e.%p
But when the system is restarted, changes disappear and core_pattern uses apport.
When the system is restarted and apport starts, apport seems to overwrite configuration.
Source: 12.04 - How to permanently edit the core_pattern file? - Ask Ubuntu
To stop this behavior, disable apport and restart the system.
/etc/default/apport
# set this to 0 to disable apport, or to 1 to enable it # you can temporarily override this with # sudo service apport start force_start=1 #enabled=1 enabled=0
If the return value of a command is greater than 128, it means that the command is terminated by signal.
$ man bash
The return value of a simple command is its exit status, or 128+n if the command is terminated by signal n.
Example:
$ some_command $ echo $? 139
In the above example, the return value is 139. Because 139=128+11 it means that the command was terminated by signal 11.
See `man signal` and you will find that signal 11 is SIGSEGV and it means segmentation violation.
You can print an array using `print` command (p) with GDB, but it is useful to print a pointer such as function parameter as an array using operator @.
Operator @ regards the left operand of @ as the address and prints the data of the left operand as an array for the number equivalent to the right operand.
(gdb) list 34 35 void func(int v[], int len) 36 { (gdb) p v[0] @ len $1 = {4470, 5197, 2482, 1016, 4154, 9986, 8313, 6873, 8517, 5857, 9019, 8002, 349, 9817, 365, 1018, 2269, 9759, 7092, 8674, 4902, 3890, 9746, 7668, 792, 3842, 4053, 6422, 630, 4880, 9996, 7164, 8392, 8469, 2959, 8380, 6533, 1795, 4296, 9964, 8259, 7474, 72, 2948, 3681, 501, 3994, 508, 9544, 941, 8054, 2186, 7418, 8684, 3224, 7322, 3822, 5022, 3085, 8341, 2296, 4073, 1034, 9839, 7067, 1197, 739, 7028, 2809, 6610, 8633, 483, 3017, 9634, 4758, 8101, 7604, 4018, 2174, 5014, 6600, 3754, 2854, 4798, 3921, 2124, 9889, 1147, 2409, 6105, 224, 6973, 5937, 2953, 8614, 9101, 3399, 8431, 2226, 3548}
Source: Arrays - Debugging with GDB
The easiest way is to use ptype with gdb.
Example:
foo.c
#include <sys/types.h> struct st { int i; char c; }; typedef int Array[10]; typedef struct st St; int main(void) { size_t s1; ssize_t s2; pid_t pid; Array arr; St st1; return 0; }
$ gcc -Wall -g -o foo foo.c $ gdb foo (gdb) b main (gdb) run (gdb) ptype s1 type = long unsigned int (gdb) ptype size_t type = long unsigned int (gdb) ptype s2 type = long int (gdb) ptype ssize_t type = long int (gdb) ptype pid type = int (gdb) ptype pid_t type = int (gdb) ptype arr type = int [10] (gdb) ptype Array type = int [10] (gdb) ptype st1 type = struct st { int i; char c; } (gdb) ptype St type = struct st { int i; char c; }
Like the above example,
ptype <expression or type name>
shows real type.
If the type is an array, it also shows its size. If the type is a struct, it also shows the type of the members of the struct. It's convenient.
You can probably find the real type using gcc -E option and looking into preprecessor's output like below, but it's bothersome and possibly needs hard work.
$ gcc -E foo.c | grep ssize_t typedef long int __ssize_t; typedef __ssize_t ssize_t; (ommitted below)
In the above example (x86_64 GNU/Linux), you can find that ssize_t is
__ssize_t => long int
$ gcc -E foo.c | grep ssize_t typedef long __darwin_ssize_t; (ommitted) typedef __darwin_ssize_t ssize_t; (ommitted)
In the above example (Mac OS X), you can find that ssize_t is
ssize_t => __darwin_ssize_t => long