[MUD-Dev] Re: Technical C/C++ coding question
Finn Arne Gangstad
finnag at guardian.no
Sat Jul 25 09:27:07 CEST 1998
On Sat, 13 Jun 1998, Ben Greear wrote:
>
> Java has this nice feature called printStackTrace(), that allows
> you to get a stack trace (and log it or whatever) during runtime.
Sorry to answer so late, but here are some functions i made for the
mud I'm working on to do what you want.
stack_trace requires gcc, and will only print a stack-trace containing the
addresses (use gdb or similar to look them up).
const char *
stack_trace()
{
#ifdef __GNUC__
static char trace_buf[400];
char *t = trace_buf;
int m = 1;
char *p = 0;
/* The general idea here is that you're not interested in call-trace
* that goes up above main() */
const unsigned int delta = size_of_main;
/* Don't look */
*t++ = '(';
m = m && (p = __builtin_return_address(1)) && (t += sprintf(t, "%p", p)) &&
(p - (char *)main) > delta;
m = m && (p = __builtin_return_address(2)) && (t += sprintf(t, " %p", p)) &&
(p - (char *)main) > delta;
m = m && (p = __builtin_return_address(3)) && (t += sprintf(t, " %p", p)) &&
(p - (char *)main) > delta;
/* .... etc as long as you bother (i did it up to 29, if you extend it
* increase the size of trace_buf */
*t++ = ')';
*t++ = 0;
return trace_buf;
#else
return "(no stack-trace using this compiler)";
#endif
}
To initialise the global variable "size_of_main", do this in main():
int main(int argc, char **argv)
{
/* ... */
size_of_main = (char *)&&main_end - (char *)main;
/* ... */
main_end:
exit(0);
}
> Is there a way to (easily) do that in c++ as well? Can I make it
> dump a core file and yet still keep runing?
And here is a function to fork and dump core:
void
fork_and_dump_core(const char *why)
{
pid_t pid;
fprintf(stderr, "DEBUG: fork_and_dump_core: %s", why);
fflush(NULL); /* flush all streams so fork doesn't mess things up */
pid = fork();
if (pid == -1) {
perror("fork_and_dump_core: fork failed");
} else if (pid == 0) {
volatile int n = 0;
n = 1 / n; /* die horribly */
_exit(0);
} else {
waitpid(pid, 0, 0); /* wait for the core dump.. usefulness questioned */
}
}
The reason for using "1 / n" (where n is 0) to die instead of abort(), is
that abort() didn't include the last function in the call-trace on the OS
i tested it on.
- Finn Arne
More information about the mud-dev-archive
mailing list