void stack_trace() { int status; size_t stack_depth, sz, i; const size_t max_depth = 100; void *stack_addrs[max_depth]; char **stack_strings, *begin, *end, *j, *function, *ret; stack_depth = backtrace(stack_addrs, max_depth); stack_strings = backtrace_symbols(stack_addrs, stack_depth); for (i = 3; i < stack_depth; i++) { sz = 200; /* Just a guess, template names will go much wider */ function = (char *)actuallymalloc(sz); begin = end = 0; /* * Find the parentheses and address offset surrounding the mangled name */ for (j = stack_strings[i]; *j; ++j) { if (*j == '(') { begin = j; } else if (*j == '+') { end = j; } } if (begin && end) { *begin++ = '\0'; *end = '\0'; /* * Found our mangled name, now in [begin, end] */ ret = abi::__cxa_demangle(begin, function, &sz, &status); if (ret) { /* * Return value may be a realloc() of the input */ function = ret; } else { /* * Demangling failed, just pretend it's a C function with no args */ strncpy(function, begin, sz - 3); strcat(function, "()"); function[sz - 1] = '\0'; } Pmsg2(000, " %s:%s\n", stack_strings[i], function); } else { /* didn't find the mangled name, just print the whole line */ Pmsg1(000, " %s\n", stack_strings[i]); } actuallyfree(function); } actuallyfree(stack_strings); /* malloc()ed by backtrace_symbols */ }
int alder_smartall_test() { char *cp, *ra; #ifdef OLD_unix malloc_debug(2); #endif /* Allocate and chain together storage that's subject to the orphaned buffer check. */ ec(malloc(120)); ec(alloc(200)); ec(calloc(10, 4)); ra = alloc(60); strcpy(ra + 8, "Hello, there. This is data."); ra = realloc(ra, 100); ra = realloc(ra, 100); ra = realloc(ra, 2048); ec(realloc(ra, 55)); /* Allocate and chain some storage for which checking is disabled by the sm_static mechanism. */ sm_static(1); ra = malloc(10); ra = alloc(20); ra = calloc(30, sizeof(short)); ra = realloc(ra, 40); sm_static(0); /* Test the "actually" variants. */ ra = actuallymalloc(100); ra = actuallycalloc(10, sizeof(double)); ra = actuallyrealloc(ra, 15 * sizeof(double)); actuallyfree(ra); /* Produce orphan buffer listing. */ sm_dump(0); // sm_dump(Dumparam); /* Release chained buffers. */ while (bchain != NULL) { dc(); } /* Now verify that all have been released. */ #ifdef SMARTALLOC fprintf(stderr, "No orphaned buffer messages should follow this line.\n"); #endif sm_dump(1); return 0; }
/* * Return 1 if OK * 0 if no input * -1 error (must stop) */ int get_cmd(FILE *input, const char *prompt, BSOCK *sock, int sec) { static char *line = NULL; static char *next = NULL; static int do_history = 0; char *command; if (line == NULL) { do_history = 0; rl_catch_signals = 0; /* do it ourselves */ /* Here, readline does ***real*** malloc * so, be we have to use the real free */ line = readline((char *)prompt); /* cast needed for old readlines */ if (!line) { return -1; /* error return and exit */ } strip_trailing_junk(line); command = line; } else if (next) { command = next + 1; } else { sendit(_("Command logic problem\n")); sock->msglen = 0; sock->msg[0] = 0; return 0; /* No input */ } /* * Split "line" into multiple commands separated by the eol character. * Each part is pointed to by "next" until finally it becomes null. */ if (eol == '\0') { next = NULL; } else { next = strchr(command, eol); if (next) { *next = '\0'; } } if (command != line && isatty(fileno(input))) { senditf("%s%s\n", prompt, command); } sock->msglen = pm_strcpy(&sock->msg, command); if (sock->msglen) { do_history++; } if (!next) { if (do_history) { add_history(line); } actuallyfree(line); /* allocated by readline() malloc */ line = NULL; } return 1; /* OK */ }
void stack_trace() { int ret, i; bool demangled_symbol; size_t stack_depth; size_t sz = 200; /* Just a guess, template names will go much wider */ const size_t max_depth = 100; void *stack_addrs[100]; char **stack_strings, *begin, *end, *j, *function; stack_depth = backtrace(stack_addrs, max_depth); stack_strings = backtrace_symbols(stack_addrs, stack_depth); for (i = 1; i < stack_depth; i++) { function = (char *)actuallymalloc(sz); begin = end = 0; /* * Find the single quote and address offset surrounding the mangled name */ for (j = stack_strings[i]; *j; ++j) { if (*j == '\'') { begin = j; } else if (*j == '+') { end = j; } } if (begin && end) { *begin++ = '\0'; *end = '\0'; /* * Found our mangled name, now in [begin, end) */ demangled_symbol = false; while (!demangled_symbol) { ret = cplus_demangle(begin, function, sz); switch (ret) { case DEMANGLE_ENAME: /* * Demangling failed, just pretend it's a C function with no args */ strcat(function, "()"); function[sz - 1] = '\0'; demangled_symbol = true; break; case DEMANGLE_ESPACE: /* * Need more space for demangled function name. */ actuallyfree(function); sz = sz * 2; function = (char *)actuallymalloc(sz); continue; default: demangled_symbol = true; break; } } Pmsg2(000, " %s:%s\n", stack_strings[i], function); } else { /* * Didn't find the mangled name, just print the whole line */ Pmsg1(000, " %s\n", stack_strings[i]); } actuallyfree(function); } actuallyfree(stack_strings); /* malloc()ed by backtrace_symbols */ }