Keep track of call history using thread data

This commit is contained in:
Justin Ethier 2015-12-14 22:55:57 -05:00
parent 606591ebe5
commit ead5bcb100
5 changed files with 28 additions and 25 deletions

View file

@ -19,10 +19,6 @@ static void Cyc_heap_init(long heap_size);
static void Cyc_heap_init(long heap_size) static void Cyc_heap_init(long heap_size)
{ {
/* Initialize stack trace table
TODO: will eventually be relocated to a per-thread operation */
Cyc_st_init();
/* Allocate heap area for second generation. */ /* Allocate heap area for second generation. */
#if DEBUG_SHOW_DIAG #if DEBUG_SHOW_DIAG
printf("main: Allocating and initializing heap...\n"); printf("main: Allocating and initializing heap...\n");

View file

@ -189,9 +189,9 @@ object memqp(void *,object,list);
void Cyc_start_thread(gc_thread_data *thd); void Cyc_start_thread(gc_thread_data *thd);
void GC(void *,closure,object*,int); void GC(void *,closure,object*,int);
void Cyc_st_init();
void Cyc_st_add(char *frame); void Cyc_st_add(char *frame);
void Cyc_st_print(FILE *out); void Cyc_st_add2(void *data, char *frame);
void Cyc_st_print(void *data, FILE *out);
char *_strdup (const char *s); char *_strdup (const char *s);
object add_symbol(symbol_type *psym); object add_symbol(symbol_type *psym);

View file

@ -60,6 +60,10 @@ struct gc_thread_data_t {
void **mark_buffer; void **mark_buffer;
int mark_buffer_len; int mark_buffer_len;
pthread_mutex_t lock; pthread_mutex_t lock;
// Data needed for call history
char **stack_traces;
int stack_trace_idx;
char *stack_prev_frame;
}; };
/* GC data structures */ /* GC data structures */

View file

@ -189,24 +189,19 @@ const object quote_void = &Cyc_void_symbol;
/* Stack Traces */ /* Stack Traces */
static const int MAX_STACK_TRACES = 10; static const int MAX_STACK_TRACES = 10;
static char **Cyc_Stack_Traces;
static int Cyc_Stack_Trace_Idx = 0;
static char *Cyc_Stack_Prev_Frame = NULL;
void Cyc_st_init() { void Cyc_st_add(char *frame) { } // TODO: a temporary function, merge with below
Cyc_Stack_Traces = calloc(MAX_STACK_TRACES, sizeof(char *)); void Cyc_st_add2(void *data, char *frame) {
} gc_thread_data *thd = (gc_thread_data *)data;
void Cyc_st_add(char *frame) {
// Do not allow recursion to remove older frames // Do not allow recursion to remove older frames
if (frame != Cyc_Stack_Prev_Frame) { if (frame != thd->stack_prev_frame) {
Cyc_Stack_Prev_Frame = frame; thd->stack_prev_frame = frame;
Cyc_Stack_Traces[Cyc_Stack_Trace_Idx] = frame; thd->stack_traces[thd->stack_trace_idx] = frame;
Cyc_Stack_Trace_Idx = (Cyc_Stack_Trace_Idx + 1) % MAX_STACK_TRACES; thd->stack_trace_idx = (thd->stack_trace_idx + 1) % MAX_STACK_TRACES;
} }
} }
void Cyc_st_print(FILE *out) { void Cyc_st_print(void *data, FILE *out) {
/* print to stream, note it is possible that /* print to stream, note it is possible that
some traces could be on the stack after a GC. some traces could be on the stack after a GC.
not sure what to do about it, may need to not sure what to do about it, may need to
@ -214,10 +209,11 @@ void Cyc_st_print(FILE *out) {
or, with the tbl being so small, maybe it will or, with the tbl being so small, maybe it will
not be an issue in practice? a bit risky to ignore though not be an issue in practice? a bit risky to ignore though
*/ */
int i = (Cyc_Stack_Trace_Idx + 1) % MAX_STACK_TRACES; gc_thread_data *thd = (gc_thread_data *)data;
while (i != Cyc_Stack_Trace_Idx) { int i = (thd->stack_trace_idx + 1) % MAX_STACK_TRACES;
if (Cyc_Stack_Traces[i]) { while (i != thd->stack_trace_idx) {
fprintf(out, "%s\n", Cyc_Stack_Traces[i]); if (thd->stack_traces[i]) {
fprintf(out, "%s\n", thd->stack_traces[i]);
} }
i = (i + 1) % MAX_STACK_TRACES; i = (i + 1) % MAX_STACK_TRACES;
} }
@ -361,7 +357,7 @@ object Cyc_default_exception_handler(void *data, int argc, closure _, object err
} }
fprintf(stderr, "\nCall history:\n"); fprintf(stderr, "\nCall history:\n");
Cyc_st_print(stderr); Cyc_st_print(data, stderr);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
//raise(SIGINT); // break into debugger, unix only //raise(SIGINT); // break into debugger, unix only
exit(1); exit(1);
@ -2484,6 +2480,13 @@ void Cyc_apply_from_buf(void *data, int argc, object prim, object *buf) {
void Cyc_start_thread(gc_thread_data *thd) void Cyc_start_thread(gc_thread_data *thd)
{ {
thd->stack_trace_idx = 0;
thd->stack_prev_frame = NULL;
// TODO: may need to relocate the calloc to another function that
// initializes thread objects, rather than here that just calls them.
// at a minimum, should initialize it to NULL so we can test for that here.
thd->stack_traces = calloc(MAX_STACK_TRACES, sizeof(char *));
/* Tank, load the jump program... */ /* Tank, load the jump program... */
setjmp(*(thd->jmp_start)); setjmp(*(thd->jmp_start));

View file

@ -183,7 +183,7 @@
(null? (cdr trace))) (null? (cdr trace)))
"" ""
(string-append (string-append
"Cyc_st_add(\"" "Cyc_st_add2(data, \""
(car trace) (car trace)
":" ":"
;; TODO: escape backslashes ;; TODO: escape backslashes