libsysprof-capture: add file chunk frame type

This commit is contained in:
Christian Hergert
2019-05-27 15:18:44 -07:00
parent 1940e45bf4
commit 7650d6e7c6
9 changed files with 277 additions and 14 deletions

View File

@ -167,6 +167,10 @@ sysprof_capture_cursor_foreach (SysprofCaptureCursor *self,
delegate = READ_DELEGATE (sysprof_capture_reader_read_metadata);
break;
case SYSPROF_CAPTURE_FRAME_FILE_CHUNK:
delegate = READ_DELEGATE (sysprof_capture_reader_read_file);
break;
default:
if (!sysprof_capture_reader_skip (self->reader))
return;

View File

@ -232,6 +232,17 @@ sysprof_capture_reader_bswap_frame (SysprofCaptureReader *self,
}
}
static inline void
sysprof_capture_reader_bswap_file_chunk (SysprofCaptureReader *self,
SysprofCaptureFileChunk *file_chunk)
{
g_assert (self != NULL);
g_assert (file_chunk != NULL);
if (G_UNLIKELY (self->endian != G_BYTE_ORDER))
file_chunk->len = GUINT16_SWAP_LE_BE (file_chunk->len);
}
static inline void
sysprof_capture_reader_bswap_log (SysprofCaptureReader *self,
SysprofCaptureLog *log)
@ -1122,3 +1133,43 @@ sysprof_capture_reader_get_stat (SysprofCaptureReader *self,
return self->st_buf_set;
}
const SysprofCaptureFileChunk *
sysprof_capture_reader_read_file (SysprofCaptureReader *self)
{
SysprofCaptureFileChunk *file_chunk;
g_assert (self != NULL);
g_assert ((self->pos % SYSPROF_CAPTURE_ALIGN) == 0);
g_assert (self->pos <= self->bufsz);
if (!sysprof_capture_reader_ensure_space_for (self, sizeof *file_chunk))
return NULL;
file_chunk = (SysprofCaptureFileChunk *)(gpointer)&self->buf[self->pos];
sysprof_capture_reader_bswap_frame (self, &file_chunk->frame);
if (file_chunk->frame.type != SYSPROF_CAPTURE_FRAME_FILE_CHUNK)
return NULL;
if (file_chunk->frame.len < sizeof *file_chunk)
return NULL;
if (!sysprof_capture_reader_ensure_space_for (self, file_chunk->frame.len))
return NULL;
file_chunk = (SysprofCaptureFileChunk *)(gpointer)&self->buf[self->pos];
sysprof_capture_reader_bswap_file_chunk (self, file_chunk);
self->pos += file_chunk->frame.len;
if ((self->pos % SYSPROF_CAPTURE_ALIGN) != 0)
return NULL;
/* Ensure trailing \0 in .path */
file_chunk->path[sizeof file_chunk->path - 1] = 0;
return file_chunk;
}

View File

@ -76,9 +76,11 @@ const SysprofCaptureSample *sysprof_capture_reader_read_sample
SYSPROF_AVAILABLE_IN_ALL
GHashTable *sysprof_capture_reader_read_jitmap (SysprofCaptureReader *self);
SYSPROF_AVAILABLE_IN_ALL
const SysprofCaptureCounterDefine *sysprof_capture_reader_read_counter_define (SysprofCaptureReader *self);
const SysprofCaptureCounterDefine *sysprof_capture_reader_read_counter_define (SysprofCaptureReader *self);
SYSPROF_AVAILABLE_IN_ALL
const SysprofCaptureCounterSet *sysprof_capture_reader_read_counter_set (SysprofCaptureReader *self);
const SysprofCaptureCounterSet *sysprof_capture_reader_read_counter_set (SysprofCaptureReader *self);
SYSPROF_AVAILABLE_IN_ALL
const SysprofCaptureFileChunk *sysprof_capture_reader_read_file (SysprofCaptureReader *self);
SYSPROF_AVAILABLE_IN_ALL
gboolean sysprof_capture_reader_reset (SysprofCaptureReader *self);
SYSPROF_AVAILABLE_IN_ALL

View File

@ -79,18 +79,19 @@ typedef union
typedef enum
{
SYSPROF_CAPTURE_FRAME_TIMESTAMP = 1,
SYSPROF_CAPTURE_FRAME_SAMPLE = 2,
SYSPROF_CAPTURE_FRAME_MAP = 3,
SYSPROF_CAPTURE_FRAME_PROCESS = 4,
SYSPROF_CAPTURE_FRAME_FORK = 5,
SYSPROF_CAPTURE_FRAME_EXIT = 6,
SYSPROF_CAPTURE_FRAME_JITMAP = 7,
SYSPROF_CAPTURE_FRAME_CTRDEF = 8,
SYSPROF_CAPTURE_FRAME_CTRSET = 9,
SYSPROF_CAPTURE_FRAME_MARK = 10,
SYSPROF_CAPTURE_FRAME_METADATA = 11,
SYSPROF_CAPTURE_FRAME_LOG = 12,
SYSPROF_CAPTURE_FRAME_TIMESTAMP = 1,
SYSPROF_CAPTURE_FRAME_SAMPLE = 2,
SYSPROF_CAPTURE_FRAME_MAP = 3,
SYSPROF_CAPTURE_FRAME_PROCESS = 4,
SYSPROF_CAPTURE_FRAME_FORK = 5,
SYSPROF_CAPTURE_FRAME_EXIT = 6,
SYSPROF_CAPTURE_FRAME_JITMAP = 7,
SYSPROF_CAPTURE_FRAME_CTRDEF = 8,
SYSPROF_CAPTURE_FRAME_CTRSET = 9,
SYSPROF_CAPTURE_FRAME_MARK = 10,
SYSPROF_CAPTURE_FRAME_METADATA = 11,
SYSPROF_CAPTURE_FRAME_LOG = 12,
SYSPROF_CAPTURE_FRAME_FILE_CHUNK = 13,
} SysprofCaptureFrameType;
SYSPROF_ALIGNED_BEGIN(1)
@ -262,6 +263,18 @@ typedef struct
} SysprofCaptureLog
SYSPROF_ALIGNED_END(1);
SYSPROF_ALIGNED_BEGIN(1)
typedef struct
{
SysprofCaptureFrame frame;
guint32 is_last : 1;
guint32 padding1 : 15;
guint32 len : 16;
gchar path[256];
guint8 data[0];
} SysprofCaptureFileChunk
SYSPROF_ALIGNED_END(1);
G_STATIC_ASSERT (sizeof (SysprofCaptureFileHeader) == 256);
G_STATIC_ASSERT (sizeof (SysprofCaptureFrame) == 24);
G_STATIC_ASSERT (sizeof (SysprofCaptureMap) == 56);
@ -278,6 +291,7 @@ G_STATIC_ASSERT (sizeof (SysprofCaptureCounterSet) == 32);
G_STATIC_ASSERT (sizeof (SysprofCaptureMark) == 96);
G_STATIC_ASSERT (sizeof (SysprofCaptureMetadata) == 64);
G_STATIC_ASSERT (sizeof (SysprofCaptureLog) == 64);
G_STATIC_ASSERT (sizeof (SysprofCaptureFileChunk) == 284);
static inline gint
sysprof_capture_address_compare (SysprofCaptureAddress a,

View File

@ -151,6 +151,24 @@ sysprof_capture_writer_cat (SysprofCaptureWriter *self,
break;
}
case SYSPROF_CAPTURE_FRAME_FILE_CHUNK:
{
const SysprofCaptureFileChunk *frame;
if (!(frame = sysprof_capture_reader_read_file (reader)))
goto panic;
sysprof_capture_writer_add_file (self,
frame->frame.time,
frame->frame.cpu,
frame->frame.pid,
frame->path,
frame->is_last,
frame->data,
frame->len);
break;
}
case SYSPROF_CAPTURE_FRAME_LOG:
{
const SysprofCaptureLog *frame;

View File

@ -1349,3 +1349,75 @@ sysprof_capture_writer_add_log (SysprofCaptureWriter *self,
return TRUE;
}
gboolean
sysprof_capture_writer_add_file (SysprofCaptureWriter *self,
gint64 time,
gint cpu,
gint32 pid,
const gchar *path,
gboolean is_last,
const guint8 *data,
gsize data_len)
{
SysprofCaptureFileChunk *ev;
gsize len;
g_assert (self != NULL);
len = sizeof *ev + data_len;
ev = (SysprofCaptureFileChunk *)sysprof_capture_writer_allocate (self, &len);
if (!ev)
return FALSE;
sysprof_capture_writer_frame_init (&ev->frame,
len,
cpu,
pid,
time,
SYSPROF_CAPTURE_FRAME_FILE_CHUNK);
ev->padding1 = 0;
ev->is_last = !!is_last;
ev->len = data_len;
g_strlcpy (ev->path, path, sizeof ev->path);
memcpy (ev->data, data, data_len);
self->stat.frame_count[SYSPROF_CAPTURE_FRAME_FILE_CHUNK]++;
return TRUE;
}
gboolean
sysprof_capture_writer_add_file_fd (SysprofCaptureWriter *self,
gint64 time,
gint cpu,
gint32 pid,
const gchar *path,
gint fd)
{
guint8 data[(4096*4L) - sizeof(SysprofCaptureFileChunk)];
g_assert (self != NULL);
for (;;)
{
gboolean is_last;
gssize n_read;
again:
n_read = read (fd, data, sizeof data);
if (n_read < 0 && errno == EAGAIN)
goto again;
is_last = n_read == 0;
if (!sysprof_capture_writer_add_file (self, time, cpu, pid, path, is_last, data, n_read))
return FALSE;
if (is_last)
break;
}
return TRUE;
}

View File

@ -45,6 +45,22 @@ SYSPROF_AVAILABLE_IN_ALL
void sysprof_capture_writer_stat (SysprofCaptureWriter *self,
SysprofCaptureStat *stat);
SYSPROF_AVAILABLE_IN_ALL
gboolean sysprof_capture_writer_add_file (SysprofCaptureWriter *self,
gint64 time,
gint cpu,
gint32 pid,
const gchar *path,
gboolean is_last,
const guint8 *data,
gsize data_len);
SYSPROF_AVAILABLE_IN_ALL
gboolean sysprof_capture_writer_add_file_fd (SysprofCaptureWriter *self,
gint64 time,
gint cpu,
gint32 pid,
const gchar *path,
gint fd);
SYSPROF_AVAILABLE_IN_ALL
gboolean sysprof_capture_writer_add_map (SysprofCaptureWriter *self,
gint64 time,
gint cpu,