diff --git a/src/libsysprof-capture/sysprof-capture-cursor.c b/src/libsysprof-capture/sysprof-capture-cursor.c index 6d4c83a5..eab3acae 100644 --- a/src/libsysprof-capture/sysprof-capture-cursor.c +++ b/src/libsysprof-capture/sysprof-capture-cursor.c @@ -223,6 +223,10 @@ sysprof_capture_cursor_foreach (SysprofCaptureCursor *self, delegate = READ_DELEGATE (sysprof_capture_reader_read_allocation); break; + case SYSPROF_CAPTURE_FRAME_PID_ROOT: + delegate = READ_DELEGATE (sysprof_capture_reader_read_pid_root); + break; + default: if (!sysprof_capture_reader_skip (self->reader)) return; diff --git a/src/libsysprof-capture/sysprof-capture-reader.c b/src/libsysprof-capture/sysprof-capture-reader.c index b07ad2dc..5ba52730 100644 --- a/src/libsysprof-capture/sysprof-capture-reader.c +++ b/src/libsysprof-capture/sysprof-capture-reader.c @@ -353,6 +353,17 @@ sysprof_capture_reader_bswap_mark (SysprofCaptureReader *self, mark->duration = bswap_64 (mark->duration); } +static inline void +sysprof_capture_reader_bswap_pid_root (SysprofCaptureReader *self, + SysprofCapturePidRoot *pr) +{ + assert (self != NULL); + assert (pr != NULL); + + if (SYSPROF_UNLIKELY (self->endian != __BYTE_ORDER)) + pr->layer = bswap_32 (pr->layer); +} + static inline void sysprof_capture_reader_bswap_jitmap (SysprofCaptureReader *self, SysprofCaptureJitmap *jitmap) @@ -679,6 +690,46 @@ sysprof_capture_reader_read_mark (SysprofCaptureReader *self) return mark; } +const SysprofCapturePidRoot * +sysprof_capture_reader_read_pid_root (SysprofCaptureReader *self) +{ + SysprofCapturePidRoot *pr; + + assert (self != NULL); + assert ((self->pos % SYSPROF_CAPTURE_ALIGN) == 0); + assert (self->pos <= self->bufsz); + + if (!sysprof_capture_reader_ensure_space_for (self, sizeof *pr + 1)) + return NULL; + + pr = (SysprofCapturePidRoot *)(void *)&self->buf[self->pos]; + + sysprof_capture_reader_bswap_frame (self, &pr->frame); + + if (pr->frame.type != SYSPROF_CAPTURE_FRAME_PID_ROOT) + return NULL; + + if (pr->frame.len < (sizeof *pr + 1)) + return NULL; + + if (!sysprof_capture_reader_ensure_space_for (self, pr->frame.len)) + return NULL; + + pr = (SysprofCapturePidRoot *)(void *)&self->buf[self->pos]; + + sysprof_capture_reader_bswap_pid_root (self, pr); + + self->pos += pr->frame.len; + + if ((self->pos % SYSPROF_CAPTURE_ALIGN) != 0) + return NULL; + + /* Ensure trailing \0 in name and message */ + ((char *)pr)[pr->frame.len-1] = 0; + + return pr; +} + const SysprofCaptureMetadata * sysprof_capture_reader_read_metadata (SysprofCaptureReader *self) { diff --git a/src/libsysprof-capture/sysprof-capture-reader.h b/src/libsysprof-capture/sysprof-capture-reader.h index 0fdd8b37..1d7b72a2 100644 --- a/src/libsysprof-capture/sysprof-capture-reader.h +++ b/src/libsysprof-capture/sysprof-capture-reader.h @@ -120,6 +120,8 @@ SYSPROF_AVAILABLE_IN_ALL const SysprofCaptureFileChunk *sysprof_capture_reader_read_file (SysprofCaptureReader *self); SYSPROF_AVAILABLE_IN_3_36 const SysprofCaptureAllocation *sysprof_capture_reader_read_allocation (SysprofCaptureReader *self); +SYSPROF_AVAILABLE_IN_3_40 +const SysprofCapturePidRoot *sysprof_capture_reader_read_pid_root (SysprofCaptureReader *self); SYSPROF_AVAILABLE_IN_ALL bool sysprof_capture_reader_reset (SysprofCaptureReader *self); SYSPROF_AVAILABLE_IN_ALL diff --git a/src/libsysprof-capture/sysprof-capture-types.h b/src/libsysprof-capture/sysprof-capture-types.h index 2f5b4b46..1fbcbec1 100644 --- a/src/libsysprof-capture/sysprof-capture-types.h +++ b/src/libsysprof-capture/sysprof-capture-types.h @@ -139,10 +139,11 @@ typedef enum SYSPROF_CAPTURE_FRAME_LOG = 12, SYSPROF_CAPTURE_FRAME_FILE_CHUNK = 13, SYSPROF_CAPTURE_FRAME_ALLOCATION = 14, + SYSPROF_CAPTURE_FRAME_PID_ROOT = 15, } SysprofCaptureFrameType; /* Not part of ABI */ -#define SYSPROF_CAPTURE_FRAME_LAST 15 +#define SYSPROF_CAPTURE_FRAME_LAST 16 SYSPROF_ALIGNED_BEGIN(1) typedef struct @@ -172,6 +173,15 @@ typedef struct } SysprofCaptureFrame SYSPROF_ALIGNED_END(1); +SYSPROF_ALIGNED_BEGIN(1) +typedef struct +{ + SysprofCaptureFrame frame; + uint32_t layer; + char path[0]; +} SysprofCapturePidRoot +SYSPROF_ALIGNED_END(1); + SYSPROF_ALIGNED_BEGIN(1) typedef struct { @@ -356,6 +366,7 @@ SYSPROF_STATIC_ASSERT (sizeof (SysprofCaptureMetadata) == 64, "SysprofCaptureMet SYSPROF_STATIC_ASSERT (sizeof (SysprofCaptureLog) == 64, "SysprofCaptureLog changed size"); SYSPROF_STATIC_ASSERT (sizeof (SysprofCaptureFileChunk) == 284, "SysprofCaptureFileChunk changed size"); SYSPROF_STATIC_ASSERT (sizeof (SysprofCaptureAllocation) == 48, "SysprofCaptureAllocation changed size"); +SYSPROF_STATIC_ASSERT (sizeof (SysprofCapturePidRoot) == 28, "SysprofCapturePidRoot changed size"); SYSPROF_STATIC_ASSERT ((offsetof (SysprofCaptureAllocation, addrs) % SYSPROF_CAPTURE_ALIGN) == 0, "SysprofCaptureAllocation.addrs is not aligned"); SYSPROF_STATIC_ASSERT ((offsetof (SysprofCaptureSample, addrs) % SYSPROF_CAPTURE_ALIGN) == 0, "SysprofCaptureSample.addrs is not aligned"); diff --git a/src/libsysprof-capture/sysprof-capture-writer-cat.c b/src/libsysprof-capture/sysprof-capture-writer-cat.c index a157ed73..0cb69df5 100644 --- a/src/libsysprof-capture/sysprof-capture-writer-cat.c +++ b/src/libsysprof-capture/sysprof-capture-writer-cat.c @@ -108,7 +108,7 @@ compare_by_src (const void *a, return -1; else if (itema->src > itemb->src) return 1; - else + else return 0; } @@ -532,6 +532,22 @@ sysprof_capture_writer_cat (SysprofCaptureWriter *self, break; } + case SYSPROF_CAPTURE_FRAME_PID_ROOT: + { + const SysprofCapturePidRoot *frame; + + if (!(frame = sysprof_capture_reader_read_pid_root (reader))) + goto panic; + + sysprof_capture_writer_add_pid_root (self, + frame->frame.time, + frame->frame.cpu, + frame->frame.pid, + frame->path, + frame->layer); + break; + } + default: /* Silently drop, which is better than looping. We could potentially * copy this over using the raw bytes at some point. diff --git a/src/libsysprof-capture/sysprof-capture-writer.c b/src/libsysprof-capture/sysprof-capture-writer.c index 8fa89d2a..5a09b6a9 100644 --- a/src/libsysprof-capture/sysprof-capture-writer.c +++ b/src/libsysprof-capture/sysprof-capture-writer.c @@ -827,6 +827,39 @@ sysprof_capture_writer_add_fork (SysprofCaptureWriter *self, return true; } +bool +sysprof_capture_writer_add_pid_root (SysprofCaptureWriter *self, + int64_t time, + int cpu, + int32_t pid, + const char *path, + uint32_t layer) +{ + SysprofCapturePidRoot *ev; + size_t strl = strlen (path); + size_t len = sizeof *ev + strl + 1; + + assert (self != NULL); + + ev = (SysprofCapturePidRoot *)sysprof_capture_writer_allocate (self, &len); + if (!ev) + return false; + + sysprof_capture_writer_frame_init (&ev->frame, + len, + cpu, + pid, + time, + SYSPROF_CAPTURE_FRAME_PID_ROOT); + ev->layer = layer; + memcpy (ev->path, path, strl); + ev->path[strl] = 0; + + self->stat.frame_count[SYSPROF_CAPTURE_FRAME_PID_ROOT]++; + + return true; +} + bool sysprof_capture_writer_add_exit (SysprofCaptureWriter *self, int64_t time, diff --git a/src/libsysprof-capture/sysprof-capture-writer.h b/src/libsysprof-capture/sysprof-capture-writer.h index 8a65726e..2432aee2 100644 --- a/src/libsysprof-capture/sysprof-capture-writer.h +++ b/src/libsysprof-capture/sysprof-capture-writer.h @@ -201,6 +201,13 @@ bool sysprof_capture_writer_add_allocation_copy (Sy int64_t alloc_size, const SysprofCaptureAddress *addrs, unsigned int n_addrs); +SYSPROF_AVAILABLE_IN_3_40 +bool sysprof_capture_writer_add_pid_root (SysprofCaptureWriter *self, + int64_t time, + int cpu, + int32_t pid, + const char *path, + uint32_t layer); SYSPROF_AVAILABLE_IN_ALL bool sysprof_capture_writer_flush (SysprofCaptureWriter *self); SYSPROF_AVAILABLE_IN_ALL diff --git a/src/tools/sysprof-dump.c b/src/tools/sysprof-dump.c index 2b3936a7..4875b697 100644 --- a/src/tools/sysprof-dump.c +++ b/src/tools/sysprof-dump.c @@ -115,6 +115,18 @@ main (gint argc, break; } + case SYSPROF_CAPTURE_FRAME_PID_ROOT: + { + const SysprofCapturePidRoot *pr = sysprof_capture_reader_read_pid_root (reader); + + if (pr == NULL) + return EXIT_FAILURE; + + g_print ("PID ROOT: pid=%d layer=%u path=%s\n", pr->frame.pid, pr->layer, pr->path); + + break; + } + case SYSPROF_CAPTURE_FRAME_JITMAP: { const SysprofCaptureJitmap *jitmap = sysprof_capture_reader_read_jitmap (reader);