mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2025-12-31 20:36:25 +00:00
libsysprof: handle mmap2 records
We still need to add an additional capture writer so that we can keep the build-id around, but this gets the mechanics in place to handle the PERF_EVENT_MMAP2 event type.
This commit is contained in:
@ -140,6 +140,7 @@ typedef union _SysprofPerfEvent
|
||||
SysprofPerfEventComm comm;
|
||||
SysprofPerfEventExit exit;
|
||||
SysprofPerfEventMmap mmap;
|
||||
SysprofPerfEventMmap2 mmap2;
|
||||
SysprofPerfEventCallchain callchain;
|
||||
SysprofPerfEventTracepoint tracepoint;
|
||||
guint8 raw[0];
|
||||
|
||||
@ -232,6 +232,8 @@ sysprof_perf_event_stream_flush (SysprofPerfEventStream *self)
|
||||
case PERF_RECORD_COMM:
|
||||
case PERF_RECORD_EXIT:
|
||||
case PERF_RECORD_FORK:
|
||||
case PERF_RECORD_MMAP:
|
||||
case PERF_RECORD_MMAP2:
|
||||
break;
|
||||
|
||||
case PERF_RECORD_SAMPLE:
|
||||
|
||||
@ -176,6 +176,24 @@ sysprof_sampler_perf_event_stream_cb (const SysprofPerfEvent *event,
|
||||
|
||||
break;
|
||||
|
||||
case PERF_RECORD_MMAP2:
|
||||
offset = strlen (event->mmap2.filename) + 1;
|
||||
realign (&offset, sizeof (guint64));
|
||||
offset += sizeof (GPid) + sizeof (GPid);
|
||||
memcpy (&time, event->mmap2.filename + offset, sizeof time);
|
||||
|
||||
sysprof_capture_writer_add_map (writer,
|
||||
time,
|
||||
cpu,
|
||||
event->mmap2.pid,
|
||||
event->mmap2.addr,
|
||||
event->mmap2.addr + event->mmap2.len,
|
||||
event->mmap2.pgoff,
|
||||
0,
|
||||
event->mmap2.filename);
|
||||
|
||||
break;
|
||||
|
||||
case PERF_RECORD_READ:
|
||||
break;
|
||||
|
||||
@ -213,6 +231,7 @@ sysprof_sampler_prepare_fiber (gpointer user_data)
|
||||
g_autoptr(GPtrArray) futures = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
struct perf_event_attr attr = {0};
|
||||
gboolean with_mmap2 = TRUE;
|
||||
guint n_cpu;
|
||||
|
||||
g_assert (prepare != NULL);
|
||||
@ -251,6 +270,7 @@ sysprof_sampler_prepare_fiber (gpointer user_data)
|
||||
futures = g_ptr_array_new_with_free_func (dex_unref);
|
||||
writer = _sysprof_recording_writer (prepare->recording);
|
||||
|
||||
try_again:
|
||||
attr.sample_type = PERF_SAMPLE_IP
|
||||
| PERF_SAMPLE_TID
|
||||
| PERF_SAMPLE_IDENTIFIER
|
||||
@ -258,7 +278,8 @@ sysprof_sampler_prepare_fiber (gpointer user_data)
|
||||
| PERF_SAMPLE_TIME;
|
||||
attr.wakeup_events = N_WAKEUP_EVENTS;
|
||||
attr.disabled = TRUE;
|
||||
attr.mmap = 1;
|
||||
attr.mmap = TRUE;
|
||||
attr.mmap2 = with_mmap2;
|
||||
attr.comm = 1;
|
||||
attr.task = 1;
|
||||
attr.exclude_idle = 1;
|
||||
@ -303,17 +324,29 @@ sysprof_sampler_prepare_fiber (gpointer user_data)
|
||||
if (dex_future_get_status (future) == DEX_FUTURE_STATUS_REJECTED)
|
||||
{
|
||||
g_autoptr(GError) future_error = NULL;
|
||||
|
||||
dex_future_get_value (future, &future_error);
|
||||
_sysprof_recording_diagnostic (prepare->recording,
|
||||
"Sampler",
|
||||
"Failed to load Perf event stream for CPU %d: %s",
|
||||
i, future_error->message);
|
||||
|
||||
if (!with_mmap2)
|
||||
_sysprof_recording_diagnostic (prepare->recording,
|
||||
"Sampler",
|
||||
"Failed to load Perf event stream for CPU %d: %s",
|
||||
i, future_error->message);
|
||||
failed++;
|
||||
}
|
||||
}
|
||||
|
||||
if (failed == futures->len)
|
||||
return dex_future_new_for_error (g_steal_pointer (&error));
|
||||
{
|
||||
if (with_mmap2)
|
||||
{
|
||||
with_mmap2 = FALSE;
|
||||
g_ptr_array_remove_range (futures, 0, futures->len);
|
||||
goto try_again;
|
||||
}
|
||||
|
||||
return dex_future_new_for_error (g_steal_pointer (&error));
|
||||
}
|
||||
}
|
||||
|
||||
/* Save each of the streams (currently corked), so that we can
|
||||
|
||||
Reference in New Issue
Block a user