From a7b038ff52e4686736d40d9a65b3289fbbdd28af Mon Sep 17 00:00:00 2001 From: Andrew Kesterson Date: Wed, 27 Jul 2011 22:31:34 -0400 Subject: [PATCH] Removed stacktrace and signal functionality since it isn't ANSI; left exception frame tracing intact. Got the library compiling on Windows and Linux both, should work anywhere setjmp/longjmp works now. Got "simple" demo working again, shows off most features of library. --- backtrace.c | 284 ---------------------------------------------------- 1 file changed, 284 deletions(-) delete mode 100644 backtrace.c diff --git a/backtrace.c b/backtrace.c deleted file mode 100644 index d334e80..0000000 --- a/backtrace.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - Based on mingw32 "backtrace" library provided by Cloud Wu, here: - http://code.google.com/p/backtrace-mingw/ - - Modified to provide the same interface that execinfo.h does on GNU/Unix hosts. -*/ - -#ifdef WIN32 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define BUFFER_MAX 1024 -char **symbols; -char scratch[BUFFER_MAX]; - -struct bfd_ctx { - bfd * handle; - asymbol ** symbol; -}; - -struct bfd_set { - char * name; - struct bfd_ctx * bc; - struct bfd_set *next; -}; - -struct find_info { - asymbol **symbol; - bfd_vma counter; - const char *file; - const char *func; - unsigned line; -}; - -void lookup_section(bfd *abfd, asection *sec, void *opaque_data) -{ - struct find_info *data = opaque_data; - - if (data->func) - return; - - if (!(bfd_get_section_flags(abfd, sec) & SEC_ALLOC)) - return; - - bfd_vma vma = bfd_get_section_vma(abfd, sec); - if (data->counter < vma || vma + bfd_get_section_size(sec) <= data->counter) - return; - - bfd_find_nearest_line(abfd, sec, data->symbol, data->counter - vma, &(data->file), &(data->func), &(data->line)); -} - -void find(struct bfd_ctx * b, DWORD offset, const char **file, const char **func, unsigned *line) -{ - struct find_info data; - data.func = NULL; - data.symbol = b->symbol; - data.counter = offset; - data.file = NULL; - data.func = NULL; - data.line = 0; - - bfd_map_over_sections(b->handle, &lookup_section, &data); - if (file) { - *file = data.file; - } - if (func) { - *func = data.func; - } - if (line) { - *line = data.line; - } -} - -int init_bfd_ctx(struct bfd_ctx *bc, const char * procname) -{ - bc->handle = NULL; - bc->symbol = NULL; - - bfd *b = bfd_openr(procname, 0); - if (!b) { - return 1; - } - - int r1 = bfd_check_format(b, bfd_object); - int r2 = bfd_check_format_matches(b, bfd_object, NULL); - int r3 = bfd_get_file_flags(b) & HAS_SYMS; - - if (!(r1 && r2 && r3)) { - bfd_close(b); - return 1; - } - - void *symbol_table; - - unsigned dummy = 0; - if (bfd_read_minisymbols(b, FALSE, &symbol_table, &dummy) == 0) { - if (bfd_read_minisymbols(b, TRUE, &symbol_table, &dummy) < 0) { - free(symbol_table); - bfd_close(b); - return 1; - } - } - - bc->handle = b; - bc->symbol = symbol_table; - - return 0; -} - -void close_bfd_ctx(struct bfd_ctx *bc) -{ - if (bc) { - if (bc->symbol) { - free(bc->symbol); - } - if (bc->handle) { - bfd_close(bc->handle); - } - } -} - -struct bfd_ctx *get_bc(struct bfd_set *set , const char *procname) -{ - while(set->name) { - if (strcmp(set->name , procname) == 0) { - return set->bc; - } - set = set->next; - } - struct bfd_ctx bc; - if (init_bfd_ctx(&bc, procname)) { - return NULL; - } - set->next = calloc(1, sizeof(*set)); - set->bc = malloc(sizeof(struct bfd_ctx)); - memcpy(set->bc, &bc, sizeof(bc)); - set->name = strdup(procname); - - return set->bc; -} - -void release_set(struct bfd_set *set) -{ - while(set) { - struct bfd_set * temp = set->next; - free(set->name); - close_bfd_ctx(set->bc); - free(set); - set = temp; - } -} - -int backtrace(void **buffer, int size) -{ - if ( !buffer ) - return 1; - bfd_init(); - struct bfd_set *set = calloc(1,sizeof(*set)); - _backtrace(buffer, size, set, NULL); - release_set(set); - return 0; -} - -char **backtrace_symbols(void **buffer, int size) -{ - return symbols; -} - -int _backtrace(void **buffer, int depth, struct bfd_set *set) -{ - char procname[MAX_PATH]; - LPCONTEXT context; - struct bfd_ctx *bc = NULL; - int i = depth; - STACKFRAME frame; - HANDLE process; - HANDLE thread; - char symbol_buffer[sizeof(IMAGEHLP_SYMBOL) + 255]; - char module_name_raw[MAX_PATH]; - IMAGEHLP_SYMBOL *symbol; - DWORD module_base; - const char * module_name; - const char * file = NULL; - const char * func = NULL; - char tmpbuf[512]; - unsigned line = 0; - DWORD dummy; - char *spos = &scratch; - - if ( symbols ) - free(symbols); - symbols = (void **)malloc((sizeof(void *) * depth)); - if (!symbols) - return 1; - memset(symbols, 0, sizeof(void *) * depth); - - memset(spos, 0x00, BUFFER_MAX); - - memset(&frame,0,sizeof(frame)); - GetModuleFileNameA(NULL, procname, sizeof procname); - process = GetCurrentProcess(); - thread = GetCurrentThread(); - GetThreadContext(thread, context); - - frame.AddrPC.Offset = context->Eip; - frame.AddrPC.Mode = AddrModeFlat; - frame.AddrStack.Offset = context->Esp; - frame.AddrStack.Mode = AddrModeFlat; - frame.AddrFrame.Offset = context->Ebp; - frame.AddrFrame.Mode = AddrModeFlat; - - while(StackWalk(IMAGE_FILE_MACHINE_I386, - process, - thread, - &frame, - context, - 0, - SymFunctionTableAccess, - SymGetModuleBase, 0)) { - - i++; - if ( i >= depth ) - break; - - symbol = (IMAGEHLP_SYMBOL *)symbol_buffer; - symbol->SizeOfStruct = (sizeof *symbol) + 255; - symbol->MaxNameLength = 254; - - module_base = SymGetModuleBase(process, frame.AddrPC.Offset); - - module_name = "[unknown module]"; - if (module_base && - GetModuleFileNameA((HINSTANCE)module_base, module_name_raw, MAX_PATH)) { - module_name = module_name_raw; - bc = get_bc(set, module_name); - } - - file = NULL; - func = NULL; - line = 0; - - if (bc) { - find(bc,frame.AddrPC.Offset,&file,&func,&line); - } - - if (file == NULL) { - dummy = 0; - if (SymGetSymFromAddr(process, frame.AddrPC.Offset, &dummy, symbol)) { - file = symbol->Name; - } - else { - file = "[unknown file]"; - } - } - - if (func == NULL) { - buffer[i] = frame.AddrPC.Offset; - sprintf((char *)&tmpbuf, "%s(NULL+0x??)[0x%x]\0", - module_name, - frame.AddrPC.Offset); - } - else { - buffer[i] = frame.AddrPC.Offset; - sprintf((char *)&tmpbuf, "%s(%s+0x??)[0x%x]\0", - module_name, - frame.AddrPC.Offset, - func); - } - strcpy(spos, (char *)&tmpbuf); - symbols[i] = spos; - spos += strlen((char *)&tmpbuf); - } -} - -#endif // WIN32