static void backtrace_and_maps (int do_abort, bool written, int fd) { if (do_abort > 1 && written) { void *addrs[64]; #define naddrs (sizeof (addrs) / sizeof (addrs[0])) int n = __backtrace (addrs, naddrs); if (n > 2) { #define strnsize(str) str, strlen (str) #define writestr(str) write_not_cancel (fd, str) writestr (strnsize ("======= Backtrace: =========\n")); __backtrace_symbols_fd (addrs + 1, n - 1, fd); writestr (strnsize ("======= Memory map: ========\n")); int fd2 = open_not_cancel_2 ("/proc/self/maps", O_RDONLY); char buf[1024]; ssize_t n2; while ((n2 = read_not_cancel (fd2, buf, sizeof (buf))) > 0) if (write_not_cancel (fd, buf, n2) != n2) break; close_not_cancel_no_status (fd2); } } }
/*+ register a pointer to be automatically cleaned up at program exit +*/ void alloc_register(void *ptr) /*+ pointer to newly-alloc'd memory +*/ { #if defined(DEBUG) && defined(DEBUG_ALLOC) fprintf(stderr, "alloc_register(%p)\n", ptr); __backtrace(); #endif assert(NULL != ptr); void* tmp; tmp = realloc(alloc_cleanup, sizeof(void *) * (alloc_cleanup_count + 1)); assert(NULL != tmp); alloc_cleanup = tmp; alloc_cleanup[alloc_cleanup_count++] = ptr; }
void release_fiq(struct fiq_handler *f) { if (current_fiq != f) { printk(KERN_ERR "%s FIQ trying to release %s FIQ\n", f->name, current_fiq->name); #ifdef CONFIG_DEBUG_ERRORS __backtrace(); #endif return; } do current_fiq = current_fiq->next; while (current_fiq->fiq_op(current_fiq->dev_id, 0)); }
/*+ backtrace and exit immediately. +*/ void __backtrace_and_die() { __backtrace(); exit(0); }