mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2026-02-10 23:20:54 +00:00
Remove last bits of process.[ch]
This commit is contained in:
181
collector.c
181
collector.c
@ -32,7 +32,6 @@
|
||||
#include "collector.h"
|
||||
#include "module/sysprof-module.h"
|
||||
#include "watch.h"
|
||||
#include "process.h"
|
||||
#include "elfparser.h"
|
||||
#include "tracker.h"
|
||||
|
||||
@ -554,190 +553,10 @@ collector_get_n_samples (Collector *collector)
|
||||
return collector->n_samples;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
StackStash *resolved_stash;
|
||||
GHashTable *unique_symbols;
|
||||
GHashTable *unique_cmdlines;
|
||||
} ResolveInfo;
|
||||
|
||||
/* Note that 'unique_symbols' is a direct_hash table. Ie., we
|
||||
* rely on the address of symbol strings being different for different
|
||||
* symbols.
|
||||
*/
|
||||
static char *
|
||||
unique_dup (GHashTable *unique_symbols, const char *sym)
|
||||
{
|
||||
char *result;
|
||||
|
||||
result = g_hash_table_lookup (unique_symbols, sym);
|
||||
if (!result)
|
||||
{
|
||||
result = elf_demangle (sym);
|
||||
g_hash_table_insert (unique_symbols, (char *)sym, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static char *
|
||||
lookup_symbol (Process *process, uint64_t address,
|
||||
GHashTable *unique_symbols,
|
||||
gboolean kernel,
|
||||
gboolean first_addr)
|
||||
{
|
||||
const char *sym;
|
||||
|
||||
g_assert (process);
|
||||
|
||||
if (kernel)
|
||||
{
|
||||
gulong offset;
|
||||
sym = process_lookup_kernel_symbol ((gulong)address, &offset);
|
||||
|
||||
/* If offset is 0, it is a callback, not a return address.
|
||||
*
|
||||
* If "first_addr" is true, then the address is an
|
||||
* instruction pointer, not a return address, so it may
|
||||
* legitimately be at offset 0.
|
||||
*/
|
||||
if (offset == 0 && !first_addr)
|
||||
{
|
||||
#if 0
|
||||
g_print ("rejecting callback: %s (%p)\n", sym, address);
|
||||
#endif
|
||||
sym = NULL;
|
||||
}
|
||||
|
||||
/* If offset is greater than 4096, then what happened is most
|
||||
* likely that it is the address of something in the gap between the
|
||||
* kernel text and the text of the modules. Rather than assign
|
||||
* this to the last function of the kernel text, we remove it here.
|
||||
*
|
||||
* FIXME: what we really should do is find out where this split
|
||||
* is, and act accordingly. Actually, we should look at /proc/modules
|
||||
*/
|
||||
if (offset > 4096)
|
||||
{
|
||||
#if 0
|
||||
g_print ("offset\n");
|
||||
#endif
|
||||
sym = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gulong offset;
|
||||
|
||||
sym = process_lookup_symbol (process, (gulong)address, &offset);
|
||||
|
||||
if (offset == 0 && !first_addr)
|
||||
{
|
||||
#if 0
|
||||
sym = g_strdup_printf ("%s [callback]", sym);
|
||||
g_print ("rejecting %s since it looks like a callback\n",
|
||||
sym);
|
||||
sym = NULL;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (sym)
|
||||
return unique_dup (unique_symbols, sym);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
resolve_symbols (StackLink *trace, gint size, gpointer data)
|
||||
{
|
||||
static const char *const everything = "[Everything]";
|
||||
ResolveInfo *info = data;
|
||||
gboolean in_kernel = FALSE;
|
||||
gboolean first_addr = TRUE;
|
||||
uint64_t addr_stack[128];
|
||||
uint64_t *resolved_trace;
|
||||
StackLink *link;
|
||||
Process *process;
|
||||
char *cmdline;
|
||||
int len;
|
||||
|
||||
len = 2;
|
||||
|
||||
for (link = trace; link && link->next; link = link->next)
|
||||
{
|
||||
if (link->data == 0x01)
|
||||
in_kernel = TRUE;
|
||||
|
||||
len++;
|
||||
}
|
||||
|
||||
if (len > 128)
|
||||
resolved_trace = g_new (uint64_t, len);
|
||||
else
|
||||
resolved_trace = addr_stack;
|
||||
|
||||
process = U64_TO_POINTER (link->data);
|
||||
|
||||
len = 0;
|
||||
for (link = trace; link && link->next; link = link->next)
|
||||
{
|
||||
uint64_t address = link->data;
|
||||
char *symbol;
|
||||
|
||||
if (address == 0x01)
|
||||
in_kernel = FALSE;
|
||||
|
||||
symbol = lookup_symbol (process, address, info->unique_symbols,
|
||||
in_kernel, first_addr);
|
||||
first_addr = FALSE;
|
||||
|
||||
if (symbol)
|
||||
resolved_trace[len++] = POINTER_TO_U64 (symbol);
|
||||
}
|
||||
|
||||
cmdline = g_hash_table_lookup (
|
||||
info->unique_cmdlines, (char *)process_get_cmdline (process));
|
||||
|
||||
if (!cmdline)
|
||||
{
|
||||
cmdline = g_strdup (process_get_cmdline (process));
|
||||
|
||||
g_hash_table_insert (info->unique_cmdlines, cmdline, cmdline);
|
||||
}
|
||||
|
||||
resolved_trace[len++] = POINTER_TO_U64 (cmdline);
|
||||
resolved_trace[len++] = POINTER_TO_U64 (
|
||||
unique_dup (info->unique_symbols, everything));
|
||||
|
||||
stack_stash_add_trace (info->resolved_stash, resolved_trace, len, size);
|
||||
|
||||
if (resolved_trace != addr_stack)
|
||||
g_free (resolved_trace);
|
||||
}
|
||||
|
||||
Profile *
|
||||
collector_create_profile (Collector *collector)
|
||||
{
|
||||
return tracker_create_profile (collector->tracker);
|
||||
|
||||
ResolveInfo info;
|
||||
Profile *profile;
|
||||
|
||||
info.resolved_stash = stack_stash_new ((GDestroyNotify)g_free);
|
||||
info.unique_symbols = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||
info.unique_cmdlines = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
|
||||
stack_stash_foreach (collector->stash, resolve_symbols, &info);
|
||||
|
||||
g_hash_table_destroy (info.unique_symbols);
|
||||
g_hash_table_destroy (info.unique_cmdlines);
|
||||
|
||||
profile = profile_new (info.resolved_stash);
|
||||
|
||||
stack_stash_unref (info.resolved_stash);
|
||||
|
||||
return profile;
|
||||
}
|
||||
|
||||
GQuark
|
||||
|
||||
Reference in New Issue
Block a user