mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2025-12-31 20:36:25 +00:00
libsysprof-capture: add file chunk frame type
This commit is contained in:
@ -167,6 +167,10 @@ sysprof_capture_cursor_foreach (SysprofCaptureCursor *self,
|
|||||||
delegate = READ_DELEGATE (sysprof_capture_reader_read_metadata);
|
delegate = READ_DELEGATE (sysprof_capture_reader_read_metadata);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SYSPROF_CAPTURE_FRAME_FILE_CHUNK:
|
||||||
|
delegate = READ_DELEGATE (sysprof_capture_reader_read_file);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (!sysprof_capture_reader_skip (self->reader))
|
if (!sysprof_capture_reader_skip (self->reader))
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -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
|
static inline void
|
||||||
sysprof_capture_reader_bswap_log (SysprofCaptureReader *self,
|
sysprof_capture_reader_bswap_log (SysprofCaptureReader *self,
|
||||||
SysprofCaptureLog *log)
|
SysprofCaptureLog *log)
|
||||||
@ -1122,3 +1133,43 @@ sysprof_capture_reader_get_stat (SysprofCaptureReader *self,
|
|||||||
|
|
||||||
return self->st_buf_set;
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@ -76,9 +76,11 @@ const SysprofCaptureSample *sysprof_capture_reader_read_sample
|
|||||||
SYSPROF_AVAILABLE_IN_ALL
|
SYSPROF_AVAILABLE_IN_ALL
|
||||||
GHashTable *sysprof_capture_reader_read_jitmap (SysprofCaptureReader *self);
|
GHashTable *sysprof_capture_reader_read_jitmap (SysprofCaptureReader *self);
|
||||||
SYSPROF_AVAILABLE_IN_ALL
|
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
|
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
|
SYSPROF_AVAILABLE_IN_ALL
|
||||||
gboolean sysprof_capture_reader_reset (SysprofCaptureReader *self);
|
gboolean sysprof_capture_reader_reset (SysprofCaptureReader *self);
|
||||||
SYSPROF_AVAILABLE_IN_ALL
|
SYSPROF_AVAILABLE_IN_ALL
|
||||||
|
|||||||
@ -79,18 +79,19 @@ typedef union
|
|||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
SYSPROF_CAPTURE_FRAME_TIMESTAMP = 1,
|
SYSPROF_CAPTURE_FRAME_TIMESTAMP = 1,
|
||||||
SYSPROF_CAPTURE_FRAME_SAMPLE = 2,
|
SYSPROF_CAPTURE_FRAME_SAMPLE = 2,
|
||||||
SYSPROF_CAPTURE_FRAME_MAP = 3,
|
SYSPROF_CAPTURE_FRAME_MAP = 3,
|
||||||
SYSPROF_CAPTURE_FRAME_PROCESS = 4,
|
SYSPROF_CAPTURE_FRAME_PROCESS = 4,
|
||||||
SYSPROF_CAPTURE_FRAME_FORK = 5,
|
SYSPROF_CAPTURE_FRAME_FORK = 5,
|
||||||
SYSPROF_CAPTURE_FRAME_EXIT = 6,
|
SYSPROF_CAPTURE_FRAME_EXIT = 6,
|
||||||
SYSPROF_CAPTURE_FRAME_JITMAP = 7,
|
SYSPROF_CAPTURE_FRAME_JITMAP = 7,
|
||||||
SYSPROF_CAPTURE_FRAME_CTRDEF = 8,
|
SYSPROF_CAPTURE_FRAME_CTRDEF = 8,
|
||||||
SYSPROF_CAPTURE_FRAME_CTRSET = 9,
|
SYSPROF_CAPTURE_FRAME_CTRSET = 9,
|
||||||
SYSPROF_CAPTURE_FRAME_MARK = 10,
|
SYSPROF_CAPTURE_FRAME_MARK = 10,
|
||||||
SYSPROF_CAPTURE_FRAME_METADATA = 11,
|
SYSPROF_CAPTURE_FRAME_METADATA = 11,
|
||||||
SYSPROF_CAPTURE_FRAME_LOG = 12,
|
SYSPROF_CAPTURE_FRAME_LOG = 12,
|
||||||
|
SYSPROF_CAPTURE_FRAME_FILE_CHUNK = 13,
|
||||||
} SysprofCaptureFrameType;
|
} SysprofCaptureFrameType;
|
||||||
|
|
||||||
SYSPROF_ALIGNED_BEGIN(1)
|
SYSPROF_ALIGNED_BEGIN(1)
|
||||||
@ -262,6 +263,18 @@ typedef struct
|
|||||||
} SysprofCaptureLog
|
} SysprofCaptureLog
|
||||||
SYSPROF_ALIGNED_END(1);
|
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 (SysprofCaptureFileHeader) == 256);
|
||||||
G_STATIC_ASSERT (sizeof (SysprofCaptureFrame) == 24);
|
G_STATIC_ASSERT (sizeof (SysprofCaptureFrame) == 24);
|
||||||
G_STATIC_ASSERT (sizeof (SysprofCaptureMap) == 56);
|
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 (SysprofCaptureMark) == 96);
|
||||||
G_STATIC_ASSERT (sizeof (SysprofCaptureMetadata) == 64);
|
G_STATIC_ASSERT (sizeof (SysprofCaptureMetadata) == 64);
|
||||||
G_STATIC_ASSERT (sizeof (SysprofCaptureLog) == 64);
|
G_STATIC_ASSERT (sizeof (SysprofCaptureLog) == 64);
|
||||||
|
G_STATIC_ASSERT (sizeof (SysprofCaptureFileChunk) == 284);
|
||||||
|
|
||||||
static inline gint
|
static inline gint
|
||||||
sysprof_capture_address_compare (SysprofCaptureAddress a,
|
sysprof_capture_address_compare (SysprofCaptureAddress a,
|
||||||
|
|||||||
@ -151,6 +151,24 @@ sysprof_capture_writer_cat (SysprofCaptureWriter *self,
|
|||||||
break;
|
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:
|
case SYSPROF_CAPTURE_FRAME_LOG:
|
||||||
{
|
{
|
||||||
const SysprofCaptureLog *frame;
|
const SysprofCaptureLog *frame;
|
||||||
|
|||||||
@ -1349,3 +1349,75 @@ sysprof_capture_writer_add_log (SysprofCaptureWriter *self,
|
|||||||
|
|
||||||
return TRUE;
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@ -45,6 +45,22 @@ SYSPROF_AVAILABLE_IN_ALL
|
|||||||
void sysprof_capture_writer_stat (SysprofCaptureWriter *self,
|
void sysprof_capture_writer_stat (SysprofCaptureWriter *self,
|
||||||
SysprofCaptureStat *stat);
|
SysprofCaptureStat *stat);
|
||||||
SYSPROF_AVAILABLE_IN_ALL
|
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,
|
gboolean sysprof_capture_writer_add_map (SysprofCaptureWriter *self,
|
||||||
gint64 time,
|
gint64 time,
|
||||||
gint cpu,
|
gint cpu,
|
||||||
|
|||||||
@ -20,9 +20,12 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
#include <glib/gstdio.h>
|
#include <glib/gstdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sysprof-capture.h>
|
#include <sysprof-capture.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_reader_basic (void)
|
test_reader_basic (void)
|
||||||
@ -708,6 +711,73 @@ test_reader_writer_metadata (void)
|
|||||||
g_unlink ("metadata1.syscap");
|
g_unlink ("metadata1.syscap");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_reader_writer_file (void)
|
||||||
|
{
|
||||||
|
g_autofree gchar *data = NULL;
|
||||||
|
GByteArray *buf = g_byte_array_new ();
|
||||||
|
SysprofCaptureWriter *writer;
|
||||||
|
SysprofCaptureReader *reader;
|
||||||
|
SysprofCaptureFrameType type;
|
||||||
|
GError *error = NULL;
|
||||||
|
gssize len;
|
||||||
|
gsize data_len;
|
||||||
|
guint count = 0;
|
||||||
|
gint fd;
|
||||||
|
gint r;
|
||||||
|
|
||||||
|
writer = sysprof_capture_writer_new ("file1.syscap", 0);
|
||||||
|
fd = g_open ("/proc/kallsyms", O_RDONLY);
|
||||||
|
|
||||||
|
r = g_file_get_contents ("/proc/kallsyms", &data, &data_len, NULL);
|
||||||
|
g_assert_true (r);
|
||||||
|
|
||||||
|
len = lseek (fd, SEEK_END, 0);
|
||||||
|
g_assert_cmpint (len, >, 0);
|
||||||
|
|
||||||
|
lseek (fd, SEEK_SET, 0);
|
||||||
|
sysprof_capture_writer_add_file_fd (writer, SYSPROF_CAPTURE_CURRENT_TIME, -1, -1, "/proc/kallsyms", fd);
|
||||||
|
|
||||||
|
lseek (fd, SEEK_SET, 0);
|
||||||
|
sysprof_capture_writer_add_file_fd (writer, SYSPROF_CAPTURE_CURRENT_TIME, -1, -1, "/proc/kallsyms", fd);
|
||||||
|
|
||||||
|
close (fd);
|
||||||
|
|
||||||
|
g_clear_pointer (&writer, sysprof_capture_writer_unref);
|
||||||
|
|
||||||
|
reader = sysprof_capture_reader_new ("file1.syscap", &error);
|
||||||
|
g_assert_no_error (error);
|
||||||
|
g_assert (reader != NULL);
|
||||||
|
|
||||||
|
while (count < 2)
|
||||||
|
{
|
||||||
|
const SysprofCaptureFileChunk *file;
|
||||||
|
|
||||||
|
r = sysprof_capture_reader_peek_type (reader, &type);
|
||||||
|
g_assert_true (r);
|
||||||
|
g_assert_cmpint (type, ==, SYSPROF_CAPTURE_FRAME_FILE_CHUNK);
|
||||||
|
|
||||||
|
file = sysprof_capture_reader_read_file (reader);
|
||||||
|
g_assert_nonnull (file);
|
||||||
|
g_assert_cmpstr (file->path, ==, "/proc/kallsyms");
|
||||||
|
|
||||||
|
if (count == 0)
|
||||||
|
g_byte_array_append (buf, file->data, file->len);
|
||||||
|
|
||||||
|
count += file->is_last;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_assert_cmpint (0, ==, memcmp (data, buf->data, data_len));
|
||||||
|
|
||||||
|
r = sysprof_capture_reader_peek_type (reader, &type);
|
||||||
|
g_assert_cmpint (r, ==, FALSE);
|
||||||
|
|
||||||
|
g_clear_pointer (&reader, sysprof_capture_reader_unref);
|
||||||
|
g_clear_pointer (&buf, g_byte_array_unref);
|
||||||
|
|
||||||
|
g_unlink ("file1.syscap");
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc,
|
main (int argc,
|
||||||
char *argv[])
|
char *argv[])
|
||||||
@ -720,5 +790,6 @@ main (int argc,
|
|||||||
g_test_add_func ("/SysprofCapture/ReaderWriter/log", test_reader_writer_log);
|
g_test_add_func ("/SysprofCapture/ReaderWriter/log", test_reader_writer_log);
|
||||||
g_test_add_func ("/SysprofCapture/ReaderWriter/mark", test_reader_writer_mark);
|
g_test_add_func ("/SysprofCapture/ReaderWriter/mark", test_reader_writer_mark);
|
||||||
g_test_add_func ("/SysprofCapture/ReaderWriter/metadata", test_reader_writer_metadata);
|
g_test_add_func ("/SysprofCapture/ReaderWriter/metadata", test_reader_writer_metadata);
|
||||||
|
g_test_add_func ("/SysprofCapture/ReaderWriter/file", test_reader_writer_file);
|
||||||
return g_test_run ();
|
return g_test_run ();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -139,6 +139,21 @@ main (gint argc,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SYSPROF_CAPTURE_FRAME_FILE_CHUNK:
|
||||||
|
{
|
||||||
|
const SysprofCaptureFileChunk *file_chunk = sysprof_capture_reader_read_file (reader);
|
||||||
|
gdouble ptime = (file_chunk->frame.time - begin_time) / (gdouble)NSEC_PER_SEC;
|
||||||
|
|
||||||
|
g_print ("FILE_CHUNK: pid=%d time=%"G_GINT64_FORMAT" (%lf)\n"
|
||||||
|
" path = %s\n"
|
||||||
|
" is_last = %d\n"
|
||||||
|
" bytes = %d\n",
|
||||||
|
file_chunk->frame.pid, file_chunk->frame.time, ptime,
|
||||||
|
file_chunk->path, file_chunk->is_last, file_chunk->len);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case SYSPROF_CAPTURE_FRAME_MARK:
|
case SYSPROF_CAPTURE_FRAME_MARK:
|
||||||
{
|
{
|
||||||
const SysprofCaptureMark *mark = sysprof_capture_reader_read_mark (reader);
|
const SysprofCaptureMark *mark = sysprof_capture_reader_read_mark (reader);
|
||||||
|
|||||||
Reference in New Issue
Block a user