diff --git a/src/tools/sysprof-cat.c b/src/tools/sysprof-cat.c index b9c5ae90..b12890f9 100644 --- a/src/tools/sysprof-cat.c +++ b/src/tools/sysprof-cat.c @@ -27,80 +27,6 @@ #include #include -typedef struct -{ - guint64 src; - guint64 dst; -} TranslateItem; - -enum { - TRANSLATE_ADDR, - TRANSLATE_CTR, - N_TRANSLATE -}; - -static GArray *translate_table[N_TRANSLATE]; - -static void -translate_table_clear (guint table) -{ - g_clear_pointer (&translate_table[table], g_array_unref); -} - -static gint -compare_by_src (gconstpointer a, - gconstpointer b) -{ - const TranslateItem *itema = a; - const TranslateItem *itemb = a; - - if (itema->src < itemb->src) - return -1; - else if (itema->src > itemb->src) - return 1; - else - return 0; -} - -static void -translate_table_sort (guint table) -{ - if (translate_table[table]) - g_array_sort (translate_table[table], compare_by_src); -} - -static void -translate_table_add (guint table, - guint64 src, - guint64 dst) -{ - TranslateItem item = { src, dst }; - - if (translate_table[table] == NULL) - translate_table[table] = g_array_new (FALSE, FALSE, sizeof (TranslateItem)); - - g_array_append_val (translate_table[table], item); -} - -static guint64 -translate_table_translate (guint table, - guint64 src) -{ - const TranslateItem *item; - TranslateItem key = { src, 0 }; - - if (!translate_table[table]) - return src; - - item = bsearch (&key, - translate_table[table]->data, - translate_table[table]->len, - sizeof (TranslateItem), - compare_by_src); - - return item != NULL ? item->dst : src; -} - gint main (gint argc, gchar *argv[]) @@ -108,8 +34,6 @@ main (gint argc, g_autoptr(SysprofCaptureWriter) writer = NULL; g_autofree gchar *contents = NULL; g_autofree gchar *tmpname = NULL; - gint64 first_start_time = G_MAXINT64; - gint64 end_time = -1; gsize len; gint fd; @@ -141,308 +65,28 @@ main (gint argc, for (guint i = 1; i < argc; i++) { + g_autoptr(SysprofCaptureReader) reader = NULL; g_autoptr(GError) error = NULL; - g_autoptr(SysprofCaptureReader) reader = sysprof_capture_reader_new (argv[i], &error); - SysprofCaptureFrameType type; - gint64 start_time; - if (reader == NULL) + if (!(reader = sysprof_capture_reader_new (argv[i], &error))) { g_printerr ("Failed to create reader for \"%s\": %s\n", argv[i], error->message); return EXIT_FAILURE; } - translate_table_clear (TRANSLATE_CTR); - translate_table_clear (TRANSLATE_ADDR); - - start_time = sysprof_capture_reader_get_start_time (reader); - - if (start_time < first_start_time) - first_start_time = start_time; - - while (sysprof_capture_reader_peek_type (reader, &type)) + if (!sysprof_capture_writer_cat (writer, reader, &error)) { - SysprofCaptureFrame fr; - - if (sysprof_capture_reader_peek_frame (reader, &fr)) - { - if (fr.time > end_time) - end_time = fr.time; - } - - switch (type) - { - case SYSPROF_CAPTURE_FRAME_TIMESTAMP: - { - const SysprofCaptureTimestamp *frame; - - if (!(frame = sysprof_capture_reader_read_timestamp (reader))) - goto panic; - - sysprof_capture_writer_add_timestamp (writer, - frame->frame.time, - frame->frame.cpu, - frame->frame.pid); - break; - } - - case SYSPROF_CAPTURE_FRAME_MAP: - { - const SysprofCaptureMap *frame; - - if (!(frame = sysprof_capture_reader_read_map (reader))) - goto panic; - - sysprof_capture_writer_add_map (writer, - frame->frame.time, - frame->frame.cpu, - frame->frame.pid, - frame->start, - frame->end, - frame->offset, - frame->inode, - frame->filename); - break; - } - - case SYSPROF_CAPTURE_FRAME_MARK: - { - const SysprofCaptureMark *frame; - - if (!(frame = sysprof_capture_reader_read_mark (reader))) - goto panic; - - sysprof_capture_writer_add_mark (writer, - frame->frame.time, - frame->frame.cpu, - frame->frame.pid, - frame->duration, - frame->group, - frame->name, - frame->message); - - if (frame->frame.time + frame->duration > end_time) - end_time = frame->frame.time + frame->duration; - - break; - } - - case SYSPROF_CAPTURE_FRAME_PROCESS: - { - const SysprofCaptureProcess *frame; - - if (!(frame = sysprof_capture_reader_read_process (reader))) - goto panic; - - sysprof_capture_writer_add_process (writer, - frame->frame.time, - frame->frame.cpu, - frame->frame.pid, - frame->cmdline); - break; - } - - case SYSPROF_CAPTURE_FRAME_FORK: - { - const SysprofCaptureFork *frame; - - if (!(frame = sysprof_capture_reader_read_fork (reader))) - goto panic; - - sysprof_capture_writer_add_fork (writer, - frame->frame.time, - frame->frame.cpu, - frame->frame.pid, - frame->child_pid); - break; - } - - case SYSPROF_CAPTURE_FRAME_EXIT: - { - const SysprofCaptureExit *frame; - - if (!(frame = sysprof_capture_reader_read_exit (reader))) - goto panic; - - sysprof_capture_writer_add_exit (writer, - frame->frame.time, - frame->frame.cpu, - frame->frame.pid); - break; - } - - case SYSPROF_CAPTURE_FRAME_METADATA: - { - const SysprofCaptureMetadata *frame; - - if (!(frame = sysprof_capture_reader_read_metadata (reader))) - goto panic; - - sysprof_capture_writer_add_metadata (writer, - frame->frame.time, - frame->frame.cpu, - frame->frame.pid, - frame->id, - frame->metadata, - frame->frame.len - G_STRUCT_OFFSET (SysprofCaptureMetadata, metadata)); - break; - } - - case SYSPROF_CAPTURE_FRAME_JITMAP: - { - GHashTable *jitmap; - GHashTableIter iter; - const gchar *name; - guint64 addr; - - if (!(jitmap = sysprof_capture_reader_read_jitmap (reader))) - goto panic; - - g_hash_table_iter_init (&iter, jitmap); - while (g_hash_table_iter_next (&iter, (gpointer *)&addr, (gpointer *)&name)) - { - guint64 replace = sysprof_capture_writer_add_jitmap (writer, name); - /* We need to keep a table of replacement addresses so that - * we can translate the samples into the destination address - * space that we synthesized for the address identifier. - */ - translate_table_add (TRANSLATE_ADDR, addr, replace); - } - - translate_table_sort (TRANSLATE_ADDR); - - g_hash_table_unref (jitmap); - - break; - } - - case SYSPROF_CAPTURE_FRAME_SAMPLE: - { - const SysprofCaptureSample *frame; - - if (!(frame = sysprof_capture_reader_read_sample (reader))) - goto panic; - - { - SysprofCaptureAddress addrs[frame->n_addrs]; - - for (guint z = 0; z < frame->n_addrs; z++) - addrs[z] = translate_table_translate (TRANSLATE_ADDR, frame->addrs[z]); - - sysprof_capture_writer_add_sample (writer, - frame->frame.time, - frame->frame.cpu, - frame->frame.pid, - frame->tid, - addrs, - frame->n_addrs); - } - - break; - } - - case SYSPROF_CAPTURE_FRAME_CTRDEF: - { - const SysprofCaptureCounterDefine *frame; - - if (!(frame = sysprof_capture_reader_read_counter_define (reader))) - goto panic; - - { - g_autoptr(GArray) counter = g_array_new (FALSE, FALSE, sizeof (SysprofCaptureCounter)); - - for (guint z = 0; z < frame->n_counters; z++) - { - SysprofCaptureCounter c = frame->counters[z]; - guint src = c.id; - - c.id = sysprof_capture_writer_request_counter (writer, 1); - - if (c.id != src) - translate_table_add (TRANSLATE_CTR, src, c.id); - - g_array_append_val (counter, c); - } - - sysprof_capture_writer_define_counters (writer, - frame->frame.time, - frame->frame.cpu, - frame->frame.pid, - (gpointer)counter->data, - counter->len); - - translate_table_sort (TRANSLATE_CTR); - } - - break; - } - - case SYSPROF_CAPTURE_FRAME_CTRSET: - { - const SysprofCaptureCounterSet *frame; - - if (!(frame = sysprof_capture_reader_read_counter_set (reader))) - goto panic; - - { - g_autoptr(GArray) ids = g_array_new (FALSE, FALSE, sizeof (guint)); - g_autoptr(GArray) values = g_array_new (FALSE, FALSE, sizeof (SysprofCaptureCounterValue)); - - for (guint z = 0; z < frame->n_values; z++) - { - const SysprofCaptureCounterValues *v = &frame->values[z]; - - for (guint y = 0; y < G_N_ELEMENTS (v->ids); y++) - { - if (v->ids[y]) - { - guint dst = translate_table_translate (TRANSLATE_CTR, v->ids[y]); - SysprofCaptureCounterValue value = v->values[y]; - - g_array_append_val (ids, dst); - g_array_append_val (values, value); - } - } - } - - g_assert (ids->len == values->len); - - sysprof_capture_writer_set_counters (writer, - frame->frame.time, - frame->frame.cpu, - frame->frame.pid, - (const guint *)(gpointer)ids->data, - (const SysprofCaptureCounterValue *)(gpointer)values->data, - ids->len); - } - - break; - } - - default: - break; - } + g_printerr ("Failed to join \"%s\": %s\n", + argv[i], error->message); + return EXIT_FAILURE; } } - sysprof_capture_writer_flush (writer); - - /* do this after flushing as it uses pwrite() to replace data */ - _sysprof_capture_writer_set_time_range (writer, first_start_time, end_time); - if (g_file_get_contents (tmpname, &contents, &len, NULL)) write (STDOUT_FILENO, contents, len); g_unlink (tmpname); return EXIT_SUCCESS; - -panic: - g_printerr ("There was a failure to read the stream.\n"); - - if (tmpname) - g_unlink (tmpname); - - return EXIT_FAILURE; }