You would need to use the information provided by such functions along with a parser for the DWARF debugging format to lookup the necessary information to generate a more useful backtrace. There is, to my knowledge, no non-GPL code available for doing this.
Scary caffeine-induced idea. Use the dlsym library routines to open your open executable's namespace and, in the backtrace function, use the GNU extension dladdr() to try and match the addresses provided by the backtrace to a symbol name. You have to have compiled and linked with -rdynamic and probably -ldl in order to try this. :)
Take a gander at the HARDGDB stuff, it can be modified greatly.
In anycase, the hardgdb actually uses GDB. So if you do a…
log_string("%s", MudBackTrace());
using the HARDGDB code. You'll receive an actual backtrace into your logs. ofcourse, it also pipes out a command to gdb your pid. -asis-
Make sure you grab the gdb.dat file from the bottom of the file aswell, tis vital. You can modify it as necessary. (make it walk though the frames if you'd like)
so frame 1 info locals frame 2 info locals frame 3 info locals. …
theres no harm in using a backtrace function, especially if it uses GDB itself and just reports to a internal log.
Unless your working it on a segfault, then you won't get much out of it. But if your have an annoying glitch in the mud, and you suspect whats causing it, an internal backtrace can be quite useful. Atleast in my opinion.
01 Feb, 2009, David Haley wrote in the 8th comment:
Votes: 0
There's really no point in replicating gdb inside your MUD if you can reliably reproduce the bug. If you have an idea which line is the culprit, set a breakpoint normally and be happy.
The code-generated backtrace is perhaps useful in cases where the bug is very hard to reproduce, but you would be better off using assertions to cause the program to fail, so that you get a proper core dump. After all, if you already suspect a line as the culprit, you can look at the call tree to get the (probably limited) set of entry points for that function.
I would hazard a guess that the vast majority of crasher bugs in most Diku-related codebases are from pointer access where the pointer isn't valid (IE: ch->pc_data->booger, or room->people[k]->inventory[j]), or from string overflows (hence the ever-increasing value of MAX_STRING_LENGTH, and use of 2*MSL buffers).
In most of those cases, nothing has been printed to the logs recently, and with the crash, nothing will be printed to the logs. You literally have no breadcrumbs anywhere near the crime scene, and many of them will only happen in the right circumstances (2 players in a room and a third walks in holding a bugged item, someone tries to set their description – yeah, that never happens – and overflows something, not in that code, but perhaps in the mob-program trigger to read it).
A backtrace that just shows the calling stack would tell me what functions to look around, and half the time I'll spot the error without even needing to run the driver in gdb. The other half, at least I know where to set breakpoints and watches.
Those of us who've worked on LP muds, or in non-compiled languages like perl, python, etc, get used to having any crash tell you a little bit about what the environment was like as it crashed. Not having that is like answering the phone without turning the room lights on. Sure, you can do it, but if the phone isn't where you expected it to be, there will be much cursing and stubbing of toes trying to get to it.
01 Feb, 2009, David Haley wrote in the 10th comment:
Votes: 0
I'm not sure the argument was against having some knowledge of where the crash occurred, rather, it was against the idea of replicating gdb inside the game. The above backtrace gives the stack trace that you need, without all the pain of learning to fiddle with the debugger libraries etc.
05 Feb, 2009, quixadhal wrote in the 11th comment:
Votes: 0
Rojan QDel said:
The issue is that its output isn't exactly human readable: Obtained 12 stack frames. /home/anna/mp/src/swreality(_Z12MudBackTracev+0x1a) [0x816fd8e] /home/anna/mp/src/swreality [0x813aa28] /lib/tls/libc.so.6 [0x53e918] /home/anna/mp/src/swreality(_Z6damageP9char_dataS0_ii+0x18c6) [0x817f57e] /home/anna/mp/src/swreality(_Z7one_hitP9char_dataS0_i+0x379d) [0x817d79b]
Something about this thread bugged me this morning, even though it's been a couple days. In poking around a bit, I have to ask, are you compiling with C++? Also, did you compile with debugging symbols enabled (-g)?
char *MudBackTrace( void )
{
static char mybugbuf[MSL];
void *array[30];
size_t size, i;
char **bstrings;
size = backtrace( array, 30 );
bstrings = backtrace_symbols( array, size );
sprintf( mybugbuf, "Obtained %d stack frames.\n", size );
for ( i = 0; i < size; i++ )
{
mudstrlcat( mybugbuf, bstrings, MSL );
mudstrlcat( mybugbuf, "\n",MSL );
}
// free(bstrings);
return ( mybugbuf );
}
The issue is that its output isn't exactly human readable:
Obtained 12 stack frames.
/home/anna/mp/src/swreality(_Z12MudBackTracev+0x1a) [0x816fd8e]
/home/anna/mp/src/swreality [0x813aa28]
/lib/tls/libc.so.6 [0x53e918]
/home/anna/mp/src/swreality(_Z6damageP9char_dataS0_ii+0x18c6) [0x817f57e]
/home/anna/mp/src/swreality(_Z7one_hitP9char_dataS0_i+0x379d) [0x817d79b]
/home/anna/mp/src/swreality(_Z9multi_hitP9char_dataS0_i+0x8f7) [0x8178fc1]
/home/anna/mp/src/swreality(_Z15violence_updatev+0x563) [0x817812f]
/home/anna/mp/src/swreality(_Z14update_handlerv+0x437) [0x82eb1b7]
/home/anna/mp/src/swreality(_Z9game_loopv+0x6ab) [0x813bde5]
/home/anna/mp/src/swreality(main+0x400) [0x813a780]
/lib/tls/libc.so.6(__libc_start_main+0xd3) [0x52bdf3]
/home/anna/mp/src/swreality(__gxx_personality_v0+0xa5) [0x8072a61]
Does anyone know if there's a flag I can set or some other modification that will make the output more useful?