Commit c6fdbf08 authored by Geoff Simmons's avatar Geoff Simmons

trackrdrd: - added some object checking to insert()

	- adopting varnishd.c's hack of calling nm -an to get symbolic
          names for stack traces
parent 01a3cbb3
...@@ -590,7 +590,10 @@ static inline dataentry ...@@ -590,7 +590,10 @@ static inline dataentry
*insert(unsigned xid, unsigned fd, float tim) *insert(unsigned xid, unsigned fd, float tim)
{ {
dataentry *de = data_get(); dataentry *de = data_get();
CHECK_OBJ_NOTNULL(de, DATA_MAGIC);
assert(de->state == DATA_EMPTY);
hashentry *he = hash_insert(xid, de, tim); hashentry *he = hash_insert(xid, de, tim);
CHECK_OBJ(he, HASH_MAGIC);
if (! he) { if (! he) {
LOG_Log(LOG_WARNING, "Insert: Could not insert hash for XID %d", LOG_Log(LOG_WARNING, "Insert: Could not insert hash for XID %d",
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include <string.h> #include <string.h>
#include <syslog.h> #include <syslog.h>
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h>
#ifndef HAVE_EXECINFO_H #ifndef HAVE_EXECINFO_H
#include "compat/execinfo.h" #include "compat/execinfo.h"
...@@ -49,6 +50,7 @@ ...@@ -49,6 +50,7 @@
#endif #endif
#include "vas.h" #include "vas.h"
#include "vsb.h"
#include "trackrdrd.h" #include "trackrdrd.h"
...@@ -64,28 +66,116 @@ HNDL_Terminate(int sig) ...@@ -64,28 +66,116 @@ HNDL_Terminate(int sig)
term = 1; term = 1;
} }
/*
* This hack is almost verbatim from varnishd.c -- attempt to run nm(1) on
* ourselves at startup to get a mapping from lib pointers to symbolic
* function names for stack traces.
*
* +1 to phk's rant in varnishd.c about the lack of a standard for this.
*/
struct symbols {
uintptr_t a;
char *n;
VTAILQ_ENTRY(symbols) list;
};
static VTAILQ_HEAD(,symbols) symbols = VTAILQ_HEAD_INITIALIZER(symbols);
static int
symbol_lookup(struct vsb *vsb, void *ptr)
{
struct symbols *s, *s0;
uintptr_t pp;
pp = (uintptr_t)ptr;
s0 = NULL;
VTAILQ_FOREACH(s, &symbols, list) {
if (s->a > pp)
continue;
if (s0 == NULL || s->a > s0->a)
s0 = s;
}
if (s0 == NULL)
return (-1);
VSB_printf(vsb, "%p: %s+%jx", ptr, s0->n, (uintmax_t)pp - s0->a);
return (0);
}
static void
symbol_hack(const char *a0)
{
char buf[BUFSIZ], *p, *e;
FILE *fi;
uintptr_t a;
struct symbols *s;
sprintf(buf, "nm -an %s 2>/dev/null", a0);
fi = popen(buf, "r");
if (fi == NULL)
return;
while (fgets(buf, sizeof buf, fi)) {
if (buf[0] == ' ')
continue;
p = NULL;
a = strtoul(buf, &p, 16);
if (p == NULL)
continue;
if (a == 0)
continue;
if (*p++ != ' ')
continue;
p++;
if (*p++ != ' ')
continue;
if (*p <= ' ')
continue;
e = strchr(p, '\0');
AN(e);
while (e > p && isspace(e[-1]))
e--;
*e = '\0';
s = malloc(sizeof *s + strlen(p) + 1);
AN(s);
s->a = a;
s->n = (void*)(s + 1);
strcpy(s->n, p);
VTAILQ_INSERT_TAIL(&symbols, s, list);
}
(void)pclose(fi);
}
static void static void
stacktrace(void) stacktrace(void)
{ {
void *buf[MAX_STACK_DEPTH]; void *buf[MAX_STACK_DEPTH];
int depth, i; int depth, i;
char **strings; struct vsb *sb = VSB_new_auto();
depth = backtrace (buf, MAX_STACK_DEPTH); depth = backtrace (buf, MAX_STACK_DEPTH);
if (depth == 0) { if (depth == 0) {
LOG_Log0(LOG_ERR, "Stacktrace empty"); LOG_Log0(LOG_ERR, "Stacktrace empty");
return; return;
} }
strings = backtrace_symbols(buf, depth); for (i = 0; i < depth; i++) {
if (strings == NULL) { VSB_clear(sb);
LOG_Log0(LOG_ERR, "Cannot retrieve symbols for stacktrace"); if (symbol_lookup(sb, buf[i]) < 0) {
return; char **strings;
strings = backtrace_symbols(&buf[i], 1);
if (strings != NULL && strings[0] != NULL)
VSB_printf(sb, "%p: %s", buf[i], strings[0]);
else
VSB_printf(sb, "%p: (?)", buf[i]);
}
VSB_finish(sb);
LOG_Log(LOG_ERR, "%s", VSB_data(sb));
} }
/* XXX: get symbol names from nm? cf. cache_panic.c/pan_backtrace */ }
for (i = 0; i < depth; i++)
LOG_Log(LOG_ERR, "%s", strings[i]); void
HNDL_Init(const char *a0)
free(strings); {
symbol_hack(a0);
} }
void void
......
...@@ -354,6 +354,8 @@ main(int argc, char * const *argv) ...@@ -354,6 +354,8 @@ main(int argc, char * const *argv)
ignore_action.sa_handler = SIG_IGN; ignore_action.sa_handler = SIG_IGN;
default_action.sa_handler = SIG_DFL; default_action.sa_handler = SIG_DFL;
HNDL_Init(argv[0]);
if (!D_flag) { if (!D_flag) {
child_pid = fork(); child_pid = fork();
switch(child_pid) { switch(child_pid) {
......
...@@ -63,7 +63,8 @@ volatile sig_atomic_t term; ...@@ -63,7 +63,8 @@ volatile sig_atomic_t term;
struct sigaction terminate_action, ignore_action, stacktrace_action, struct sigaction terminate_action, ignore_action, stacktrace_action,
default_action; default_action;
void HNDL_Init(const char *a0);
void HNDL_Abort(int sig); void HNDL_Abort(int sig);
void HNDL_Terminate(int sig); void HNDL_Terminate(int sig);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment