[sysprof] capture: add pid-root frame type
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [sysprof] capture: add pid-root frame type
- Date: Thu, 25 Feb 2021 02:40:58 +0000 (UTC)
commit 4758fb42ce97d4d0af34dfc9ee96e8de2fe564da
Author: Christian Hergert <chergert redhat com>
Date: Wed Feb 24 17:50:36 2021 -0800
capture: add pid-root frame type
While I'm not thrilled to add new frame types for every sort of thing, I
think having this will be relatively useful so we can improve decoding
operations.
This adds SysprofCapturePidRoot which lets us specify a root directory
on the host system for which is the real root (/) of the PID. This can
be useful when reconstructing overlays for containers and you need to
direct access to alternate roots.
The layer gives us some ability to try to deal with overlayfs, albeit at
a very rudimentary level. In most cases I anticipate we just deal with
the main root and ignore overlays until necessary.
src/libsysprof-capture/sysprof-capture-cursor.c | 4 ++
src/libsysprof-capture/sysprof-capture-reader.c | 51 ++++++++++++++++++++++
src/libsysprof-capture/sysprof-capture-reader.h | 2 +
src/libsysprof-capture/sysprof-capture-types.h | 13 +++++-
.../sysprof-capture-writer-cat.c | 18 +++++++-
src/libsysprof-capture/sysprof-capture-writer.c | 33 ++++++++++++++
src/libsysprof-capture/sysprof-capture-writer.h | 7 +++
src/tools/sysprof-dump.c | 12 +++++
8 files changed, 138 insertions(+), 2 deletions(-)
---
diff --git a/src/libsysprof-capture/sysprof-capture-cursor.c b/src/libsysprof-capture/sysprof-capture-cursor.c
index 6d4c83a..eab3aca 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 b07ad2d..5ba5273 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 0fdd8b3..1d7b72a 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 2f5b4b4..1fbcbec 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 a157ed7..0cb69df 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 8fa89d2..5a09b6a 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 8a65726..2432aee 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 2b3936a..4875b69 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);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]