mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2025-12-31 20:36:25 +00:00
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.
This commit is contained in:
@ -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;
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
Reference in New Issue
Block a user