Files
sysprof/src/libsysprof/tests/test-symbolize.c
Christian Hergert dbb7833cbf libsysprof: join libsysprof-analyze and libsysprof-profile
This brings together the two libraries back into one now that the whole
design is pretty well sorted out. They depend on roughly the same libraries
anyway and it's way easier of the single library can both read and write
the capture files (along with bringing in libsysprof-capture symbols in
a single place).
2023-07-19 17:40:41 -07:00

174 lines
5.4 KiB
C

#include "config.h"
#include <sysprof.h>
#include "sysprof-document-private.h"
static GMainLoop *main_loop;
static gboolean silent;
static gboolean no_bundled;
static char **debug_dirs;
static char *kallsyms_path;
static const GOptionEntry entries[] = {
{ "no-bundled", 'b', 0, G_OPTION_ARG_NONE, &no_bundled, "Ignore symbols bundled in capture file" },
{ "silent", 's', 0, G_OPTION_ARG_NONE, &silent, "Do not print symbol information" },
{ "debug-dir", 'd', 0, G_OPTION_ARG_FILENAME_ARRAY, &debug_dirs, "Specify external debug directory, may be repeated" },
{ "kallsyms", 'k', 0, G_OPTION_ARG_FILENAME, &kallsyms_path, "Specify path to kallsyms for kernel symbolizing" },
{ 0 }
};
static void
load_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
SysprofDocumentLoader *loader = (SysprofDocumentLoader *)object;
g_autoptr(SysprofDocument) document = NULL;
g_autoptr(GListModel) traceables = NULL;
g_autoptr(GError) error = NULL;
g_autoptr(GString) str = NULL;
SysprofSymbol *symbols[128];
guint n_symbols;
guint n_items;
g_assert (SYSPROF_IS_DOCUMENT_LOADER (loader));
g_assert (G_IS_ASYNC_RESULT (result));
if (!(document = sysprof_document_loader_load_finish (loader, result, &error)))
g_error ("Failed to load document: %s", error->message);
traceables = sysprof_document_list_traceables (document);
n_items = g_list_model_get_n_items (traceables);
if (silent)
{
g_main_loop_quit (main_loop);
return;
}
str = g_string_new ("");
for (guint i = 0; i < n_items; i++)
{
g_autoptr(SysprofDocumentTraceable) traceable = g_list_model_get_item (traceables, i);
str->len = 0;
str->str[0] = 0;
g_assert (traceable != NULL);
g_assert (SYSPROF_IS_DOCUMENT_TRACEABLE (traceable));
n_symbols = sysprof_document_symbolize_traceable (document,
traceable,
symbols,
G_N_ELEMENTS (symbols),
NULL);
g_print ("%s depth=%u pid=%u\n",
G_OBJECT_TYPE_NAME (traceable),
n_symbols,
sysprof_document_frame_get_pid (SYSPROF_DOCUMENT_FRAME (traceable)));
for (guint j = 0; j < n_symbols; j++)
{
SysprofSymbol *symbol = symbols[j];
const char *name;
const char *path;
const char *nick;
if (symbol != NULL)
{
name = sysprof_symbol_get_name (symbol);
path = sysprof_symbol_get_binary_path (symbol);
nick = sysprof_symbol_get_binary_nick (symbol);
}
else
{
name = path = nick = NULL;
}
g_string_append_printf (str,
" %02d: 0x%"G_GINT64_MODIFIER"x:",
j,
sysprof_document_traceable_get_stack_address (traceable, j));
if (name)
g_string_append_printf (str, " %s", name);
if (path)
g_string_append_printf (str, " [%s]", path);
if (nick)
g_string_append_printf (str, " (%s)", nick);
g_string_append_c (str, '\n');
}
g_string_append (str, " ================\n");
write (STDOUT_FILENO, str->str, str->len);
}
g_print ("Document symbolized\n");
g_main_loop_quit (main_loop);
}
int
main (int argc,
char *argv[])
{
g_autoptr(SysprofDocumentLoader) loader = NULL;
g_autoptr(GOptionContext) context = NULL;
g_autoptr(GError) error = NULL;
main_loop = g_main_loop_new (NULL, FALSE);
context = g_option_context_new ("- test document symbolization");
g_option_context_add_main_entries (context, entries, NULL);
if (!g_option_context_parse (context, &argc, &argv, &error))
{
g_printerr ("%s\n", error->message);
return 1;
}
if (argc != 2 || !g_file_test (argv[1], G_FILE_TEST_EXISTS))
{
g_printerr ("usage: %s CAPTURE_FILE\n", argv[0]);
return 1;
}
loader = sysprof_document_loader_new (argv[1]);
if (TRUE)
{
g_autoptr(SysprofMultiSymbolizer) multi = sysprof_multi_symbolizer_new ();
SysprofSymbolizer *elf = sysprof_elf_symbolizer_new ();
g_autoptr(GFile) kallsyms_file = kallsyms_path ? g_file_new_for_path (kallsyms_path) : NULL;
GFileInputStream *kallsyms_stream = kallsyms_file ? g_file_read (kallsyms_file, NULL, NULL) : NULL;
if (debug_dirs)
sysprof_elf_symbolizer_set_external_debug_dirs (SYSPROF_ELF_SYMBOLIZER (elf),
(const char * const *)debug_dirs);
if (!no_bundled)
sysprof_multi_symbolizer_take (multi, sysprof_bundled_symbolizer_new ());
if (kallsyms_stream == NULL)
sysprof_multi_symbolizer_take (multi, sysprof_kallsyms_symbolizer_new ());
else
sysprof_multi_symbolizer_take (multi, sysprof_kallsyms_symbolizer_new_for_symbols (G_INPUT_STREAM (kallsyms_stream)));
sysprof_multi_symbolizer_take (multi, elf);
sysprof_multi_symbolizer_take (multi, sysprof_jitmap_symbolizer_new ());
sysprof_document_loader_set_symbolizer (loader, SYSPROF_SYMBOLIZER (multi));
}
sysprof_document_loader_load_async (loader, NULL, load_cb, NULL);
g_main_loop_run (main_loop);
return 0;
}