Files
sysprof/src/libsysprof-analyze/tests/test-symbolize.c
Christian Hergert 15acac7e2e libsysprof-analyze: allow specifying kallsyms path
This is useful when opening an older capture which will not have embedded
the kallsyms content into the capture.
2023-05-19 17:28:11 -07:00

173 lines
5.3 KiB
C

#include "config.h"
#include <sysprof-analyze.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));
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;
}