case MONO_COUNTER_SECURITY: return "Mono Security";
case MONO_COUNTER_RUNTIME: return "Mono Runtime";
case MONO_COUNTER_SYSTEM: return "Mono System";
+ case MONO_COUNTER_PROFILER: return "Mono Profiler";
default: return "<unknown>";
}
}
/* we resolved an unknown class (unless we had the code unloaded) */
if (cd) {
/*printf ("resolved unknown: %s\n", name);*/
- free (cd->name);
+ g_free (cd->name);
cd->name = pstrdup (name);
return cd;
}
cd->code = code;
cd->len = len;
/*printf ("resolved unknown: %s\n", name);*/
- free (cd->name);
+ g_free (cd->name);
cd->name = pstrdup (name);
return cd;
}
add_rev_class_hashed (n, to->rev_hash_size, to->rev_hash [i].klass, to->rev_hash [i].count);
}
if (to->rev_hash)
- free (to->rev_hash);
+ g_free (to->rev_hash);
to->rev_hash = n;
}
to->rev_count += add_rev_class_hashed (to->rev_hash, to->rev_hash_size, from, 1);
add_heap_hashed (n, &res, hs->hash_size, hs->class_hash [i]->klass, hs->class_hash [i]->total_size, hs->class_hash [i]->count);
}
if (hs->class_hash)
- free (hs->class_hash);
+ g_free (hs->class_hash);
hs->class_hash = n;
}
res = NULL;
HeapObjectDesc* ho = alloc_heap_obj (objaddr, hash [i]->hklass, hash [i]->num_refs + num);
*ref_offset = hash [i]->num_refs;
memcpy (ho->refs, hash [i]->refs, hash [i]->num_refs * sizeof (uintptr_t));
- free (hash [i]);
+ g_free (hash [i]);
hash [i] = ho;
return ho;
}
add_heap_hashed_obj (n, hs->objects_hash_size, hs->objects_hash [i]);
}
if (hs->objects_hash)
- free (hs->objects_hash);
+ g_free (hs->objects_hash);
hs->objects_hash = n;
}
hs->objects_count += add_heap_hashed_obj (hs->objects_hash, hs->objects_hash_size, obj);
}
}
fprintf (outfile, "Total unmarked: %zd/%zd\n", num_unmarked, hs->objects_count);
- free (marks);
+ g_free (marks);
}
static void
for (i = 0; i < hs->objects_hash_size; ++i) {
HeapObjectDesc *ho = hs->objects_hash [i];
if (ho)
- free (ho);
+ g_free (ho);
}
if (hs->objects_hash)
- free (hs->objects_hash);
+ g_free (hs->objects_hash);
hs->objects_hash = NULL;
hs->objects_hash_size = 0;
hs->objects_count = 0;
int timer_overhead;
int pid;
int port;
+ char *args;
+ char *arch;
+ char *os;
uint64_t startup_time;
ThreadContext *threads;
ThreadContext *current_thread;
add_trace_hashed (n, trace->size, trace->traces [i].bt, trace->traces [i].count);
}
if (trace->traces)
- free (trace->traces);
+ g_free (trace->traces);
trace->traces = n;
}
trace->count += add_trace_hashed (trace->traces, trace->size, bt, value);
case MONO_GC_EVENT_RECLAIM_END: return "reclaim end";
case MONO_GC_EVENT_END: return "end";
case MONO_GC_EVENT_PRE_STOP_WORLD: return "pre stop";
+ case MONO_GC_EVENT_PRE_STOP_WORLD_LOCKED: return "pre stop lock";
case MONO_GC_EVENT_POST_STOP_WORLD: return "post stop";
case MONO_GC_EVENT_PRE_START_WORLD: return "pre start";
case MONO_GC_EVENT_POST_START_WORLD: return "post start";
+ case MONO_GC_EVENT_POST_START_WORLD_UNLOCKED: return "post start unlock";
+ default:
+ return "unknown";
+ }
+}
+
+static const char*
+sync_point_name (int type)
+{
+ switch (type) {
+ case SYNC_POINT_PERIODIC: return "periodic";
+ case SYNC_POINT_WORLD_STOP: return "world stop";
+ case SYNC_POINT_WORLD_START: return "world start";
default:
return "unknown";
}
}
static MethodDesc**
-decode_bt (MethodDesc** sframes, int *size, unsigned char *p, unsigned char **endp, intptr_t ptr_base)
+decode_bt (ProfContext *ctx, MethodDesc** sframes, int *size, unsigned char *p, unsigned char **endp, intptr_t ptr_base, intptr_t *method_base)
{
MethodDesc **frames;
int i;
- int flags = decode_uleb128 (p, &p);
+ if (ctx->data_version < 13)
+ decode_uleb128 (p, &p); /* flags */
int count = decode_uleb128 (p, &p);
- if (flags != 0)
- return NULL;
if (count > *size)
frames = (MethodDesc **)malloc (count * sizeof (void*));
else
frames = sframes;
for (i = 0; i < count; ++i) {
intptr_t ptrdiff = decode_sleb128 (p, &p);
- frames [i] = lookup_method (ptr_base + ptrdiff);
+ if (ctx->data_version > 12) {
+ *method_base += ptrdiff;
+ frames [i] = lookup_method (*method_base);
+ } else {
+ frames [i] = lookup_method (ptr_base + ptrdiff);
+ }
}
*size = count;
*endp = p;
time_from += startup_time;
time_to += startup_time;
}
- if (!thread->name)
- thread->name = pstrdup ("Main");
}
for (i = 0; i < thread->stack_id; ++i)
thread->stack [i]->recurse_count++;
if (new_size > max_heap_size)
max_heap_size = new_size;
} else if (subtype == TYPE_GC_EVENT) {
- uint64_t ev = decode_uleb128 (p, &p);
- int gen = decode_uleb128 (p, &p);
+ uint64_t ev;
+ if (ctx->data_version > 12)
+ ev = *p++;
+ else
+ ev = decode_uleb128 (p, &p);
+ int gen;
+ if (ctx->data_version > 12)
+ gen = *p++;
+ else
+ gen = decode_uleb128 (p, &p);
if (debug)
fprintf (outfile, "gc event for gen%d: %s at %llu (thread: 0x%zx)\n", gen, gc_event_name (ev), (unsigned long long) time_base, thread->thread_id);
if (gen > 2) {
intptr_t objdiff = decode_sleb128 (p, &p);
if (has_bt) {
num_bt = 8;
- frames = decode_bt (sframes, &num_bt, p, &p, ptr_base);
+ frames = decode_bt (ctx, sframes, &num_bt, p, &p, ptr_base, &method_base);
if (!frames) {
fprintf (outfile, "Cannot load backtrace\n");
return 0;
if (debug)
fprintf (outfile, "handle (%s) %u created for object %p\n", get_handle_name (htype), handle, (void*)OBJ_ADDR (objdiff));
if (frames != sframes)
- free (frames);
+ g_free (frames);
} else if (subtype == TYPE_GC_HANDLE_DESTROYED || subtype == TYPE_GC_HANDLE_DESTROYED_BT) {
int has_bt = subtype == TYPE_GC_HANDLE_DESTROYED_BT;
int num_bt = 0;
uint32_t handle = decode_uleb128 (p, &p);
if (has_bt) {
num_bt = 8;
- frames = decode_bt (sframes, &num_bt, p, &p, ptr_base);
+ frames = decode_bt (ctx, sframes, &num_bt, p, &p, ptr_base, &method_base);
if (!frames) {
fprintf (outfile, "Cannot load backtrace\n");
return 0;
if (debug)
fprintf (outfile, "handle (%s) %u destroyed\n", get_handle_name (htype), handle);
if (frames != sframes)
- free (frames);
+ g_free (frames);
+ } else if (subtype == TYPE_GC_FINALIZE_START) {
+ // TODO: Generate a finalizer report based on these events.
+ if (debug)
+ fprintf (outfile, "gc finalizer queue being processed at %llu\n", (unsigned long long) time_base);
+ } else if (subtype == TYPE_GC_FINALIZE_END) {
+ if (debug)
+ fprintf (outfile, "gc finalizer queue finished processing at %llu\n", (unsigned long long) time_base);
+ } else if (subtype == TYPE_GC_FINALIZE_OBJECT_START) {
+ intptr_t objdiff = decode_sleb128 (p, &p);
+ if (debug)
+ fprintf (outfile, "gc finalizing object %p at %llu\n", (void *) OBJ_ADDR (objdiff), (unsigned long long) time_base);
+ } else if (subtype == TYPE_GC_FINALIZE_OBJECT_END) {
+ intptr_t objdiff = decode_sleb128 (p, &p);
+ if (debug)
+ fprintf (outfile, "gc finalized object %p at %llu\n", (void *) OBJ_ADDR (objdiff), (unsigned long long) time_base);
}
break;
}
time_base += tdiff;
if (mtype == TYPE_CLASS) {
intptr_t imptrdiff = decode_sleb128 (p, &p);
- uint64_t flags = decode_uleb128 (p, &p);
- if (flags) {
- fprintf (outfile, "non-zero flags in class\n");
- return 0;
- }
+ if (ctx->data_version < 13)
+ decode_uleb128 (p, &p); /* flags */
if (debug)
fprintf (outfile, "%s class %p (%s in %p) at %llu\n", load_str, (void*)(ptr_base + ptrdiff), p, (void*)(ptr_base + imptrdiff), (unsigned long long) time_base);
if (subtype == TYPE_END_LOAD)
while (*p) p++;
p++;
} else if (mtype == TYPE_IMAGE) {
- uint64_t flags = decode_uleb128 (p, &p);
- if (flags) {
- fprintf (outfile, "non-zero flags in image\n");
- return 0;
- }
+ if (ctx->data_version < 13)
+ decode_uleb128 (p, &p); /* flags */
if (debug)
fprintf (outfile, "%s image %p (%s) at %llu\n", load_str, (void*)(ptr_base + ptrdiff), p, (unsigned long long) time_base);
if (subtype == TYPE_END_LOAD)
while (*p) p++;
p++;
} else if (mtype == TYPE_ASSEMBLY) {
- uint64_t flags = decode_uleb128 (p, &p);
- if (flags) {
- fprintf (outfile, "non-zero flags in assembly\n");
- return 0;
- }
+ if (ctx->data_version < 13)
+ decode_uleb128 (p, &p); /* flags */
if (debug)
fprintf (outfile, "%s assembly %p (%s) at %llu\n", load_str, (void*)(ptr_base + ptrdiff), p, (unsigned long long) time_base);
if (subtype == TYPE_END_LOAD)
while (*p) p++;
p++;
} else if (mtype == TYPE_DOMAIN) {
- uint64_t flags = decode_uleb128 (p, &p);
- if (flags) {
- fprintf (outfile, "non-zero flags in domain\n");
- return 0;
- }
+ if (ctx->data_version < 13)
+ decode_uleb128 (p, &p); /* flags */
DomainContext *nd = get_domain (ctx, ptr_base + ptrdiff);
/* no subtype means it's a name event, rather than start/stop */
if (subtype == 0)
p++;
}
} else if (mtype == TYPE_CONTEXT) {
- uint64_t flags = decode_uleb128 (p, &p);
- if (flags) {
- fprintf (outfile, "non-zero flags in context\n");
- return 0;
- }
+ if (ctx->data_version < 13)
+ decode_uleb128 (p, &p); /* flags */
intptr_t domaindiff = decode_sleb128 (p, &p);
if (debug)
fprintf (outfile, "%s context %p (%p) at %llu\n", load_str, (void*)(ptr_base + ptrdiff), (void *) (ptr_base + domaindiff), (unsigned long long) time_base);
if (subtype == TYPE_END_LOAD)
get_remctx (ctx, ptr_base + ptrdiff)->domain_id = ptr_base + domaindiff;
} else if (mtype == TYPE_THREAD) {
- uint64_t flags = decode_uleb128 (p, &p);
- if (flags) {
- fprintf (outfile, "non-zero flags in thread\n");
- return 0;
- }
+ if (ctx->data_version < 13)
+ decode_uleb128 (p, &p); /* flags */
ThreadContext *nt = get_thread (ctx, ptr_base + ptrdiff);
/* no subtype means it's a name event, rather than start/stop */
if (subtype == 0)
fprintf (outfile, "alloced object %p, size %llu (%s) at %llu\n", (void*)OBJ_ADDR (objdiff), (unsigned long long) len, lookup_class (ptr_base + ptrdiff)->name, (unsigned long long) time_base);
if (has_bt) {
num_bt = 8;
- frames = decode_bt (sframes, &num_bt, p, &p, ptr_base);
+ frames = decode_bt (ctx, sframes, &num_bt, p, &p, ptr_base, &method_base);
if (!frames) {
fprintf (outfile, "Cannot load backtrace\n");
return 0;
tracked_creation (OBJ_ADDR (objdiff), cd, len, bt, time_base);
}
if (frames != sframes)
- free (frames);
+ g_free (frames);
break;
}
case TYPE_METHOD: {
if (subtype == TYPE_HEAP_OBJECT) {
HeapObjectDesc *ho = NULL;
int i;
- intptr_t objdiff = decode_sleb128 (p + 1, &p);
+ intptr_t objdiff;
+ if (ctx->data_version > 12) {
+ uint64_t tdiff = decode_uleb128 (p + 1, &p);
+ LOG_TIME (time_base, tdiff);
+ time_base += tdiff;
+ objdiff = decode_sleb128 (p, &p);
+ } else
+ objdiff = decode_sleb128 (p + 1, &p);
intptr_t ptrdiff = decode_sleb128 (p, &p);
uint64_t size = decode_uleb128 (p, &p);
uintptr_t num = decode_uleb128 (p, &p);
if (debug && size)
fprintf (outfile, "traced object %p, size %llu (%s), refs: %zd\n", (void*)OBJ_ADDR (objdiff), (unsigned long long) size, cd->name, num);
} else if (subtype == TYPE_HEAP_ROOT) {
- uintptr_t num = decode_uleb128 (p + 1, &p);
+ uintptr_t num;
+ if (ctx->data_version > 12) {
+ uint64_t tdiff = decode_uleb128 (p + 1, &p);
+ LOG_TIME (time_base, tdiff);
+ time_base += tdiff;
+ num = decode_uleb128 (p, &p);
+ } else
+ num = decode_uleb128 (p + 1, &p);
uintptr_t gc_num G_GNUC_UNUSED = decode_uleb128 (p, &p);
int i;
for (i = 0; i < num; ++i) {
intptr_t objdiff = decode_sleb128 (p, &p);
- int root_type = decode_uleb128 (p, &p);
+ int root_type;
+ if (ctx->data_version > 12)
+ root_type = *p++;
+ else
+ root_type = decode_uleb128 (p, &p);
/* we just discard the extra info for now */
uintptr_t extra_info = decode_uleb128 (p, &p);
if (debug)
hs->roots_extra = thread->roots_extra;
hs->roots_types = thread->roots_types;
} else {
- free (thread->roots);
- free (thread->roots_extra);
- free (thread->roots_types);
+ g_free (thread->roots);
+ g_free (thread->roots_extra);
+ g_free (thread->roots_types);
}
thread->num_roots = 0;
thread->size_roots = 0;
}
if (has_bt) {
num_bt = 8;
- frames = decode_bt (sframes, &num_bt, p, &p, ptr_base);
+ frames = decode_bt (ctx, sframes, &num_bt, p, &p, ptr_base, &method_base);
if (!frames) {
fprintf (outfile, "Cannot load backtrace\n");
return 0;
if (debug)
fprintf (outfile, "monitor %s for object %p\n", monitor_ev_name (event), (void*)OBJ_ADDR (objdiff));
if (frames != sframes)
- free (frames);
+ g_free (frames);
break;
}
case TYPE_EXCEPTION: {
int subtype = *p & 0x70;
- int has_bt = *p & TYPE_EXCEPTION_BT;
+ int has_bt = *p & TYPE_THROW_BT;
uint64_t tdiff = decode_uleb128 (p + 1, &p);
MethodDesc* sframes [8];
MethodDesc** frames = sframes;
if (!(time_base >= time_from && time_base < time_to))
record = 0;
if (subtype == TYPE_CLAUSE) {
- int clause_type = decode_uleb128 (p, &p);
+ int clause_type;
+ if (ctx->data_version > 12)
+ clause_type = *p++;
+ else
+ clause_type = decode_uleb128 (p, &p);
int clause_num = decode_uleb128 (p, &p);
int64_t ptrdiff = decode_sleb128 (p, &p);
method_base += ptrdiff;
throw_count++;
if (has_bt) {
has_bt = 8;
- frames = decode_bt (sframes, &has_bt, p, &p, ptr_base);
+ frames = decode_bt (ctx, sframes, &has_bt, p, &p, ptr_base, &method_base);
if (!frames) {
fprintf (outfile, "Cannot load backtrace\n");
return 0;
add_trace_thread (thread, &exc_traces, 1);
}
if (frames != sframes)
- free (frames);
+ g_free (frames);
if (debug)
fprintf (outfile, "throw %p\n", (void*)OBJ_ADDR (objdiff));
}
LOG_TIME (time_base, tdiff);
time_base += tdiff;
if (subtype == TYPE_JITHELPER) {
- int type = decode_uleb128 (p, &p);
+ int type;
+ if (ctx->data_version > 12)
+ type = *p++;
+ else
+ type = decode_uleb128 (p, &p);
intptr_t codediff = decode_sleb128 (p, &p);
int codelen = decode_uleb128 (p, &p);
const char *name;
int subtype = *p & 0xf0;
if (subtype == TYPE_SAMPLE_HIT) {
int i;
- int sample_type = decode_uleb128 (p + 1, &p);
- uint64_t tstamp = decode_uleb128 (p, &p);
+ int sample_type;
+ uint64_t tstamp;
+ if (ctx->data_version > 12) {
+ uint64_t tdiff = decode_uleb128 (p + 1, &p);
+ LOG_TIME (time_base, tdiff);
+ time_base += tdiff;
+ sample_type = *p++;
+ tstamp = time_base;
+ } else {
+ sample_type = decode_uleb128 (p + 1, &p);
+ tstamp = decode_uleb128 (p, &p);
+ }
void *tid = (void *) thread_id;
if (ctx->data_version > 10)
tid = (void *) (ptr_base + decode_sleb128 (p, &p));
for (i = 0; i < count; ++i) {
MethodDesc *method;
int64_t ptrdiff = decode_sleb128 (p, &p);
- int il_offset = decode_sleb128 (p, &p);
- int native_offset = decode_sleb128 (p, &p);
method_base += ptrdiff;
method = lookup_method (method_base);
if (debug)
- fprintf (outfile, "sample hit bt %d: %s at IL offset %d (native: %d)\n", i, method->name, il_offset, native_offset);
+ fprintf (outfile, "sample hit bt %d: %s\n", i, method->name);
+ if (ctx->data_version < 13) {
+ decode_sleb128 (p, &p); /* il offset */
+ decode_sleb128 (p, &p); /* native offset */
+ }
}
}
} else if (subtype == TYPE_SAMPLE_USYM) {
/* un unmanaged symbol description */
- uintptr_t addr = ptr_base + decode_sleb128 (p + 1, &p);
+ uintptr_t addr;
+ if (ctx->data_version > 12) {
+ uint64_t tdiff = decode_uleb128 (p + 1, &p);
+ LOG_TIME (time_base, tdiff);
+ time_base += tdiff;
+ addr = ptr_base + decode_sleb128 (p, &p);
+ } else
+ addr = ptr_base + decode_sleb128 (p + 1, &p);
uintptr_t size = decode_uleb128 (p, &p);
char *name;
name = pstrdup ((char*)p);
while (*p) p++;
p++;
} else if (subtype == TYPE_SAMPLE_COUNTERS_DESC) {
- uint64_t i, len = decode_uleb128 (p + 1, &p);
+ uint64_t i, len;
+ if (ctx->data_version > 12) {
+ uint64_t tdiff = decode_uleb128 (p + 1, &p);
+ LOG_TIME (time_base, tdiff);
+ time_base += tdiff;
+ len = decode_uleb128 (p, &p);
+ } else
+ len = decode_uleb128 (p + 1, &p);
for (i = 0; i < len; i++) {
uint64_t type, unit, variance, index;
uint64_t section = decode_uleb128 (p, &p);
}
name = pstrdup ((char*)p);
while (*p++);
- type = decode_uleb128 (p, &p);
- unit = decode_uleb128 (p, &p);
- variance = decode_uleb128 (p, &p);
+ if (ctx->data_version > 12) {
+ type = *p++;
+ unit = *p++;
+ variance = *p++;
+ } else {
+ type = decode_uleb128 (p, &p);
+ unit = decode_uleb128 (p, &p);
+ variance = decode_uleb128 (p, &p);
+ }
index = decode_uleb128 (p, &p);
add_counter (section_str, name, (int)type, (int)unit, (int)variance, (int)index);
}
int i;
CounterValue *value, *previous = NULL;
CounterList *list;
- uint64_t timestamp = decode_uleb128 (p + 1, &p);
+ uint64_t timestamp; // milliseconds since startup
+ if (ctx->data_version > 12) {
+ uint64_t tdiff = decode_uleb128 (p + 1, &p);
+ LOG_TIME (time_base, tdiff);
+ time_base += tdiff;
+ timestamp = (time_base - startup_time) / 1000 / 1000;
+ } else
+ timestamp = decode_uleb128 (p + 1, &p);
uint64_t time_between = timestamp / 1000 * 1000 * 1000 * 1000 + startup_time;
while (1) {
uint64_t type, index = decode_uleb128 (p, &p);
}
}
- type = decode_uleb128 (p, &p);
+ if (ctx->data_version > 12)
+ type = *p++;
+ else
+ type = decode_uleb128 (p, &p);
value = (CounterValue *)calloc (1, sizeof (CounterValue));
value->timestamp = timestamp;
int token, n_offsets, method_id;
p++;
+
+ if (ctx->data_version > 12) {
+ uint64_t tdiff = decode_uleb128 (p, &p);
+ LOG_TIME (time_base, tdiff);
+ time_base += tdiff;
+ }
+
assembly = (const char *)p; while (*p) p++; p++;
klass = (const char *)p; while (*p) p++; p++;
name = (const char *)p; while (*p) p++; p++;
int offset, count, line, column, method_id;
p++;
+
+ if (ctx->data_version > 12) {
+ uint64_t tdiff = decode_uleb128 (p, &p);
+ LOG_TIME (time_base, tdiff);
+ time_base += tdiff;
+ }
+
method_id = decode_uleb128 (p, &p);
offset = decode_uleb128 (p, &p);
count = decode_uleb128 (p, &p);
int number_of_methods, fully_covered, partially_covered;
p++;
+ if (ctx->data_version > 12) {
+ uint64_t tdiff = decode_uleb128 (p, &p);
+ LOG_TIME (time_base, tdiff);
+ time_base += tdiff;
+ }
+
name = (char *)p; while (*p) p++; p++;
guid = (char *)p; while (*p) p++; p++;
filename = (char *)p; while (*p) p++; p++;
int number_of_methods, fully_covered, partially_covered;
p++;
+ if (ctx->data_version > 12) {
+ uint64_t tdiff = decode_uleb128 (p, &p);
+ LOG_TIME (time_base, tdiff);
+ time_base += tdiff;
+ }
+
assembly_name = (char *)p; while (*p) p++; p++;
class_name = (char *)p; while (*p) p++; p++;
number_of_methods = decode_uleb128 (p, &p);
}
break;
}
+ case TYPE_META: {
+ int subtype = *p & 0xf0;
+ uint64_t tdiff = decode_uleb128 (p + 1, &p);
+ LOG_TIME (time_base, tdiff);
+ time_base += tdiff;
+ if (subtype == TYPE_SYNC_POINT) {
+ int type = *p++;
+ if (debug)
+ fprintf (outfile, "sync point %i (%s)\n", type, sync_point_name (type));
+ }
+ break;
+ }
default:
fprintf (outfile, "unhandled profiler event: 0x%x at file offset: %llu + %lld (len: %d\n)\n", *p, (unsigned long long) file_offset, (long long) (p - ctx->buf), len);
exit (1);
return 1;
}
+static int
+read_header_string (ProfContext *ctx, char **field)
+{
+ if (!load_data (ctx, 4))
+ return 0;
+
+ if (!load_data (ctx, read_int32 (ctx->buf)))
+ return 0;
+
+ *field = pstrdup ((const char *) ctx->buf);
+
+ return 1;
+}
+
static ProfContext*
load_file (char *name)
{
if (ctx->file != stdin)
ctx->gzfile = gzdopen (fileno (ctx->file), "rb");
#endif
- if (!load_data (ctx, 32))
+ if (!load_data (ctx, 30))
return NULL;
p = ctx->buf;
if (read_int32 (p) != LOG_HEADER_ID || p [6] > LOG_DATA_VERSION)
ctx->timer_overhead = read_int32 (p + 16);
ctx->pid = read_int32 (p + 24);
ctx->port = read_int16 (p + 28);
+ if (ctx->version_major >= 1) {
+ if (!read_header_string (ctx, &ctx->args))
+ return NULL;
+ if (!read_header_string (ctx, &ctx->arch))
+ return NULL;
+ if (!read_header_string (ctx, &ctx->os))
+ return NULL;
+ } else {
+ if (!load_data (ctx, 2)) /* old opsys field, was never used */
+ return NULL;
+ }
return ctx;
}
fprintf (outfile, "\nMono log profiler data\n");
fprintf (outfile, "\tProfiler version: %d.%d\n", ctx->version_major, ctx->version_minor);
fprintf (outfile, "\tData version: %d\n", ctx->data_version);
+ if (ctx->version_major >= 1) {
+ fprintf (outfile, "\tArguments: %s\n", ctx->args);
+ fprintf (outfile, "\tArchitecture: %s\n", ctx->arch);
+ fprintf (outfile, "\tOperating system: %s\n", ctx->os);
+ }
fprintf (outfile, "\tMean timer overhead: %d nanoseconds\n", ctx->timer_overhead);
fprintf (outfile, "\tProgram startup: %s", t);
if (ctx->pid)
ThreadContext *thread;
fprintf (outfile, "\nThread summary\n");
for (thread = ctx->threads; thread; thread = thread->next) {
- fprintf (outfile, "\tThread: %p, name: \"%s\"\n", (void*)thread->thread_id, thread->name? thread->name: "");
+ if (thread->thread_id) {
+ fprintf (outfile, "\tThread: %p, name: \"%s\"\n", (void*)thread->thread_id, thread->name? thread->name: "");
+ }
}
}
if (cd->root_references)
fprintf (outfile, "\t\t%zd root references (%zd pinning)\n", cd->root_references, cd->pinned_references);
dump_rev_claases (rev_sorted, cd->rev_count);
- free (rev_sorted);
+ g_free (rev_sorted);
}
- free (sorted);
+ g_free (sorted);
}
static int
DUMP_EVENT_STAT (TYPE_METHOD, TYPE_EXC_LEAVE);
DUMP_EVENT_STAT (TYPE_METHOD, TYPE_JIT);
- DUMP_EVENT_STAT (TYPE_EXCEPTION, TYPE_THROW);
+ DUMP_EVENT_STAT (TYPE_EXCEPTION, TYPE_THROW_NO_BT);
+ DUMP_EVENT_STAT (TYPE_EXCEPTION, TYPE_THROW_BT);
DUMP_EVENT_STAT (TYPE_EXCEPTION, TYPE_CLAUSE);
- DUMP_EVENT_STAT (TYPE_EXCEPTION, TYPE_EXCEPTION_BT);
DUMP_EVENT_STAT (TYPE_MONITOR, TYPE_MONITOR_NO_BT);
DUMP_EVENT_STAT (TYPE_MONITOR, TYPE_MONITOR_BT);
DUMP_EVENT_STAT (TYPE_COVERAGE, TYPE_COVERAGE_METHOD);
DUMP_EVENT_STAT (TYPE_COVERAGE, TYPE_COVERAGE_STATEMENT);
DUMP_EVENT_STAT (TYPE_COVERAGE, TYPE_COVERAGE_CLASS);
+
+ DUMP_EVENT_STAT (TYPE_META, TYPE_SYNC_POINT);
}
*top++ = 0;
from_secs = atof (val);
to_secs = atof (top);
- free (val);
+ g_free (val);
if (from_secs > to_secs) {
usage ();
return 1;