X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=trace%2Fsimple.c;h=a221a3f70310bc72344f83b55689bf6e9b7f289b;hb=8efb339dd47b164429e9a57f36ac5c3dd810a4ce;hp=3fdcc82263b6f27ce9c105edc9b2220947ed6732;hpb=d38ea87ac54af64ef611de434d07c12dc0399216;p=mirror_qemu.git diff --git a/trace/simple.c b/trace/simple.c index 3fdcc82263..a221a3f703 100644 --- a/trace/simple.c +++ b/trace/simple.c @@ -13,18 +13,17 @@ #include #endif #include "qemu/timer.h" -#include "trace.h" #include "trace/control.h" #include "trace/simple.h" -/** Trace file header event ID */ -#define HEADER_EVENT_ID (~(uint64_t)0) /* avoids conflicting with TraceEventIDs */ +/** Trace file header event ID, picked to avoid conflict with real event IDs */ +#define HEADER_EVENT_ID (~(uint64_t)0) /** Trace file magic number */ #define HEADER_MAGIC 0xf2b177cb0aa429b4ULL /** Trace file version number, bump if format changes */ -#define HEADER_VERSION 3 +#define HEADER_VERSION 4 /** Records were dropped event ID */ #define DROPPED_EVENT_ID (~(uint64_t)0 - 1) @@ -56,9 +55,12 @@ static uint32_t trace_pid; static FILE *trace_fp; static char *trace_file_name; +#define TRACE_RECORD_TYPE_MAPPING 0 +#define TRACE_RECORD_TYPE_EVENT 1 + /* * Trace buffer entry */ typedef struct { - uint64_t event; /* TraceEventID */ + uint64_t event; /* event ID value */ uint64_t timestamp_ns; uint32_t length; /* in bytes */ uint32_t pid; @@ -108,7 +110,7 @@ static bool get_trace_record(unsigned int idx, TraceRecord **recordptr) smp_rmb(); /* read memory barrier before accessing record */ /* read the record header to know record length */ read_from_buffer(idx, &record, sizeof(TraceRecord)); - *recordptr = malloc(record.length); /* dont use g_malloc, can deadlock when traced */ + *recordptr = malloc(record.length); /* don't use g_malloc, can deadlock when traced */ /* make a copy of record to avoid being overwritten */ read_from_buffer(idx, *recordptr, record.length); smp_rmb(); /* memory barrier before clearing valid flag */ @@ -160,6 +162,7 @@ static gpointer writeout_thread(gpointer opaque) unsigned int idx = 0; int dropped_count; size_t unused __attribute__ ((unused)); + uint64_t type = TRACE_RECORD_TYPE_EVENT; for (;;) { wait_for_trace_records_available(); @@ -174,13 +177,15 @@ static gpointer writeout_thread(gpointer opaque) } while (!g_atomic_int_compare_and_exchange(&dropped_events, dropped_count, 0)); dropped.rec.arguments[0] = dropped_count; + unused = fwrite(&type, sizeof(type), 1, trace_fp); unused = fwrite(&dropped.rec, dropped.rec.length, 1, trace_fp); } while (get_trace_record(idx, &recordptr)) { + unused = fwrite(&type, sizeof(type), 1, trace_fp); unused = fwrite(recordptr, recordptr->length, 1, trace_fp); writeout_idx += recordptr->length; - free(recordptr); /* dont use g_free, can deadlock when traced */ + free(recordptr); /* don't use g_free, can deadlock when traced */ idx = writeout_idx % TRACE_BUF_LEN; } @@ -202,7 +207,7 @@ void trace_record_write_str(TraceBufferRecord *rec, const char *s, uint32_t slen rec->rec_off = write_to_buffer(rec->rec_off, (void*)s, slen); } -int trace_record_start(TraceBufferRecord *rec, TraceEventID event, size_t datasize) +int trace_record_start(TraceBufferRecord *rec, uint32_t event, size_t datasize) { unsigned int idx, rec_off, old_idx, new_idx; uint32_t rec_len = sizeof(TraceRecord) + datasize; @@ -273,6 +278,28 @@ void trace_record_finish(TraceBufferRecord *rec) } } +static int st_write_event_mapping(void) +{ + uint64_t type = TRACE_RECORD_TYPE_MAPPING; + TraceEventIter iter; + TraceEvent *ev; + + trace_event_iter_init(&iter, NULL); + while ((ev = trace_event_iter_next(&iter)) != NULL) { + uint64_t id = trace_event_get_id(ev); + const char *name = trace_event_get_name(ev); + uint32_t len = strlen(name); + if (fwrite(&type, sizeof(type), 1, trace_fp) != 1 || + fwrite(&id, sizeof(id), 1, trace_fp) != 1 || + fwrite(&len, sizeof(len), 1, trace_fp) != 1 || + fwrite(name, len, 1, trace_fp) != 1) { + return -1; + } + } + + return 0; +} + void st_set_trace_file_enabled(bool enable) { if (enable == !!trace_fp) { @@ -297,7 +324,8 @@ void st_set_trace_file_enabled(bool enable) return; } - if (fwrite(&header, sizeof header, 1, trace_fp) != 1) { + if (fwrite(&header, sizeof header, 1, trace_fp) != 1 || + st_write_event_mapping() < 0) { fclose(trace_fp); trace_fp = NULL; return;