void __traceobj_mark(struct traceobj *trobj, const char *file, int line, int mark) { struct tracemark *tmk; struct service svc; int cur_mark; CANCEL_DEFER(svc); pthread_testcancel(); push_cleanup_lock(&trobj->lock); write_lock(&trobj->lock); cur_mark = trobj->cur_mark; if (cur_mark >= trobj->nr_marks) { dump_marks(trobj); panic("too many marks: [%d] at %s:%d", mark, file, line); } tmk = trobj->marks + cur_mark; tmk->file = file; tmk->line = line; tmk->mark = mark; trobj->cur_mark++; write_unlock(&trobj->lock); pop_cleanup_lock(&trobj->lock); CANCEL_RESTORE(svc); }
void backtrace_dump(struct backtrace_data *btd) { struct error_frame *ef; FILE *tracefp = stderr; int n = 0; if (btd == NULL) btd = &main_btd; push_cleanup_lock(&__printlock); read_lock(&__printlock); if (btd->inner == NULL) goto no_error; fprintf(tracefp, "%s\n[ ERROR BACKTRACE: thread %s ]\n\n", dashes, btd->name); for (ef = btd->inner; ef; ef = ef->next, n++) fprintf(tracefp, "%s #%-2d %s in %s(), %s:%d\n", ef->next ? " " : "=>", n, symerror(ef->retval), ef->fn, ef->file, ef->lineno); fputs(dashes, tracefp); fputc('\n', tracefp); fflush(tracefp); flush_backtrace(btd); no_error: read_unlock(&__printlock); pop_cleanup_lock(&__printlock); }
static void dump_marks_on_error(struct traceobj *trobj) { struct service svc; CANCEL_DEFER(svc); push_cleanup_lock(&trobj->lock); read_lock(&trobj->lock); dump_marks(trobj); read_unlock(&trobj->lock); pop_cleanup_lock(&trobj->lock); CANCEL_RESTORE(svc); }
void traceobj_join(struct traceobj *trobj) { struct service svc; CANCEL_DEFER(svc); push_cleanup_lock(&trobj->lock); read_lock(&trobj->lock); while (trobj->nr_threads < 0 || trobj->nr_threads > 0) threadobj_cond_wait(&trobj->join, &trobj->lock); read_unlock(&trobj->lock); pop_cleanup_lock(&trobj->lock); CANCEL_RESTORE(svc); }