Collecting stacktraces is a tricky business. Attempting to do it "by hand" — i.e. by reading a core file and walking the stack manually while resolving symbols possibly in shared libraries and dealing with all sorts of platforms/architecture differences — is just crazy talk. Fortunately, GDB has the ability to do this and, even better, comes with a batch mode that allows the unattended collection of a stacktrace.
Here is how, given a binary and a core dump, you generate a stacktrace:
$ gdb -batch -q -ex bt binary-name core-dump
And this is how the new stacktrace module goes by collecting stacktraces: it just calls out to GDB (if present) to gather the stacktrace and append it to the test case's stderr output.
Easy enough, huh? Well, yes, but you still need to determine what the name of the core file is! And that is, of course, platform specific and (even worse) user-customizable. Here are some examples:
- NetBSD places the core files in the current directory and names them after the binary that generated them, with a .core suffix. The names have a maximum length of MAXCOMLEN. To make things trickier, this is all customizable through the kern.defcorename sysctl setting.
- Mac OS X places core files in /cores/ using a naming scheme of the form core.PID. This is also customizable through the kern.corefile sysctl setting.
- Fedora places core files in the current directory with a naming scheme of core.PID. I guess this is also customizable, but I haven't investigated how.
In the current implementation, I have special-cased all these default values in the find_core() function, which has been tested to work on all the operating systems above mentioned. I could go one step further and attempt to cope with the user customizations, but haven't done so at this point. (Why? Because I wasn't aware that this was all tunable until I wrote this post!)
Lastly, and as mentioned earlier, the new code comes with unit and integration tests to ensure that the gathering of stacktraces works. This is something that the ATF codebase did not have, and thus is why nobody spotted that this did not work in any other system than NetBSD.
No comments:
Post a Comment