0ad/source/lib/sysdep/unix/udbg.cpp

112 lines
2.6 KiB
C++
Raw Normal View History

/* udbg.cpp
This file contains debug helpers that are common for all unix systems. See
udbg_bfd.cpp for the linux-specific stuff (Using BFD and backtrace() for symbol
lookups and backtraces)
*/
#include "precompiled.h"
#include "lib/timer.h"
#include "lib/sysdep/sysdep.h"
#include "lib/debug.h"
#if !OS_LINUX
// udbg stubs implementation. This is what's used on non-linux, so far.
void* debug_get_nth_caller(uint UNUSED(n), void *UNUSED(context))
{
return NULL;
}
LibError debug_dump_stack(wchar_t* UNUSED(buf), size_t UNUSED(max_chars), uint UNUSED(skip), void* UNUSED(context))
{
return ERR::NOT_IMPLEMENTED;
}
LibError debug_resolve_symbol(void* UNUSED(ptr_of_interest), char* UNUSED(sym_name), char* UNUSED(file), int* UNUSED(line))
{
return ERR::NOT_IMPLEMENTED;
}
#endif
void unix_debug_break()
{
kill(getpid(), SIGTRAP);
}
#define DEBUGGER_WAIT 3
#define DEBUGGER_CMD "gdb"
#define DEBUGGER_ARG_FORMAT "--pid=%d"
#define DEBUGGER_BREAK_AFTER_WAIT 0
/*
Start the debugger and tell it to attach to the current process/thread
(called by display_error)
*/
void udbg_launch_debugger()
{
pid_t orgpid=getpid();
pid_t ret=fork();
if (ret == 0)
{
// Child Process: exec() gdb (Debugger), set to attach to old fork
char buf[16];
snprintf(buf, 16, DEBUGGER_ARG_FORMAT, orgpid);
int ret=execlp(DEBUGGER_CMD, DEBUGGER_CMD, buf, NULL);
// In case of success, we should never get here anyway, though...
if (ret != 0)
{
perror("Debugger launch failed");
}
}
else if (ret > 0)
{
// Parent (original) fork:
debug_printf("Sleeping until debugger attaches.\nPlease wait.\n");
sleep(DEBUGGER_WAIT);
}
else // fork error, ret == -1
{
perror("Debugger launch: fork failed");
}
}
void debug_puts(const char* text)
2004-07-15 21:59:27 +02:00
{
fputs(text, stdout);
fflush(stdout);
2004-07-15 21:59:27 +02:00
}
// TODO: Do these properly. (I don't know what I'm doing; I just
// know that these functions are required in order to compile...)
int debug_write_crashlog(const char* UNUSED(file), wchar_t* UNUSED(header),
void* UNUSED(context))
{
abort();
}
int debug_is_pointer_bogus(const void* UNUSED(p))
{
return false;
}
void debug_heap_check()
{
}
// if <full_monty> is true or PARANOIA #defined, all possible checks are
// performed as often as possible. this is really slow (we are talking x100),
// but reports errors closer to where they occurred.
void debug_heap_enable(DebugHeapChecks UNUSED(what))
{
// No-op until we find out if glibc has heap debugging
}
// disable all automatic checks until the next debug_heap_enable.
void debug_heap_disable()
{
// No-op until we find out if glibc has heap debugging
}