Amended on Wed 16 Dec 2009 07:25 PM (UTC) by Nick Gammon
Message
Another approach to capture if the MUD exits by calling exit(1) is to put a breakpoint on exit, like this example program:
#include <stdlib.h>
void a (void)
{
exit (1);
}
void b (void)
{
a ();
}
int main (void)
{
b ();
return 0;
}
Now if I run gdb, I want to find where in the code exit is called:
$ gdb test
GNU gdb 6.8-debian
(gdb) break exit
Function "exit" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (exit) pending.
(gdb) run
Starting program: /home/nick/development/test
Breakpoint 1, 0xb7ea8d06 in exit () from /lib/tls/i686/cmov/libc.so.6
(gdb) bt
#0 0xb7ea8d06 in exit () from /lib/tls/i686/cmov/libc.so.6
#1 0x080483d6 in a ()
#2 0x080483e1 in b ()
#3 0x080483f9 in main ()
(gdb)
Note the warning message about exit not existing just yet, but it picked it up after the libraries were loaded. Then when exit was called, you can see it was indeed located in function "a" called by function "b" called by "main".
Put the actual function (my first box) only once in the code (eg. comms.c) otherwise the linker will complain it finds more than one of them. The function prototype I mentioned, which you put in your .h file, tells the other functions to expect it to be found at link time.
[12:00:59] Linking executable ...
obj/act_info.o: In function `my_exit':
/home/Josh/Desktop/dystopia2/src/dystopia.h:2600: multiple definition of `my_exit'
obj/act_comm.o:/home/Josh/Desktop/dystopia2/src/dystopia.h:2600: first defined here
obj/act_move.o: In function `my_exit':
/home/Josh/Desktop/dystopia2/src/dystopia.h:2600: multiple definition of `my_exit'
obj/act_comm.o:/home/Josh/Desktop/dystopia2/src/dystopia.h:2600: first defined here
obj/act_comm.o:/home/Josh/Desktop/dystopia2/src/dystopia.h:2600: first defined here
collect2: ld returned 1 exit status
make: *** [Dystopia] Error 1
[Josh@localhost src]$
In your case gdb didn't show much because the MUD didn't actually crash, it chose to exit, as Zeno said. If you haven't found the problem, you can still find why it calls exit. First make your own exit function:
void my_exit (int status)
{
exit (status);
}
And put a function prototype in mud.h or whatever it is called:
void my_exit (int status);
Then go through the rest of the code (using grep will help) and change every instance of:
exit (1);
to:
my_exit (1);
(And of course any other numbers you find).
Just don't change the one inside my_exit. ;P
Then fire up gdb again, and before typing "run" type in "break my_exit". That will put a breakpoint on your my_exit function. Then type "run" or "run 4000" and let it rip. Then when it tries to exit it will end up in my_exit. Then type "bt" to get a backtrace to see exactly where in the code it is calling exit.
[Josh@localhost area]$ gdb ../src/Dystopia
GNU gdb (GDB) Fedora (7.0-8.fc12)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/Josh/Desktop/dystopia2/src/Dystopia...done.
(gdb) run 4000
Starting program: /home/Josh/Desktop/dystopia2/src/Dystopia 4000
[Thread debugging using libthread_db enabled]
Program exited with code 01.
(gdb)
The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).
To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.