[profiler] Add a thread ID field to sample events.
authorAlex Rønne Petersen <alexrp@xamarin.com>
Sat, 11 Jul 2015 09:48:09 +0000 (11:48 +0200)
committerAlex Rønne Petersen <alexrp@xamarin.com>
Sat, 11 Jul 2015 09:48:09 +0000 (11:48 +0200)
Previously, it was impossible to determine which thread a sample came from
because the buffer header thread ID for all sample events is the same (that of
the profiler's helper thread).

mono/profiler/decode.c
mono/profiler/proflog.c
mono/profiler/proflog.h

index 9690f6297bd6c2fdc5585e28e6bedcafeee2e360..cc1b7a495fccc1a562a166a7d071920f33de4bbf 100644 (file)
@@ -2574,13 +2574,16 @@ decode_buffer (ProfContext *ctx)
                                int i;
                                int sample_type = decode_uleb128 (p + 1, &p);
                                uint64_t tstamp = decode_uleb128 (p, &p);
+                               void *tid = (void *) thread_id;
+                               if (ctx->data_version > 10)
+                                       tid = (void *) (ptr_base + decode_sleb128 (p, &p));
                                int count = decode_uleb128 (p, &p);
                                for (i = 0; i < count; ++i) {
                                        uintptr_t ip = ptr_base + decode_sleb128 (p, &p);
                                        if ((tstamp >= time_from && tstamp < time_to))
                                                add_stat_sample (sample_type, ip);
                                        if (debug)
-                                               fprintf (outfile, "sample hit, type: %d at %p\n", sample_type, (void*)ip);
+                                               fprintf (outfile, "sample hit, type: %d at %p for thread %p\n", sample_type, (void*)ip, tid);
                                }
                                if (ctx->data_version > 5) {
                                        count = decode_uleb128 (p, &p);
index 3183048c2d86b62fe7af45b235bc05eb99e51248..04d837ba7e2bf4ffbd35ec81993341ed11f53bb0 100644 (file)
@@ -296,6 +296,8 @@ typedef struct _LogBuffer LogBuffer;
  * if exinfo == TYPE_SAMPLE_HIT
  *     [sample_type: uleb128] type of sample (SAMPLE_*)
  *     [timestamp: uleb128] nanoseconds since startup (note: different from other timestamps!)
+ *     if (format_version > 10)
+ *             [thread: sleb128] thread id as difference from ptr_base
  *     [count: uleb128] number of following instruction addresses
  *     [ip: sleb128]* instruction pointer as difference from ptr_base
  *     if (format_version > 5)
@@ -1888,6 +1890,7 @@ dump_sample_hits (MonoProfiler *prof, StatBuffer *sbuf)
                int mbt_count = (sample [0] & 0xff00) >> 8;
                int type = sample [0] >> 16;
                uintptr_t *managed_sample_base = sample + count + 3;
+               uintptr_t thread_id = sample [1];
 
                for (int i = 0; i < mbt_count; ++i) {
                        MonoMethod *method = (MonoMethod*)managed_sample_base [i * 4 + 0];
@@ -1906,6 +1909,7 @@ dump_sample_hits (MonoProfiler *prof, StatBuffer *sbuf)
                emit_byte (logbuffer, TYPE_SAMPLE | TYPE_SAMPLE_HIT);
                emit_value (logbuffer, type);
                emit_uvalue (logbuffer, prof->startup_time + (uint64_t)sample [2] * (uint64_t)10000);
+               emit_ptr (logbuffer, (void *) thread_id);
                emit_value (logbuffer, count);
                for (int i = 0; i < count; ++i) {
                        emit_ptr (logbuffer, (void*)sample [i + 3]);
@@ -2058,6 +2062,12 @@ dump_perf_hits (MonoProfiler *prof, void *buf, int size)
                emit_byte (logbuffer, TYPE_SAMPLE | TYPE_SAMPLE_HIT);
                emit_value (logbuffer, sample_type);
                emit_uvalue (logbuffer, s->timestamp - prof->startup_time);
+               /*
+                * No useful thread ID to write here, since throughout the
+                * profiler we use pthread_self () but the ID we get from
+                * perf is the kernel's thread ID.
+                */
+               emit_ptr (logbuffer, 0);
                emit_value (logbuffer, 1); /* count */
                emit_ptr (logbuffer, (void*)(uintptr_t)s->ip);
                /* no support here yet for the managed backtrace */
index 8b7260bb1eb134047029febaf63e6141ec54a79b..7f32873789ebd7295bcf623ce5c8e11387a57317 100644 (file)
@@ -5,7 +5,7 @@
 #define LOG_HEADER_ID 0x4D505A01
 #define LOG_VERSION_MAJOR 0
 #define LOG_VERSION_MINOR 4
-#define LOG_DATA_VERSION 10
+#define LOG_DATA_VERSION 11
 /*
  * Changes in data versions:
  * version 2: added offsets in heap walk
@@ -16,6 +16,7 @@
  * version 8: added TYPE_RUNTIME and JIT helpers/trampolines
  * version 9: added MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING
  * version 10: added TYPE_COVERAGE
+ * version 11: added thread ID to TYPE_SAMPLE_HIT
  */
 
 enum {