libsysprof-capture: add support for DBusMessage frames

These are still captive to the max size of a SysprofCaptureFrame, but
most messages fit into that.
This commit is contained in:
Christian Hergert
2023-07-27 12:21:42 -07:00
parent 50c203efe2
commit f46d690a28
7 changed files with 149 additions and 1 deletions

View File

@ -219,6 +219,10 @@ sysprof_capture_cursor_foreach (SysprofCaptureCursor *self,
delegate = READ_DELEGATE (sysprof_capture_reader_read_metadata);
break;
case SYSPROF_CAPTURE_FRAME_DBUS_MESSAGE:
delegate = READ_DELEGATE (sysprof_capture_reader_read_dbus_message);
break;
case SYSPROF_CAPTURE_FRAME_FILE_CHUNK:
delegate = READ_DELEGATE (sysprof_capture_reader_read_file);
break;

View File

@ -782,6 +782,61 @@ sysprof_capture_reader_read_metadata (SysprofCaptureReader *self)
return metadata;
}
static inline void
sysprof_capture_reader_bswap_dbus_message (SysprofCaptureReader *self,
SysprofCaptureDBusMessage *dbus_message)
{
assert (self != NULL);
assert (dbus_message != NULL);
/* This only swaps the frame, not the endianness of the message data
* which is automatically handled by dbus libraries such as GDBus.
*/
if (SYSPROF_UNLIKELY (self->endian != __BYTE_ORDER))
{
dbus_message->flags = bswap_16 (dbus_message->flags);
dbus_message->message_len = bswap_16 (dbus_message->message_len);
}
}
const SysprofCaptureDBusMessage *
sysprof_capture_reader_read_dbus_message (SysprofCaptureReader *self)
{
SysprofCaptureDBusMessage *dbus_message;
assert (self != NULL);
assert ((self->pos % SYSPROF_CAPTURE_ALIGN) == 0);
assert (self->pos <= self->bufsz);
if (!sysprof_capture_reader_ensure_space_for (self, sizeof *dbus_message))
return NULL;
dbus_message = (SysprofCaptureDBusMessage *)(void *)&self->buf[self->pos];
sysprof_capture_reader_bswap_frame (self, &dbus_message->frame);
if (dbus_message->frame.type != SYSPROF_CAPTURE_FRAME_DBUS_MESSAGE)
return NULL;
sysprof_capture_reader_bswap_dbus_message (self, dbus_message);
if (dbus_message->frame.len < (sizeof *dbus_message + dbus_message->message_len))
return NULL;
if (!sysprof_capture_reader_ensure_space_for (self, dbus_message->frame.len))
return NULL;
dbus_message = (SysprofCaptureDBusMessage *)(void *)&self->buf[self->pos];
self->pos += dbus_message->frame.len;
if ((self->pos % SYSPROF_CAPTURE_ALIGN) != 0)
return NULL;
return dbus_message;
}
const SysprofCaptureProcess *
sysprof_capture_reader_read_process (SysprofCaptureReader *self)
{

View File

@ -101,6 +101,8 @@ const SysprofCaptureMark *sysprof_capture_reader_read_mark (
SYSPROF_AVAILABLE_IN_ALL
const SysprofCaptureMetadata *sysprof_capture_reader_read_metadata (SysprofCaptureReader *self);
SYSPROF_AVAILABLE_IN_ALL
const SysprofCaptureDBusMessage *sysprof_capture_reader_read_dbus_message (SysprofCaptureReader *self);
SYSPROF_AVAILABLE_IN_ALL
const SysprofCaptureExit *sysprof_capture_reader_read_exit (SysprofCaptureReader *self);
SYSPROF_AVAILABLE_IN_ALL
const SysprofCaptureFork *sysprof_capture_reader_read_fork (SysprofCaptureReader *self);

View File

@ -141,10 +141,11 @@ typedef enum
SYSPROF_CAPTURE_FRAME_ALLOCATION = 14,
SYSPROF_CAPTURE_FRAME_OVERLAY = 15,
SYSPROF_CAPTURE_FRAME_TRACE = 16,
SYSPROF_CAPTURE_FRAME_DBUS_MESSAGE = 17,
} SysprofCaptureFrameType;
/* Not part of ABI */
#define SYSPROF_CAPTURE_FRAME_LAST 17
#define SYSPROF_CAPTURE_FRAME_LAST 18
SYSPROF_ALIGNED_BEGIN(1)
typedef struct
@ -364,6 +365,24 @@ typedef struct
} SysprofCaptureAllocation
SYSPROF_ALIGNED_END(1);
SYSPROF_ALIGNED_BEGIN(1)
typedef struct
{
SysprofCaptureFrame frame;
uint16_t bus_type : 2;
uint16_t flags : 14;
uint16_t message_len;
uint8_t message[0];
} SysprofCaptureDBusMessage
SYSPROF_ALIGNED_END(1);
#define SYSPROF_CAPTURE_DBUS_TYPE_SYSTEM 0
#define SYSPROF_CAPTURE_DBUS_TYPE_SESSION 1
#define SYSPROF_CAPTURE_DBUS_TYPE_A11Y 2
#define SYSPROF_CAPTURE_DBUS_TYPE_OTHER 3
#define SYSPROF_CAPTURE_DBUS_FLAGS_MESSAGE_TOO_LARGE (1<<0)
SYSPROF_STATIC_ASSERT (sizeof (SysprofCaptureFileHeader) == 256, "SysprofCaptureFileHeader changed size");
SYSPROF_STATIC_ASSERT (sizeof (SysprofCaptureFrame) == 24, "SysprofCaptureFrame changed size");
SYSPROF_STATIC_ASSERT (sizeof (SysprofCaptureMap) == 56, "SysprofCaptureMap changed size");
@ -384,6 +403,7 @@ SYSPROF_STATIC_ASSERT (sizeof (SysprofCaptureLog) == 64, "SysprofCaptureLog chan
SYSPROF_STATIC_ASSERT (sizeof (SysprofCaptureFileChunk) == 284, "SysprofCaptureFileChunk changed size");
SYSPROF_STATIC_ASSERT (sizeof (SysprofCaptureAllocation) == 48, "SysprofCaptureAllocation changed size");
SYSPROF_STATIC_ASSERT (sizeof (SysprofCaptureOverlay) == 32, "SysprofCaptureOverlay changed size");
SYSPROF_STATIC_ASSERT (sizeof (SysprofCaptureDBusMessage) == 28, "SysprofCaptureDBusMessage 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");

View File

@ -391,6 +391,23 @@ sysprof_capture_writer_cat (SysprofCaptureWriter *self,
break;
}
case SYSPROF_CAPTURE_FRAME_DBUS_MESSAGE:
{
const SysprofCaptureDBusMessage *frame;
if (!(frame = sysprof_capture_reader_read_dbus_message (reader)))
goto panic;
sysprof_capture_writer_add_dbus_message (self,
frame->frame.time,
frame->frame.cpu,
frame->frame.pid,
frame->flags,
frame->message,
frame->message_len);
break;
}
case SYSPROF_CAPTURE_FRAME_SAMPLE:
{
const SysprofCaptureSample *frame;

View File

@ -767,6 +767,48 @@ sysprof_capture_writer_add_metadata (SysprofCaptureWriter *self,
return true;
}
bool
sysprof_capture_writer_add_dbus_message (SysprofCaptureWriter *self,
int64_t time,
int cpu,
int32_t pid,
uint32_t flags,
const uint8_t *message_data,
size_t message_len)
{
SysprofCaptureDBusMessage *ev;
size_t len;
assert (self != NULL);
assert (message_data != NULL || message_len == 0);
if (message_len > (1<<16) - sizeof *ev - 16)
{
flags |= SYSPROF_CAPTURE_DBUS_FLAGS_MESSAGE_TOO_LARGE;
message_data = NULL;
message_len = 0;
}
len = sizeof *ev + message_len;
ev = (SysprofCaptureDBusMessage *)sysprof_capture_writer_allocate (self, &len);
if (!ev)
return false;
sysprof_capture_writer_frame_init (&ev->frame,
len,
cpu,
pid,
time,
SYSPROF_CAPTURE_FRAME_DBUS_MESSAGE);
ev->flags = flags;
ev->message_len = message_len;
memcpy (ev->message, message_data, message_len);
return true;
}
SysprofCaptureAddress
sysprof_capture_writer_add_jitmap (SysprofCaptureWriter *self,
const char *name)

View File

@ -230,6 +230,14 @@ bool sysprof_capture_writer_add_overlay (Sy
const char *src,
const char *dst);
SYSPROF_AVAILABLE_IN_ALL
bool sysprof_capture_writer_add_dbus_message (SysprofCaptureWriter *self,
int64_t time,
int cpu,
int32_t pid,
uint32_t flags,
const uint8_t *message_data,
size_t message_len);
SYSPROF_AVAILABLE_IN_ALL
bool sysprof_capture_writer_flush (SysprofCaptureWriter *self);
SYSPROF_AVAILABLE_IN_ALL
bool sysprof_capture_writer_save_as (SysprofCaptureWriter *self,