mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2025-12-31 20:36:25 +00:00
This is useful when opening an older capture which will not have embedded the kallsyms content into the capture.
173 lines
5.3 KiB
C
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;
|
|
}
|