mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2026-02-11 23:51:06 +00:00
Make StackStash store uint64_ts instead of pointers
This commit is contained in:
132
collector.c
132
collector.c
@ -341,71 +341,6 @@ time_diff (const GTimeVal *first,
|
|||||||
|
|
||||||
#define RESET_DEAD_PERIOD 250
|
#define RESET_DEAD_PERIOD 250
|
||||||
|
|
||||||
static void
|
|
||||||
add_trace_to_stash (const SysprofStackTrace *trace,
|
|
||||||
StackStash *stash)
|
|
||||||
{
|
|
||||||
Process *process = process_get_from_pid (trace->pid);
|
|
||||||
gulong *addrs;
|
|
||||||
int i;
|
|
||||||
int n_addresses;
|
|
||||||
int n_kernel_words;
|
|
||||||
int a;
|
|
||||||
gulong addrs_stack[2048];
|
|
||||||
int n_alloc;
|
|
||||||
|
|
||||||
n_addresses = trace->n_addresses;
|
|
||||||
n_kernel_words = trace->n_kernel_words;
|
|
||||||
|
|
||||||
n_alloc = n_addresses + n_kernel_words + 2;
|
|
||||||
if (n_alloc <= 2048)
|
|
||||||
addrs = addrs_stack;
|
|
||||||
else
|
|
||||||
addrs = g_new (gulong, n_alloc);
|
|
||||||
|
|
||||||
a = 0;
|
|
||||||
/* Add kernel addresses */
|
|
||||||
if (trace->n_kernel_words)
|
|
||||||
{
|
|
||||||
for (i = 0; i < trace->n_kernel_words; ++i)
|
|
||||||
{
|
|
||||||
gulong addr = (gulong)trace->kernel_stack[i];
|
|
||||||
|
|
||||||
if (process_is_kernel_address (addr))
|
|
||||||
addrs[a++] = addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add kernel marker */
|
|
||||||
addrs[a++] = 0x01;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add user addresses */
|
|
||||||
|
|
||||||
for (i = 0; i < n_addresses; ++i)
|
|
||||||
{
|
|
||||||
gulong addr = (gulong)trace->addresses[i];
|
|
||||||
|
|
||||||
process_ensure_map (process, trace->pid, addr);
|
|
||||||
addrs[a++] = addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add process */
|
|
||||||
addrs[a++] = (gulong)process;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (a != n_addresses)
|
|
||||||
g_print ("a: %d, n_addresses: %d, kernel words: %d\n trace->nad %d",
|
|
||||||
a, n_addresses, trace->n_kernel_words, trace->n_addresses);
|
|
||||||
|
|
||||||
g_assert (a == n_addresses);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
stack_stash_add_trace (stash, addrs, a, 1);
|
|
||||||
|
|
||||||
if (addrs != addrs_stack)
|
|
||||||
g_free (addrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
in_dead_period (Collector *collector)
|
in_dead_period (Collector *collector)
|
||||||
{
|
{
|
||||||
@ -455,17 +390,17 @@ process_sample (Collector *collector,
|
|||||||
Process *process = process_get_from_pid (sample->pid);
|
Process *process = process_get_from_pid (sample->pid);
|
||||||
gboolean first = collector->n_samples == 0;
|
gboolean first = collector->n_samples == 0;
|
||||||
uint64_t context = 0;
|
uint64_t context = 0;
|
||||||
gulong addrs_stack[2048];
|
uint64_t addrs_stack[2048];
|
||||||
gulong *addrs;
|
uint64_t *addrs;
|
||||||
|
uint64_t *a;
|
||||||
int n_alloc;
|
int n_alloc;
|
||||||
int i;
|
int i;
|
||||||
gulong *a;
|
|
||||||
|
|
||||||
n_alloc = sample->n_ips + 2;
|
n_alloc = sample->n_ips + 2;
|
||||||
if (n_alloc < 2048)
|
if (n_alloc < 2048)
|
||||||
addrs = addrs_stack;
|
addrs = addrs_stack;
|
||||||
else
|
else
|
||||||
addrs = g_new (gulong, n_alloc);
|
addrs = g_new (uint64_t, n_alloc);
|
||||||
|
|
||||||
a = addrs;
|
a = addrs;
|
||||||
for (i = 0; i < sample->n_ips; ++i)
|
for (i = 0; i < sample->n_ips; ++i)
|
||||||
@ -499,7 +434,7 @@ process_sample (Collector *collector,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*a++ = (gulong)process;
|
*a++ = POINTER_TO_U64 (process);
|
||||||
|
|
||||||
stack_stash_add_trace (collector->stash, addrs, a - addrs, 1);
|
stack_stash_add_trace (collector->stash, addrs, a - addrs, 1);
|
||||||
|
|
||||||
@ -634,7 +569,7 @@ unique_dup (GHashTable *unique_symbols, const char *sym)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
lookup_symbol (Process *process, gpointer address,
|
lookup_symbol (Process *process, uint64_t address,
|
||||||
GHashTable *unique_symbols,
|
GHashTable *unique_symbols,
|
||||||
gboolean kernel,
|
gboolean kernel,
|
||||||
gboolean first_addr)
|
gboolean first_addr)
|
||||||
@ -702,29 +637,43 @@ lookup_symbol (Process *process, gpointer address,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
resolve_symbols (GList *trace, gint size, gpointer data)
|
resolve_symbols (StackLink *trace, gint size, gpointer data)
|
||||||
{
|
{
|
||||||
static const char *const everything = "[Everything]";
|
static const char *const everything = "[Everything]";
|
||||||
GList *list;
|
|
||||||
ResolveInfo *info = data;
|
ResolveInfo *info = data;
|
||||||
Process *process = g_list_last (trace)->data;
|
|
||||||
GPtrArray *resolved_trace = g_ptr_array_new ();
|
|
||||||
char *cmdline;
|
|
||||||
gboolean in_kernel = FALSE;
|
gboolean in_kernel = FALSE;
|
||||||
gboolean first_addr = TRUE;
|
gboolean first_addr = TRUE;
|
||||||
|
uint64_t addr_stack[128];
|
||||||
|
uint64_t *resolved_trace;
|
||||||
|
StackLink *link;
|
||||||
|
Process *process;
|
||||||
|
char *cmdline;
|
||||||
|
int len;
|
||||||
|
|
||||||
for (list = trace; list && list->next; list = list->next)
|
len = 2;
|
||||||
|
|
||||||
|
for (link = trace; link && link->next; link = link->next)
|
||||||
{
|
{
|
||||||
if (list->data == GINT_TO_POINTER (0x01))
|
if (link->data == 0x01)
|
||||||
in_kernel = TRUE;
|
in_kernel = TRUE;
|
||||||
|
|
||||||
|
len++;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (list = trace; list && list->next; list = list->next)
|
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)
|
||||||
{
|
{
|
||||||
gpointer address = list->data;
|
uint64_t address = link->data;
|
||||||
char *symbol;
|
char *symbol;
|
||||||
|
|
||||||
if (address == GINT_TO_POINTER (0x01))
|
if (address == 0x01)
|
||||||
in_kernel = FALSE;
|
in_kernel = FALSE;
|
||||||
|
|
||||||
symbol = lookup_symbol (process, address, info->unique_symbols,
|
symbol = lookup_symbol (process, address, info->unique_symbols,
|
||||||
@ -732,11 +681,12 @@ resolve_symbols (GList *trace, gint size, gpointer data)
|
|||||||
first_addr = FALSE;
|
first_addr = FALSE;
|
||||||
|
|
||||||
if (symbol)
|
if (symbol)
|
||||||
g_ptr_array_add (resolved_trace, symbol);
|
resolved_trace[len++] = POINTER_TO_U64 (symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdline = g_hash_table_lookup (info->unique_cmdlines,
|
cmdline = g_hash_table_lookup (
|
||||||
(char *)process_get_cmdline (process));
|
info->unique_cmdlines, (char *)process_get_cmdline (process));
|
||||||
|
|
||||||
if (!cmdline)
|
if (!cmdline)
|
||||||
{
|
{
|
||||||
cmdline = g_strdup (process_get_cmdline (process));
|
cmdline = g_strdup (process_get_cmdline (process));
|
||||||
@ -744,16 +694,14 @@ resolve_symbols (GList *trace, gint size, gpointer data)
|
|||||||
g_hash_table_insert (info->unique_cmdlines, cmdline, cmdline);
|
g_hash_table_insert (info->unique_cmdlines, cmdline, cmdline);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_ptr_array_add (resolved_trace, cmdline);
|
resolved_trace[len++] = POINTER_TO_U64 (cmdline);
|
||||||
|
resolved_trace[len++] = POINTER_TO_U64 (
|
||||||
|
unique_dup (info->unique_symbols, everything));
|
||||||
|
|
||||||
g_ptr_array_add (resolved_trace,
|
stack_stash_add_trace (info->resolved_stash, resolved_trace, len, size);
|
||||||
unique_dup (info->unique_symbols, everything));
|
|
||||||
|
|
||||||
stack_stash_add_trace (info->resolved_stash,
|
if (resolved_trace != addr_stack)
|
||||||
(gulong *)resolved_trace->pdata,
|
g_free (resolved_trace);
|
||||||
resolved_trace->len, size);
|
|
||||||
|
|
||||||
g_ptr_array_free (resolved_trace, TRUE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Profile *
|
Profile *
|
||||||
|
|||||||
33
profile.c
33
profile.c
@ -83,7 +83,7 @@ serialize_call_tree (StackNode *node,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
sfile_begin_add_record (output, "node");
|
sfile_begin_add_record (output, "node");
|
||||||
sfile_add_pointer (output, "object", node->address);
|
sfile_add_pointer (output, "object", U64_TO_POINTER (node->data));
|
||||||
sfile_add_pointer (output, "siblings", node->siblings);
|
sfile_add_pointer (output, "siblings", node->siblings);
|
||||||
sfile_add_pointer (output, "children", node->children);
|
sfile_add_pointer (output, "children", node->children);
|
||||||
sfile_add_pointer (output, "parent", node->parent);
|
sfile_add_pointer (output, "parent", node->parent);
|
||||||
@ -196,7 +196,7 @@ profile_load (const char *filename, GError **err)
|
|||||||
|
|
||||||
sfile_begin_get_record (input, "node");
|
sfile_begin_get_record (input, "node");
|
||||||
|
|
||||||
sfile_get_pointer (input, "object", (gpointer *)&node->address);
|
sfile_get_pointer (input, "object", (gpointer *)&node->data);
|
||||||
sfile_get_pointer (input, "siblings", (gpointer *)&node->siblings);
|
sfile_get_pointer (input, "siblings", (gpointer *)&node->siblings);
|
||||||
sfile_get_pointer (input, "children", (gpointer *)&node->children);
|
sfile_get_pointer (input, "children", (gpointer *)&node->children);
|
||||||
sfile_get_pointer (input, "parent", (gpointer *)&node->parent);
|
sfile_get_pointer (input, "parent", (gpointer *)&node->parent);
|
||||||
@ -233,15 +233,19 @@ profile_new (StackStash *stash)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_trace_to_tree (GList *trace, gint size, gpointer data)
|
add_trace_to_tree (StackLink *trace, gint size, gpointer data)
|
||||||
{
|
{
|
||||||
GList *list;
|
StackLink *link;
|
||||||
ProfileDescendant *parent = NULL;
|
ProfileDescendant *parent = NULL;
|
||||||
ProfileDescendant **tree = data;
|
ProfileDescendant **tree = data;
|
||||||
|
|
||||||
for (list = g_list_last (trace); list != NULL; list = list->prev)
|
link = trace;
|
||||||
|
while (link->next)
|
||||||
|
link = link->next;
|
||||||
|
|
||||||
|
for (; link != NULL; link = link->prev)
|
||||||
{
|
{
|
||||||
gpointer address = list->data;
|
gpointer address = U64_TO_POINTER (link->data);
|
||||||
ProfileDescendant *prev = NULL;
|
ProfileDescendant *prev = NULL;
|
||||||
ProfileDescendant *match = NULL;
|
ProfileDescendant *match = NULL;
|
||||||
|
|
||||||
@ -348,19 +352,21 @@ profile_list_callers (Profile *profile,
|
|||||||
if (!node->parent)
|
if (!node->parent)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
caller = g_hash_table_lookup (callers_by_name, node->parent->address);
|
caller = g_hash_table_lookup (
|
||||||
|
callers_by_name, U64_TO_POINTER (node->parent->data));
|
||||||
|
|
||||||
if (!caller)
|
if (!caller)
|
||||||
{
|
{
|
||||||
caller = profile_caller_new ();
|
caller = profile_caller_new ();
|
||||||
caller->name = node->parent->address;
|
caller->name = U64_TO_POINTER (node->parent->data);
|
||||||
caller->total = 0;
|
caller->total = 0;
|
||||||
caller->self = 0;
|
caller->self = 0;
|
||||||
|
|
||||||
caller->next = result;
|
caller->next = result;
|
||||||
result = caller;
|
result = caller;
|
||||||
|
|
||||||
g_hash_table_insert (callers_by_name, node->parent->address, caller);
|
g_hash_table_insert (
|
||||||
|
callers_by_name, U64_TO_POINTER (node->parent->data), caller);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,15 +382,16 @@ profile_list_callers (Profile *profile,
|
|||||||
|
|
||||||
for (n = node; n && n->parent; n = n->parent)
|
for (n = node; n && n->parent; n = n->parent)
|
||||||
{
|
{
|
||||||
if (n->address == node->address &&
|
if (n->data == node->data &&
|
||||||
n->parent->address == node->parent->address)
|
n->parent->data == node->parent->data)
|
||||||
{
|
{
|
||||||
top_caller = n->parent;
|
top_caller = n->parent;
|
||||||
top_callee = n;
|
top_callee = n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
caller = g_hash_table_lookup (callers_by_name, node->parent->address);
|
caller = g_hash_table_lookup (
|
||||||
|
callers_by_name, U64_TO_POINTER (node->parent->data));
|
||||||
|
|
||||||
if (!g_hash_table_lookup (processed_callers, top_caller))
|
if (!g_hash_table_lookup (processed_callers, top_caller))
|
||||||
{
|
{
|
||||||
@ -564,7 +571,7 @@ build_object_list (StackNode *node, gpointer data)
|
|||||||
StackNode *n;
|
StackNode *n;
|
||||||
|
|
||||||
obj = g_new (ProfileObject, 1);
|
obj = g_new (ProfileObject, 1);
|
||||||
obj->name = node->address;
|
obj->name = U64_TO_POINTER (node->data);
|
||||||
|
|
||||||
obj->total = compute_total (node);
|
obj->total = compute_total (node);
|
||||||
obj->self = 0;
|
obj->self = 0;
|
||||||
|
|||||||
51
stackstash.c
51
stackstash.c
@ -42,8 +42,8 @@ decorate_node (StackNode *node,
|
|||||||
decorate_node (node->siblings, stash);
|
decorate_node (node->siblings, stash);
|
||||||
decorate_node (node->children, stash);
|
decorate_node (node->children, stash);
|
||||||
|
|
||||||
node->next = g_hash_table_lookup (stash->nodes_by_data, node->address);
|
node->next = g_hash_table_lookup (stash->nodes_by_data, &node->data);
|
||||||
g_hash_table_insert (stash->nodes_by_data, node->address, node);
|
g_hash_table_insert (stash->nodes_by_data, &node->data, node);
|
||||||
|
|
||||||
/* FIXME: This could be done more efficiently
|
/* FIXME: This could be done more efficiently
|
||||||
* by keeping track of the ancestors we have seen.
|
* by keeping track of the ancestors we have seen.
|
||||||
@ -51,7 +51,7 @@ decorate_node (StackNode *node,
|
|||||||
node->toplevel = TRUE;
|
node->toplevel = TRUE;
|
||||||
for (n = node->parent; n != NULL; n = n->parent)
|
for (n = node->parent; n != NULL; n = n->parent)
|
||||||
{
|
{
|
||||||
if (n->address == node->address)
|
if (n->data == node->data)
|
||||||
{
|
{
|
||||||
node->toplevel = FALSE;
|
node->toplevel = FALSE;
|
||||||
break;
|
break;
|
||||||
@ -59,13 +59,30 @@ decorate_node (StackNode *node,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
address_hash (gconstpointer key)
|
||||||
|
{
|
||||||
|
const uint64_t *addr = key;
|
||||||
|
|
||||||
|
return *addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
address_equal (gconstpointer key1, gconstpointer key2)
|
||||||
|
{
|
||||||
|
const uint64_t *addr1 = key1;
|
||||||
|
const uint64_t *addr2 = key2;
|
||||||
|
|
||||||
|
return *addr1 == *addr2;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
stack_stash_decorate (StackStash *stash)
|
stack_stash_decorate (StackStash *stash)
|
||||||
{
|
{
|
||||||
if (stash->nodes_by_data)
|
if (stash->nodes_by_data)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
stash->nodes_by_data = g_hash_table_new (g_direct_hash, g_direct_equal);
|
stash->nodes_by_data = g_hash_table_new (address_hash, address_equal);
|
||||||
|
|
||||||
decorate_node (stash->root, stash);
|
decorate_node (stash->root, stash);
|
||||||
}
|
}
|
||||||
@ -76,8 +93,9 @@ free_key (gpointer key,
|
|||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
GDestroyNotify destroy = data;
|
GDestroyNotify destroy = data;
|
||||||
|
uint64_t u64 = *(uint64_t *)key;
|
||||||
|
|
||||||
destroy (key);
|
destroy (U64_TO_POINTER (u64));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -92,6 +110,7 @@ stack_stash_undecorate (StackStash *stash)
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_hash_table_destroy (stash->nodes_by_data);
|
g_hash_table_destroy (stash->nodes_by_data);
|
||||||
|
stash->nodes_by_data = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,7 +150,7 @@ stack_node_new (StackStash *stash)
|
|||||||
|
|
||||||
node->siblings = NULL;
|
node->siblings = NULL;
|
||||||
node->children = NULL;
|
node->children = NULL;
|
||||||
node->address = NULL;
|
node->data = 0;
|
||||||
node->parent = NULL;
|
node->parent = NULL;
|
||||||
node->size = 0;
|
node->size = 0;
|
||||||
node->next = NULL;
|
node->next = NULL;
|
||||||
@ -182,7 +201,7 @@ stack_stash_free (StackStash *stash)
|
|||||||
|
|
||||||
void
|
void
|
||||||
stack_stash_add_trace (StackStash *stash,
|
stack_stash_add_trace (StackStash *stash,
|
||||||
gulong *addrs,
|
uint64_t *addrs,
|
||||||
int n_addrs,
|
int n_addrs,
|
||||||
int size)
|
int size)
|
||||||
{
|
{
|
||||||
@ -204,7 +223,7 @@ stack_stash_add_trace (StackStash *stash,
|
|||||||
prev = NULL;
|
prev = NULL;
|
||||||
for (match = *location; match; prev = match, match = match->siblings)
|
for (match = *location; match; prev = match, match = match->siblings)
|
||||||
{
|
{
|
||||||
if (match->address == (gpointer)addrs[i])
|
if (match->data == addrs[i])
|
||||||
{
|
{
|
||||||
if (prev)
|
if (prev)
|
||||||
{
|
{
|
||||||
@ -221,7 +240,7 @@ stack_stash_add_trace (StackStash *stash,
|
|||||||
if (!match)
|
if (!match)
|
||||||
{
|
{
|
||||||
match = stack_node_new (stash);
|
match = stack_node_new (stash);
|
||||||
match->address = (gpointer)addrs[i];
|
match->data = addrs[i];
|
||||||
match->siblings = *location;
|
match->siblings = *location;
|
||||||
match->parent = parent;
|
match->parent = parent;
|
||||||
*location = match;
|
*location = match;
|
||||||
@ -238,11 +257,11 @@ stack_stash_add_trace (StackStash *stash,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
do_callback (StackNode *node,
|
do_callback (StackNode *node,
|
||||||
GList *trace,
|
StackLink *trace,
|
||||||
StackFunction func,
|
StackFunction func,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
GList link;
|
StackLink link;
|
||||||
|
|
||||||
if (trace)
|
if (trace)
|
||||||
trace->prev = &link;
|
trace->prev = &link;
|
||||||
@ -252,7 +271,7 @@ do_callback (StackNode *node,
|
|||||||
|
|
||||||
while (node)
|
while (node)
|
||||||
{
|
{
|
||||||
link.data = node->address;
|
link.data = node->data;
|
||||||
|
|
||||||
if (node->size)
|
if (node->size)
|
||||||
func (&link, node->size, data);
|
func (&link, node->size, data);
|
||||||
@ -279,10 +298,10 @@ stack_node_foreach_trace (StackNode *node,
|
|||||||
StackFunction func,
|
StackFunction func,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
GList link;
|
StackLink link;
|
||||||
|
|
||||||
link.next = NULL;
|
link.next = NULL;
|
||||||
link.data = node->address;
|
link.data = node->data;
|
||||||
link.prev = NULL;
|
link.prev = NULL;
|
||||||
|
|
||||||
if (node->size)
|
if (node->size)
|
||||||
@ -310,9 +329,11 @@ StackNode *
|
|||||||
stack_stash_find_node (StackStash *stash,
|
stack_stash_find_node (StackStash *stash,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
|
uint64_t u64 = POINTER_TO_U64 (data);
|
||||||
|
|
||||||
g_return_val_if_fail (stash != NULL, NULL);
|
g_return_val_if_fail (stash != NULL, NULL);
|
||||||
|
|
||||||
return g_hash_table_lookup (get_nodes_by_data (stash), data);
|
return g_hash_table_lookup (get_nodes_by_data (stash), &u64);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|||||||
24
stackstash.h
24
stackstash.h
@ -21,13 +21,18 @@
|
|||||||
#define STACK_STASH_H
|
#define STACK_STASH_H
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef struct StackStash StackStash;
|
typedef struct StackStash StackStash;
|
||||||
typedef struct StackNode StackNode;
|
typedef struct StackNode StackNode;
|
||||||
|
typedef struct StackLink StackLink;
|
||||||
|
|
||||||
|
#define U64_TO_POINTER(u) ((void *)(intptr_t)u)
|
||||||
|
#define POINTER_TO_U64(p) ((uint64_t)(intptr_t)p)
|
||||||
|
|
||||||
struct StackNode
|
struct StackNode
|
||||||
{
|
{
|
||||||
gpointer address;
|
uint64_t data;
|
||||||
|
|
||||||
guint total : 32;
|
guint total : 32;
|
||||||
guint size : 31;
|
guint size : 31;
|
||||||
@ -40,18 +45,25 @@ struct StackNode
|
|||||||
StackNode * next;
|
StackNode * next;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (* StackFunction) (GList *trace,
|
struct StackLink
|
||||||
gint size,
|
{
|
||||||
gpointer data);
|
uint64_t data;
|
||||||
|
StackLink *next;
|
||||||
|
StackLink *prev;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void (* StackFunction) (StackLink *trace,
|
||||||
|
gint size,
|
||||||
|
gpointer data);
|
||||||
|
|
||||||
typedef void (* StackNodeFunc) (StackNode *node,
|
typedef void (* StackNodeFunc) (StackNode *node,
|
||||||
gpointer data);
|
gpointer data);
|
||||||
|
|
||||||
/* Stach */
|
/* Stach */
|
||||||
StackStash *stack_stash_new (GDestroyNotify destroy);
|
StackStash *stack_stash_new (GDestroyNotify destroy);
|
||||||
StackNode * stack_node_new (StackStash *stash);
|
StackNode * stack_node_new (StackStash *stash);
|
||||||
void stack_stash_add_trace (StackStash *stash,
|
void stack_stash_add_trace (StackStash *stash,
|
||||||
gulong *addrs,
|
uint64_t *addrs,
|
||||||
gint n_addrs,
|
gint n_addrs,
|
||||||
int size);
|
int size);
|
||||||
void stack_stash_foreach (StackStash *stash,
|
void stack_stash_foreach (StackStash *stash,
|
||||||
|
|||||||
Reference in New Issue
Block a user