SWI portability

This commit is contained in:
Vitor Santos Costa
2013-01-16 12:28:37 +00:00
parent 1bba29c646
commit 7cf4e9442c
6 changed files with 224 additions and 102 deletions

View File

@@ -89,15 +89,49 @@ get_trace_store(void)
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
next_btrace_id() produces the id for the next backtrace and sets
bt->current to the subsequent id. Although bt is thread-local, it may be
called from a signal handler or (Windows) exception. We cannot use
locking because the mutex functions are not async signal safe. So, we
use atomic instructions if possible. Otherwise, we ensure consistency of
the datastructures, but we may overwrite an older stack trace.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
static int
next_btrace_id(btrace *bt)
{ int current;
#ifdef COMPARE_AND_SWAP
int next;
do
{ current = bt->current;
next = current+1;
if ( next == SAVE_TRACES )
next = 0;
} while ( !COMPARE_AND_SWAP(&bt->current, current, next) );
#else
current = bt->current++ % SAVE_TRACES;
if ( bt->current >= SAVE_TRACES )
bt->current %= SAVE_TRACES;
#endif
return current;
}
void
save_backtrace(const char *why)
{ btrace *bt = get_trace_store();
if ( bt )
{ btrace_stack *s = &bt->dumps[bt->current];
{ btrace_stack *s;
unw_cursor_t cursor; unw_context_t uc;
int depth;
int current = next_btrace_id(bt);
s = &bt->dumps[current];
unw_getcontext(&uc);
unw_init_local(&cursor, &uc);
for(depth=0; unw_step(&cursor) > 0 && depth < MAX_DEPTH; depth++)
@@ -107,9 +141,6 @@ save_backtrace(const char *why)
}
s->name = why;
s->depth = depth;
if ( ++bt->current == SAVE_TRACES )
bt->current = 0;
}
}
@@ -228,6 +259,33 @@ get_trace_store(void)
}
/* Copy of same function above. Relies on a different btrace structure.
Ideally, this should be shared :-(
*/
static int
next_btrace_id(btrace *bt)
{ int current;
#ifdef COMPARE_AND_SWAP
int next;
do
{ current = bt->current;
next = current+1;
if ( next == SAVE_TRACES )
next = 0;
} while ( !COMPARE_AND_SWAP(&bt->current, current, next) );
#else
current = bt->current++ % SAVE_TRACES;
if ( bt->current >= SAVE_TRACES )
bt->current %= SAVE_TRACES;
#endif
return current;
}
void
save_backtrace(const char *why)
{ btrace *bt = get_trace_store();
@@ -235,15 +293,14 @@ save_backtrace(const char *why)
if ( bt )
{ void *array[100];
size_t frames;
int current = next_btrace_id(bt);
frames = backtrace(array, sizeof(array)/sizeof(void *));
bt->sizes[bt->current] = frames;
if ( bt->symbols[bt->current] )
free(bt->symbols[bt->current]);
bt->symbols[bt->current] = backtrace_symbols(array, frames);
bt->why[bt->current] = why;
if ( ++bt->current == SAVE_TRACES )
bt->current = 0;
bt->sizes[current] = frames;
if ( bt->symbols[current] )
free(bt->symbols[current]);
bt->symbols[current] = backtrace_symbols(array, frames);
bt->why[current] = why;
}
}
@@ -358,6 +415,9 @@ initBackTrace(void)
*/
#define MAX_MODULE_NAME_LENGTH 64
#define LOCK() PL_LOCK(L_CSTACK)
#define UNLOCK() PL_UNLOCK(L_CSTACK)
typedef struct
{ char name[MAX_FUNCTION_NAME_LENGTH]; /* function called */
DWORD64 offset; /* offset in function */
@@ -397,6 +457,32 @@ get_trace_store(void)
return LD->btrace_store;
}
/* Copy of same function above. Relies on a different btrace structure.
Ideally, this should be shared :-(
*/
static int
next_btrace_id(btrace *bt)
{ int current;
#ifdef COMPARE_AND_SWAP
int next;
do
{ current = bt->current;
next = current+1;
if ( next == SAVE_TRACES )
next = 0;
} while ( !COMPARE_AND_SWAP(&bt->current, current, next) );
#else
current = bt->current++ % SAVE_TRACES;
if ( bt->current >= SAVE_TRACES )
bt->current %= SAVE_TRACES;
#endif
return current;
}
int backtrace(btrace_stack* trace, PEXCEPTION_POINTERS pExceptionInfo)
{ STACKFRAME64 frame;
CONTEXT context;
@@ -406,7 +492,6 @@ int backtrace(btrace_stack* trace, PEXCEPTION_POINTERS pExceptionInfo)
char symbolScratch[sizeof(SYMBOL_INFO) + MAX_SYMBOL_LEN];
SYMBOL_INFO* symbol = (SYMBOL_INFO*)&symbolScratch;
IMAGEHLP_MODULE64 moduleInfo;
EXCEPTION_POINTERS *pExp = NULL;
DWORD64 offset;
DWORD imageType;
int skip = 0;
@@ -529,11 +614,12 @@ void
win_save_backtrace(const char *why, PEXCEPTION_POINTERS pExceptionInfo)
{ btrace *bt = get_trace_store();
if ( bt )
{ btrace_stack *s = &bt->dumps[bt->current];
{ int current = next_btrace_id(bt);
btrace_stack *s = &bt->dumps[current];
LOCK();
s->depth = backtrace(s, pExceptionInfo);
UNLOCK();
s->name = why;
if ( ++bt->current == SAVE_TRACES )
bt->current = 0;
}
}