diff --git a/Makefile b/Makefile index e1593a9..5e99f9d 100644 --- a/Makefile +++ b/Makefile @@ -68,6 +68,7 @@ $(ATR_LIBS): clean: ${RM} $(BUILD_DIR)/*.o $(BUILD_DIR)/*.dep $(BIN) $(BUILD_DIR)/prepare.bld $(RESULT_DIR)/prepare.res $(BUILD_DIR)/version.h + @make clean -C ./framework @if [ -z "$$(ls -A $(BUILD_DIR) 2>&1)" ]; then ${RM} -r $(BUILD_DIR); fi @if [ -z "$$(ls -A $(RESULT_DIR) 2>&1)" ]; then ${RM} -r $(RESULT_DIR); fi diff --git a/framework/context.cpp b/framework/context.cpp index 3ae43e0..2a3a0e9 100644 --- a/framework/context.cpp +++ b/framework/context.cpp @@ -202,7 +202,7 @@ char* pst_strdup(const char* str) pst_assert(str); uint32_t len = strlen(str); - char* dst = (char*)allocator.alloc(len + 1); + char* dst = (char*)allocator.alloc(&allocator, len + 1); memcpy(dst, str, len); dst[len] = 0; diff --git a/framework/dwarf_call_site.cpp b/framework/dwarf_call_site.cpp index 0985cfe..0bef02b 100644 --- a/framework/dwarf_call_site.cpp +++ b/framework/dwarf_call_site.cpp @@ -6,11 +6,13 @@ */ #include +#include #include "dwarf_call_site.h" #include "dwarf_utils.h" #include "hash_multimap.h" #include "dwarf_utils.h" +#include "dwarf_function.h" // ----------------------------------------------------------------------------------- // pst_call_site_param @@ -203,7 +205,7 @@ void pst_call_site_fini(pst_call_site* site) // DW_TAG_GNU_call_site_parameter is defined under child DIE of DW_TAG_GNU_call_site and defines value of subroutine before calling it // relates to DW_OP_GNU_entry_value() handling in callee function to determine the value of an argument/variable of the callee // get DIE of return type -bool storage_handle_dwarf(pst_call_site_storage* storage, Dwarf_Die* result) +bool storage_handle_dwarf(pst_call_site_storage* storage, Dwarf_Die* result, pst_function* info) { Dwarf_Die origin; Dwarf_Attribute attr_mem; @@ -225,7 +227,7 @@ bool storage_handle_dwarf(pst_call_site_storage* storage, Dwarf_Die* result) if(attr) { pst_dwarf_expr expr; pst_dwarf_expr_init(&expr); - if(handle_location(storage->ctx, &attr_mem, expr, pc, this)) { + if(handle_location(storage->ctx, &attr_mem, &expr, info->pc, info)) { target = expr.value; pst_log(SEVERITY_DEBUG, "\tDW_AT_GNU_call_site_target: %#lX", target); } @@ -280,7 +282,7 @@ pst_call_site* storage_add_call_site(pst_call_site_storage* storage, uint64_t ta if(target) { hash_add(&storage->cs_to_target, &st->tgt_node, &target, sizeof(target)); } else if(origin) { - hash_add(&storage->cs_to_origin, &st->org_node, (char*)origin, strlen(origin)); + hash_add(&storage->cs_to_origin, &st->org_node, origin, strlen(origin)); } return st; diff --git a/framework/dwarf_call_site.h b/framework/dwarf_call_site.h index 450a494..25c9d7d 100644 --- a/framework/dwarf_call_site.h +++ b/framework/dwarf_call_site.h @@ -16,6 +16,12 @@ #include "dwarf_expression.h" #include "hash_multimap.h" +typedef struct pst_callee_info { + Dwarf_Addr target; + char* origin; + Dwarf_Addr pc; +} pst_callee_info; + // ----------------------------------------------------------------------------------- // DW_TAG_call_site_parameter @@ -66,7 +72,7 @@ void pst_call_site_init(pst_call_site* site, pst_context* context, uint64_t targ pst_call_site* pst_call_site_new(pst_context* context, uint64_t target, const char* origin); void pst_call_site_fini(pst_call_site* site); - +typedef struct __pst_function pst_function; // ----------------------------------------------------------------------------------- // storage for all of function's call sites // ----------------------------------------------------------------------------------- diff --git a/framework/dwarf_expression.cpp b/framework/dwarf_expression.cpp index 8f170a3..7bac984 100644 --- a/framework/dwarf_expression.cpp +++ b/framework/dwarf_expression.cpp @@ -59,14 +59,14 @@ bool expr_is_equal(pst_dwarf_expr* lhs, pst_dwarf_expr* rhs) return false; } - pst_dwarf_op* lop = lhs->next_op(NULL); - pst_dwarf_op* rop = rhs->next_op(NULL); + pst_dwarf_op* lop = lhs->next_op(lhs, NULL); + pst_dwarf_op* rop = rhs->next_op(rhs, NULL); while(lop && rop) { if(lop->operation == rop->operation && lop->arg1 == rop->arg1 && lop->arg2 == rop->arg2) { return true; } - lop = lhs->next_op(lop); - rop = rhs->next_op(rop); + lop = lhs->next_op(lhs, lop); + rop = rhs->next_op(rhs, rop); } return false; @@ -127,7 +127,7 @@ void expr_clean(pst_dwarf_expr* expr) void expr_setup(pst_dwarf_expr* expr, Dwarf_Op* exprs, size_t exprlen) { - expr->clean(); + expr->clean(expr); for(size_t i = 0; i < exprlen; ++i) { expr->add_op(expr, exprs[i].atom, exprs[i].number, exprs[i].number2); } @@ -167,7 +167,7 @@ pst_dwarf_expr* pst_dwarf_expr_new() void pst_dwarf_expr_fini(pst_dwarf_expr* expr) { - expr->clean(); + expr->clean(expr); if(expr->allocated) { pst_free(expr); } diff --git a/framework/dwarf_function.cpp b/framework/dwarf_function.cpp index aa1b879..3530962 100644 --- a/framework/dwarf_function.cpp +++ b/framework/dwarf_function.cpp @@ -71,7 +71,7 @@ bool fn_print_dwarf(pst_function* fn) pst_parameter* param = fn->next_param(fn, NULL); if(param && param->is_return) { // print return value type, function name and start list of parameters - param->print_dwarf(); + param->print_dwarf(param); fn->ctx->print(fn->ctx, " %s(", fn->name); param = fn->next_param(fn, param); } else { @@ -82,7 +82,7 @@ bool fn_print_dwarf(pst_function* fn) for(; param; param = fn->next_param(fn, param)) { if(param->is_return) { // print return value type, function name and start list of parameters - param->print_dwarf(); + param->print_dwarf(param); fn->ctx->print(fn->ctx, " %s(", fn->name); continue; } @@ -98,7 +98,7 @@ bool fn_print_dwarf(pst_function* fn) } else { fn->ctx->print(fn->ctx, " "); } - param->print_dwarf(); + param->print_dwarf(param); fn->ctx->print(fn->ctx, ";\n"); } else { if(first) { @@ -106,7 +106,7 @@ bool fn_print_dwarf(pst_function* fn) } else { fn->ctx->print(fn->ctx, ", "); } - param->print_dwarf(); + param->print_dwarf(param); } } @@ -160,8 +160,8 @@ bool fn_handle_lexical_block(pst_function* fn, Dwarf_Die* result) break; case DW_TAG_variable: { pst_parameter* param = fn->add_param(fn); - if(!param->handle_dwarf(&child, fn)) { - fn->del_param(fn, param); + if(!param->handle_dwarf(param, &child, fn)) { + fn->del_param(param); } break; } @@ -217,7 +217,7 @@ bool fn_handle_dwarf(pst_function * fn, Dwarf_Die* d) if (dwarf_getlocation (attr, &expr, &exprlen) == 0) { fn->ctx->print_expr(fn->ctx, expr, exprlen, attr); pst_decl(pst_dwarf_stack, stack, fn->ctx); - if(stack.calc(&stack, expr, exprlen, attr, this)) { + if(stack.calc(&stack, expr, exprlen, attr, fn)) { uint64_t value; if(stack.get_value(&stack, &value)) { pst_log(SEVERITY_DEBUG, "DW_AT_framebase expression: \"%s\" ==> 0x%lX", fn->ctx->buff, value); @@ -239,12 +239,12 @@ bool fn_handle_dwarf(pst_function * fn, Dwarf_Die* d) pst_parameter* ret_p = fn->add_param(fn); ret_p->is_return = true; attr = dwarf_attr(fn->die, DW_AT_type, &attr_mem); if(attr) { - if(!ret_p->handle_type(attr)) { + if(!ret_p->handle_type(ret_p, attr)) { pst_log(SEVERITY_ERROR, "Failed to handle return parameter type for function %s(...)", fn->name); - fn->del_param(fn, ret_p); + fn->del_param(ret_p); } } else { - ret_p->add_type("void", 0); + ret_p->add_type(ret_p, "void", 0); } // handle and save additionally these attributes: @@ -274,7 +274,7 @@ bool fn_handle_dwarf(pst_function * fn, Dwarf_Die* d) case DW_TAG_variable: { pst_parameter* param = fn->add_param(fn); if(!param->handle_dwarf(param, &result, fn)) { - fn->del_param(fn, param); + fn->del_param(param); } break; @@ -318,7 +318,7 @@ bool fn_unwind(pst_function* fn, Dwarf_Addr addr) } else { str = filename; } - fn->file = str; + fn->file = pst_strdup(str); fn->ctx->print(fn->ctx, "%s:%d", str, fn->line); } else { fn->ctx->print(fn->ctx, "%p", (void*)addr); @@ -407,7 +407,7 @@ bool fn_get_frame(pst_function* fn) fn->ctx->print_expr(fn->ctx, cfa_ops, cfa_nops, NULL); pst_decl(pst_dwarf_stack, stack, fn->ctx); - if(stack.calc(&stack, cfa_ops, cfa_nops, NULL, this) && stack.get_value(&stack, &fn->cfa)) { + if(stack.calc(&stack, cfa_ops, cfa_nops, NULL, fn) && stack.get_value(&stack, &fn->cfa)) { pst_log(SEVERITY_INFO, "Function %s(...): CFA expression: %s ==> %#lX", fn->name, fn->ctx->buff, fn->cfa); // setup context to match CFA for frame @@ -456,6 +456,17 @@ void pst_function_init(pst_function* fn, pst_context* _ctx, __pst_function* _par fn->allocated = false; } +pst_function* pst_function_new(pst_context* _ctx, __pst_function* _parent) +{ + pst_function* fn = pst_alloc(pst_function); + if(fn) { + pst_function_init(fn, _ctx, _parent); + fn->allocated = true; + } + + return fn; +} + void pst_function_fini(pst_function* fn) { fn->clear(fn); @@ -472,4 +483,8 @@ void pst_function_fini(pst_function* fn) if(fn->file) { pst_free(fn->file); } + + if(fn->allocated) { + pst_free(fn); + } } diff --git a/framework/dwarf_function.h b/framework/dwarf_function.h index 8fa9130..def3066 100644 --- a/framework/dwarf_function.h +++ b/framework/dwarf_function.h @@ -20,17 +20,16 @@ typedef struct __pst_function { list_node node; // uplink. !!! must be first !!! - void clear(pst_function* fn); - pst_parameter* add_param(pst_function* fn); - void del_param(pst_function* fn, pst_parameter* p); - pst_parameter* next_param(pst_function* fn, pst_parameter* p); + void (*clear) (pst_function* fn); + pst_parameter* (*add_param) (pst_function* fn); + void (*del_param) (pst_parameter* p); + pst_parameter* (*next_param) (pst_function* fn, pst_parameter* p); - bool unwind(pst_function* fn, Dwarf_Addr addr); - bool handle_dwarf(pst_function* fn, Dwarf_Die* d); - bool print_dwarf(pst_function* fn); - bool handle_lexical_block(pst_function* fn, Dwarf_Die* result); - - bool get_frame(pst_function* fn); + bool (*unwind) (pst_function* fn, Dwarf_Addr addr); + bool (*handle_dwarf) (pst_function* fn, Dwarf_Die* d); + bool (*print_dwarf) (pst_function* fn); + bool (*handle_lexical_block) (pst_function* fn, Dwarf_Die* result); + bool (*get_frame) (pst_function* fn); Dwarf_Addr lowpc; // offset to start of the function against base address Dwarf_Addr highpc; // offset to the next address after the end of the function against base address @@ -50,6 +49,8 @@ typedef struct __pst_function { pst_context* ctx; // context of unwinding bool allocated; // whether this object was allocated or not } pst_function; - +void pst_function_init(pst_function* fn, pst_context* _ctx, __pst_function* _parent); +void pst_function_fini(pst_function* fn); +pst_function* pst_function_new(pst_context* _ctx, __pst_function* _parent); #endif /* FRAMEWORK_DWARF_FUNCTION_H_ */ diff --git a/framework/dwarf_parameter.cpp b/framework/dwarf_parameter.cpp index a431ca3..c255ff8 100644 --- a/framework/dwarf_parameter.cpp +++ b/framework/dwarf_parameter.cpp @@ -50,12 +50,12 @@ bool param_print_dwarf(pst_parameter* param) if(list_count(¶m->types)) { if(!param->is_return) { if(param->has_value) { - param->ctx->print(param->ctx, "%s %s = 0x%lX", param->next_type(NULL)->name, param->name, param->location.value); + param->ctx->print(param->ctx, "%s %s = 0x%lX", param->next_type(param, NULL)->name, param->name, param->location.value); } else { - param->ctx->print(param->ctx, "%s %s = ", param->next_type(NULL)->name, param->name); + param->ctx->print(param->ctx, "%s %s = ", param->next_type(param, NULL)->name, param->name); } } else { - param->ctx->print(param->ctx, "%s", param->next_type(NULL)->name); + param->ctx->print(param->ctx, "%s", param->next_type(param, NULL)->name); } } else { if(param->has_value) { @@ -89,7 +89,7 @@ bool param_handle_type(pst_parameter* param, Dwarf_Attribute* base) dwarf_formudata(attr, ¶m->size); } pst_log(SEVERITY_DEBUG, "base type '%s'(%lu)", dwarf_diename(&ret_die), param->size); - param->add_type(dwarf_diename(&ret_die), DW_TAG_base_type); + param->add_type(param, dwarf_diename(&ret_die), DW_TAG_base_type); param->type = DW_TAG_base_type; attr = dwarf_attr(&ret_die, DW_AT_encoding, &attr_mem); @@ -101,38 +101,38 @@ bool param_handle_type(pst_parameter* param, Dwarf_Attribute* base) } case DW_TAG_array_type: pst_log(SEVERITY_DEBUG, "array type"); - param->add_type("[]", DW_TAG_array_type); + param->add_type(param, "[]", DW_TAG_array_type); break; case DW_TAG_structure_type: pst_log(SEVERITY_DEBUG, "structure type"); - param->add_type("struct", DW_TAG_structure_type); + param->add_type(param, "struct", DW_TAG_structure_type); break; case DW_TAG_union_type: pst_log(SEVERITY_DEBUG, "union type"); - param->add_type("union", DW_TAG_union_type); + param->add_type(param, "union", DW_TAG_union_type); break; case DW_TAG_class_type: pst_log(SEVERITY_DEBUG, "class type"); - param->add_type("class", DW_TAG_class_type); + param->add_type(param, "class", DW_TAG_class_type); break; case DW_TAG_pointer_type: pst_log(SEVERITY_DEBUG, "pointer type"); - param->add_type("*", DW_TAG_pointer_type); + param->add_type(param, "*", DW_TAG_pointer_type); break; case DW_TAG_enumeration_type: pst_log(SEVERITY_DEBUG, "enumeration type"); - param->add_type("enum", DW_TAG_enumeration_type); + param->add_type(param, "enum", DW_TAG_enumeration_type); break; case DW_TAG_const_type: pst_log(SEVERITY_DEBUG, "constant type"); - param->add_type("const", DW_TAG_const_type); + param->add_type(param, "const", DW_TAG_const_type); break; case DW_TAG_subroutine_type: pst_log(SEVERITY_DEBUG, "Skipping subroutine type"); break; case DW_TAG_typedef: pst_log(SEVERITY_DEBUG, "typedef '%s' type", dwarf_diename(&ret_die)); - param->add_type(dwarf_diename(&ret_die), DW_TAG_typedef); + param->add_type(param, dwarf_diename(&ret_die), DW_TAG_typedef); break; default: pst_log(SEVERITY_WARNING, "Unknown 0x%X tag type", dwarf_tag(&ret_die)); @@ -141,7 +141,7 @@ bool param_handle_type(pst_parameter* param, Dwarf_Attribute* base) attr = dwarf_attr(&ret_die, DW_AT_type, &attr_mem); if(attr) { - return param->handle_type(attr); + return param->handle_type(param, attr); } return true; @@ -295,7 +295,7 @@ pst_parameter* pst_parameter_new(pst_context* ctx) } void pst_parameter_fini(pst_parameter* param) { - param->clear(); + param->clear(param); if(param->name) { pst_free(param->name); } diff --git a/framework/dwarf_stack.cpp b/framework/dwarf_stack.cpp index 8c68e9a..0277b37 100644 --- a/framework/dwarf_stack.cpp +++ b/framework/dwarf_stack.cpp @@ -178,7 +178,6 @@ void stack_clear(pst_dwarf_stack* st) bool stack_calc(pst_dwarf_stack* st, Dwarf_Op *exprs, int expr_len, Dwarf_Attribute* attr, pst_function* fun = NULL) { st->clear(st); - bool nret = true; for (int i = 0; i < expr_len; i++) { const dwarf_op_map* map = find_op_map(exprs[i].atom); @@ -220,7 +219,7 @@ bool stack_calc(pst_dwarf_stack* st, Dwarf_Op *exprs, int expr_len, Dwarf_Attrib Dwarf_Op *expr; size_t exprlen; if (dwarf_getlocation(&attr_mem, &expr, &exprlen) == 0) { - pst_call_site* cs = fun->parent->find_call_site(fun); + pst_call_site* cs = fun->parent->call_sites.find_call_site(&fun->parent->call_sites, fun); if(!cs) { pst_log(SEVERITY_ERROR, "Failed to find call site while calculate DW_OP_GNU_entry_value expression"); return false; @@ -228,7 +227,7 @@ bool stack_calc(pst_dwarf_stack* st, Dwarf_Op *exprs, int expr_len, Dwarf_Attrib pst_dwarf_expr loc; pst_dwarf_expr_init(&loc); loc.setup(&loc, expr, exprlen); - pst_call_site_param* param = cs->find_param(loc); + pst_call_site_param* param = cs->find_param(cs, loc); pst_dwarf_expr_fini(&loc); if(!param) { pst_log(SEVERITY_ERROR, "Failed to find call site parameter while calculate DW_OP_GNU_entry_value expression"); @@ -240,8 +239,7 @@ bool stack_calc(pst_dwarf_stack* st, Dwarf_Op *exprs, int expr_len, Dwarf_Attrib continue; } else { pst_log(SEVERITY_ERROR, "Failed to get DW_OP_GNU_entry_value attr location"); - nret = false; - break; + return false; } } else { pst_log(SEVERITY_ERROR, "Failed to get DW_OP_GNU_entry_value attr expression"); diff --git a/framework/dwarf_utils.cpp b/framework/dwarf_utils.cpp index 78a0a91..ea0bf18 100644 --- a/framework/dwarf_utils.cpp +++ b/framework/dwarf_utils.cpp @@ -32,7 +32,7 @@ bool handle_location(pst_context* ctx, Dwarf_Attribute* attr, pst_dwarf_expr* lo if(dwarf_hasform(attr, DW_FORM_exprloc)) { // Location expression (exprloc class of location in DWARF terms) if(dwarf_getlocation(attr, &expr, &exprlen) == 0) { - loc->setup(expr, exprlen); + loc->setup(loc, expr, exprlen); ctx->print_expr(ctx, expr, exprlen, attr); ret = stack.calc(&stack, expr, exprlen, attr, fun); } @@ -45,7 +45,7 @@ bool handle_location(pst_context* ctx, Dwarf_Attribute* attr, pst_dwarf_expr* lo for(int i = 0; (off = dwarf_getlocations (attr, off, &base, &start, &end, &expr, &exprlen)) > 0; ++i) { ctx->print_expr(ctx, expr, exprlen, attr); if(offset >= start && offset <= end) { - loc->setup(expr, exprlen); + loc->setup(loc, expr, exprlen); // actual location, try to calculate Location expression ret = stack.calc(&stack, expr, exprlen, attr, fun); } else { diff --git a/framework/hash_multimap.cpp b/framework/hash_multimap.cpp index e3e426c..0a3cf64 100644 --- a/framework/hash_multimap.cpp +++ b/framework/hash_multimap.cpp @@ -1,20 +1,19 @@ /* ============================================================================= * CDL (Configuration Definition Language) validator $Revision: 1.4 $ - * (C)2004-2007 Nikolai Nosov. All rights reserved. + * (C)2004-2007 Nikolay Nosov. All rights reserved. * * File: $RCSfile: hash_multimap.c,v $ * Purpose: Hash Multimap implementation - * Written by: Nikolai Nosov nnosov@gmail.com + * Written by: Nikolay Nosov * Last modified: $Date: 2008/06/21 12:15:53 $ by $Author: nnosov $. * * For more information please visit + * http://nsoft.volgocity.ru/cdl or * http://cdl.sourceforge.net * ===========================================================================*/ - #include #include #include - #include "hash_multimap.h" /* Default hash function @@ -22,16 +21,19 @@ @param size hash key size in bytes @return hash value, depends of the hash key */ -static unsigned int default_hash_fn(const char *key, int size) +static unsigned int default_hash_fn(const void *key, int size) { register int i, j; unsigned int cs = 0; unsigned int ps = 0; - if(key) { - for(i = 0, j = 0; i < size; i++, j++) { - ps |= ((unsigned int)key[i]) << (j * 8); - if(j == 3 || j == (size - 1)) { + if(key) + { + for(i = 0, j = 0; i < size; i++, j++) + { + ps |= ((unsigned int)((const char*)key)[i]) << (j * 8); + if(j == 3 || j == (size - 1)) + { cs ^= ps; ps = 0; j = 0; @@ -42,12 +44,13 @@ static unsigned int default_hash_fn(const char *key, int size) return cs; } -static int default_compare_fn(const char *key1, const char *key2, const int size) +static int default_compare_fn(const void *key1, const void *key2, const int size) { return !memcmp(key1, key2, size); } /** Initialize hash node. Must be called before first usage of the node. + @param node pointer to the hash node descriptor */ void hash_node_init(struct hash_node *node) @@ -58,6 +61,7 @@ void hash_node_init(struct hash_node *node) } /** Cleanup hash node + @param node pointer to the hash node descriptor */ void hash_node_cleanup(struct hash_node *node) @@ -69,6 +73,7 @@ void hash_node_cleanup(struct hash_node *node) } /** Initialize hash table + @param map pointer to the hash table descriptor @param hash_shift size of the hash table in bits. Should be greater than HASH_MIN_SHIFT and less than HASH_MAX_SHIFT. In case of less than HASH_MIN_SHIFT, @@ -83,7 +88,8 @@ int hash_head_init(struct hash_head *map, unsigned int hash_shift, _hash_fn hf, { int i; - if(map) { + if(map) + { if(hash_shift <= HASH_MIN_SHIFT) { map->hash_shift = HASH_MIN_SHIFT; } else if(hash_shift >= HASH_MAX_SHIFT) { @@ -95,9 +101,11 @@ int hash_head_init(struct hash_head *map, unsigned int hash_shift, _hash_fn hf, map->hash_size = 1UL << map->hash_shift; map->hash_mask = (map->hash_size - 1); - map->bucket = (list_head*)malloc(sizeof(list_head) * map->hash_size); - if(map->bucket) { - for(uint16_t i = 0; i < map->hash_size; i++) { + map->bucket = (struct list_head *)malloc(sizeof(struct list_head) * map->hash_size); + if(map->bucket) + { + for(i = 0; i < map->hash_size; i++) + { list_head_init(map->bucket + i); } @@ -112,12 +120,12 @@ int hash_head_init(struct hash_head *map, unsigned int hash_shift, _hash_fn hf, } else { map->compare_fn = default_compare_fn; } - } else { - return ENOMEM; } - } else { - return ENODEV; + else + return ENOMEM; } + else + return ENODEV; return 0; } @@ -132,10 +140,14 @@ void hash_head_cleanup(struct hash_head *map) struct hash_node *node; int i; - if(map) { - if(map->bucket) { - for(i = 0; i < map->hash_size; i++) { - list_for_each_safe(p, n, map->bucket + i) { + if(map) + { + if(map->bucket) + { + for(i = 0; i < map->hash_size; i++) + { + list_for_each_safe(p, n, map->bucket + i) + { node = list_entry(p, struct hash_node, node); hash_node_cleanup(node); } @@ -160,12 +172,12 @@ struct hash_node* hash_find(struct hash_head *map, const void *key, int key_size struct hash_node *node; list = map->bucket + (map->hash_fn(key, key_size) & map->hash_mask); - list_for_each(n, list) { + list_for_each(n, list) + { node = list_entry(n, struct hash_node, node); - if(key_size == node->key_size) { - if(map->compare_fn(key, node->key, key_size)) { - return node; - } + if(key_size == node->key_size) + { + if(map->compare_fn(key, node->key, key_size)) return node; } } @@ -184,9 +196,11 @@ struct hash_node* hash_find_next(struct hash_head *map, struct hash_node *hn1) struct hash_node *hn2; - while((n = list_next(n)) != NULL) { + while((n = list_next(n)) != NULL) + { hn2 = list_entry(n, struct hash_node, node); - if(hn1->key_size == hn2->key_size) { + if(hn1->key_size == hn2->key_size) + { if(map->compare_fn(hn1->key, hn2->key, hn2->key_size)) return hn2; } } @@ -203,10 +217,11 @@ struct hash_node* hash_find_next(struct hash_head *map, struct hash_node *hn1) @return zero in case of success, ENOMEM in case of error */ -int hash_add(struct hash_head *map, struct hash_node *node, void *key, int key_size) +int hash_add(struct hash_head *map, struct hash_node *node, const void *key, int key_size) { node->key = (char*)malloc(key_size); - if(node->key) { + if(node->key) + { memcpy(node->key, key, key_size); node->key_size = key_size; list_add_bottom(map->bucket + (map->hash_fn(key, key_size) & map->hash_mask), &node->node); @@ -249,7 +264,8 @@ struct hash_node * hash_node_first(struct hash_iterator *iter) iter->current = list_first(iter->map->bucket); iter->map_idx = 0; - if (iter->current) { + if (iter->current) + { return list_entry(iter->current, struct hash_node, node); } @@ -263,14 +279,11 @@ struct hash_node * hash_node_first(struct hash_iterator *iter) */ struct hash_node * hash_node_next(struct hash_iterator *iter) { - if(iter->map_idx >= iter->map->hash_size) { - return NULL; - } + if(iter->map_idx >= iter->map->hash_size) return NULL; if(iter->current) { iter->current = list_next(iter->current); } - if(iter->current) { return list_entry(iter->current, struct hash_node, node); } @@ -308,9 +321,7 @@ int hash_count(struct hash_head *head) int i; int count = 0; - for(i = 0; i < head->hash_size; i++) { - count += list_count(head->bucket + i); - } + for(i = 0; i < head->hash_size; i++) count += list_count(head->bucket + i); return count; } diff --git a/framework/hash_multimap.h b/framework/hash_multimap.h index 650eb5d..acaec75 100644 --- a/framework/hash_multimap.h +++ b/framework/hash_multimap.h @@ -1,109 +1,94 @@ -#ifndef HASH_MULTIMAP_H -#define HASH_MULTIMAP_H - -/* ============================================================================= - * CDL (Configuration Definition Language) validator $Revision: 1.4 $ - * (C)2004-2007 Nikolai Nosov. All rights reserved. - * - * File: $RCSfile: hash_multimap.c,v $ - * Purpose: Hash Multimap implementation - * Written by: Nikolai Nosov nnosov@gmail.com - * Last modified: $Date: 2008/06/21 12:15:53 $ by $Author: nnosov $. - * - * For more information please visit - * http://cdl.sourceforge.net - * ===========================================================================*/ - -#include - -#include "list_head.h" - -#define HASH_MIN_SHIFT (8) -#define HASH_MAX_SHIFT (15) - -#define hash_entry(ptr, type, member) container_of(ptr, type, member) - -/** Hash multimap node descriptor - -@param key hash key value -@param key_size hash key size in bytes -@param node uplink to hash multimap table -*/ -typedef struct hash_node -{ - list_node node; - char* key; - int key_size; -} hash_node; - -/** Hash function prototype - -@param key hash key value -@param key_size hash key size in bytes -@return hash value -*/ -typedef unsigned int (* _hash_fn)(const char *key, int key_size); - -/** Compare function prototype - * - * @param key1 pointer to the first key for comparison - * @param key2 pointer to the second key for comparison - * @param size size of compared part of the keys in bytes - * - * @return zero if keys equals each other, othervize 1 -*/ -typedef int (*_compare_fn)(const char *key1, const char *key2, int size); - -/** Hash multimap table descriptor - -@param hash_shift size of hash table as power of 2 -@param hash_size size of the hash table -@param hash_mask mask for the hash value -@param bucket pointer to the array of linked lists. in other words, pointer to -hash multimap table -@param count count of the nodes in the hash table -*/ -typedef struct hash_head { - uint8_t hash_shift; - uint16_t hash_size; - uint32_t hash_mask; - list_head* bucket; - - _hash_fn hash_fn; - _compare_fn compare_fn; -} hash_head; - -/** Hash table iterator - -@param map pointer to the hash table descriptor, used for iteration -@param current pointer to the current list node (bucket[map_idx]) -@param map_idx current bucket index -*/ -struct hash_iterator { - hash_head* map; // pointer to the hash map header - list_node* current; // pointer to current list node in the bucket[map_idx] list - int map_idx; // index of current list in the hash map bucket -}; - -void hash_node_init(struct hash_node *node); -void hash_node_cleanup(struct hash_node *node); - -unsigned int default_hash_fn(const char *key, int size); -int default_compare_fn(const char *key1, const char *key2, const int size); - -int hash_head_init(struct hash_head *map, unsigned int hash_shift = 8, _hash_fn hf = default_hash_fn, _compare_fn cf = default_compare_fn); -void hash_head_cleanup(struct hash_head *map); - -struct hash_node* hash_find(struct hash_head *map, const void *key, int key_size); -struct hash_node* hash_find_next(struct hash_head *map, struct hash_node *node); - -int hash_add(struct hash_head *map, struct hash_node *node, void *key, int key_size); -void hash_del(struct hash_node *node); - -void hash_iterator_init(struct hash_head *map, struct hash_iterator *iter); -struct hash_node * hash_node_first(struct hash_iterator *iter); -struct hash_node * hash_node_next(struct hash_iterator *iter); -void hash_node_del(struct hash_iterator *iter); -int hash_count(struct hash_head *head); - -#endif // HASH_MULTIMAP_H +#ifndef HASH_MULTIMAP_H +#define HASH_MULTIMAP_H + +#include "list_head.h" + +#define HASH_MIN_SHIFT (8) +#define HASH_MAX_SHIFT (15) + +#define hash_entry(ptr, type, member) container_of(ptr, type, member) + +/** Hash multimap node descriptor + +@param key hash key value +@param key_size hash key size in bytes +@param node uplink to hash multimap table +*/ +struct hash_node +{ + char *key; + int key_size; + struct list_node node; +}; + +/** Hash function prototype + +@param key hash key value +@param key_size hash key size in bytes +@return hash value +*/ +typedef unsigned int (* _hash_fn)(const void *key, int key_size); + +/** Compare function prototype + * + * @param key1 pointer to the first key for comparison + * @param key2 pointer to the second key for comparison + * @param size size of compared part of the keys in bytes + * + * @return zero if keys equals each other, othervize 1 +*/ +typedef int (*_compare_fn)(const void *key1, const void *key2, int size); + +/** Hash multimap table descriptor + +@param hash_shift size of hash table as power of 2 +@param hash_size size of the hash table +@param hash_mask mask for the hash value +@param bucket pointer to the array of linked lists. in other words, pointer to +hash multimap table +@param count count of the nodes in the hash table +*/ +struct hash_head +{ + unsigned char hash_shift; + unsigned short hash_size; + unsigned int hash_mask; + struct list_head *bucket; + //int count; + + _hash_fn hash_fn; + _compare_fn compare_fn; +}; + +/** Hash table iterator + +@param map pointer to the hash table descriptor, used for iteration +@param current pointer to the current list node (bucket[map_idx]) +@param map_idx current bucket index +*/ +struct hash_iterator +{ + struct hash_head *map; // pointer to the hash map header + struct list_node *current; // pointer to current list node in the bucket[map_idx] list + unsigned int map_idx; // index of current list in the hash map bucket +}; + +void hash_node_init(struct hash_node *node); +void hash_node_cleanup(struct hash_node *node); + +int hash_head_init(struct hash_head *map, unsigned int hash_shift = HASH_MIN_SHIFT, _hash_fn hf = 0, _compare_fn cf = 0); +void hash_head_cleanup(struct hash_head *map); + +struct hash_node* hash_find(struct hash_head *map, const void *key, int key_size); +struct hash_node* hash_find_next(struct hash_head *map, struct hash_node *node); + +int hash_add(struct hash_head *map, struct hash_node *node, const void *key, int key_size); +void hash_del(struct hash_node *node); + +void hash_iterator_init(struct hash_head *map, struct hash_iterator *iter); +struct hash_node * hash_node_first(struct hash_iterator *iter); +struct hash_node * hash_node_next(struct hash_iterator *iter); +void hash_node_del(struct hash_iterator *iter); +int hash_count(struct hash_head *head); + +#endif // HASH_MULTIMAP_H diff --git a/framework/logger/log.cpp b/framework/logger/log.cpp index 3ff4514..b8676bc 100644 --- a/framework/logger/log.cpp +++ b/framework/logger/log.cpp @@ -77,7 +77,7 @@ void log_init_base(pst_log* plog, const char* source) plog->child = 0; } -void log_fini(pst_log* log) +void pst_log_fini(pst_log* log) { pthread_mutex_destroy(&log->mLock); log->close(log); @@ -133,7 +133,7 @@ bool is_opened_console(pst_log* log) { return true; } -void pst_init_console(pst_log* log) +void pst_log_init_console(pst_log* log) { log_init_base(log, NULL); log->close = close_console; diff --git a/framework/registers.h b/framework/registers.h index 121e9b5..045cb0c 100644 --- a/framework/registers.h +++ b/framework/registers.h @@ -21,15 +21,4 @@ typedef enum { REG_EXPR_ERROR } pst_reg_error; -typedef struct __pst_frame : public SC_ListNode { - __pst_frame() { - memset(reg_state, REG_UNDEFINED, sizeof(reg_state)); - memset(regs, 0, sizeof(regs)); - cfa = 0; - } - int32_t reg_state[128]; - uint64_t regs[128]; - uint64_t cfa; -} pst_frame; - pst_reg_error pst_get_reg(pst_context* ctx, int regno, uint64_t& regval); diff --git a/framework/sysutils.cpp b/framework/sysutils.cpp index 4e689ca..11883c7 100644 --- a/framework/sysutils.cpp +++ b/framework/sysutils.cpp @@ -34,26 +34,26 @@ // dwarf_getattrs() allows to enumerate all DIE attributes // dwarf_getfuncs() allows to enumerate functions within CU -bool __pst_handler::get_dwarf_function(pst_function* fun) +bool handler_get_dwarf_function(pst_handler* h, pst_function* fun) { Dwarf_Addr mod_cu = 0; // get CU(Compilation Unit) debug definition - ctx.module = dwfl_addrmodule(ctx.dwfl, fun->pc); - Dwarf_Die* cdie = dwfl_module_addrdie(ctx.module, fun->pc, &mod_cu); + h->ctx.module = dwfl_addrmodule(h->ctx.dwfl, fun->pc); + Dwarf_Die* cdie = dwfl_module_addrdie(h->ctx.module, fun->pc, &mod_cu); //Dwarf_Die* cdie = dwfl_addrdie(dwfl, addr, &mod_bias); if(!cdie) { - ctx.log(SEVERITY_INFO, "Failed to find DWARF DIE for address %X", fun->pc); + h->ctx.log(SEVERITY_INFO, "Failed to find DWARF DIE for address %X", fun->pc); return false; } if(dwarf_tag(cdie) != DW_TAG_compile_unit) { - ctx.log(SEVERITY_DEBUG, "Skipping non-cu die. DWARF tag: 0x%X, name = %s", dwarf_tag(cdie), dwarf_diename(cdie)); + h->ctx.log(SEVERITY_DEBUG, "Skipping non-cu die. DWARF tag: 0x%X, name = %s", dwarf_tag(cdie), dwarf_diename(cdie)); return false; } Dwarf_Die result; if(dwarf_child(cdie, &result)) { - ctx.log(SEVERITY_ERROR, "No child DIE found for CU %s", dwarf_diename(cdie)); + h->ctx.log(SEVERITY_ERROR, "No child DIE found for CU %s", dwarf_diename(cdie)); return false; } @@ -63,8 +63,8 @@ bool __pst_handler::get_dwarf_function(pst_function* fun) int tag = dwarf_tag(&result); if(tag == DW_TAG_subprogram || tag == DW_TAG_entry_point || tag == DW_TAG_inlined_subroutine) { //ctx.log(SEVERITY_DEBUG, "function die name %s", dwarf_diename(&result)); - if(!strcmp(fun->name.c_str(), dwarf_diename(&result))) { - return fun->handle_dwarf(&result); + if(!strcmp(fun->name, dwarf_diename(&result))) { + return fun->handle_dwarf(fun, &result); } } } while(dwarf_siblingof(&result, &result) == 0); @@ -72,76 +72,95 @@ bool __pst_handler::get_dwarf_function(pst_function* fun) return nret; } -pst_function* __pst_handler::add_function(__pst_function* parent) +pst_function* handler_add_function(pst_handler* h, pst_function* parent) { - pst_function* f = new pst_function(&ctx, parent); - functions.InsertLast(f); + pst_new(pst_function, fn, &h->ctx, parent); + list_add_bottom(&h->functions, &fn->node); - return f; + return fn; } -void __pst_handler::del_function(pst_function* f) +void handler_del_function(pst_function* fn) { - functions.Remove(f); - delete f; + list_del(&fn->node); + pst_function_fini(fn); } -void __pst_handler::clear() +void handler_clear(pst_handler* h) { - for(pst_function* f = (pst_function*)functions.First(); f; f = (pst_function*)functions.First()) { - functions.Remove(f); - delete f; + pst_function* fn = NULL; + struct list_node *pos, *tn; + list_for_each_entry_safe(fn, pos, tn, &h->functions, node) { + list_del(&fn->node); + pst_function_fini(fn); } } -pst_function* __pst_handler::next_function(pst_function* f) +pst_function* handler_next_function(pst_handler* h, pst_function* fn) { - pst_function* next = NULL; - if(!f) { - next = (pst_function*)functions.First(); - } else { - next = (pst_function*)functions.Next(f); + list_node* n = (fn == NULL) ? list_first(&h->functions) : list_next(&fn->node); + pst_function* ret = NULL; + if(n) { + ret = list_entry(n, pst_function, node); } - return next; + return ret; } -pst_function* __pst_handler::last_function() +pst_function* handler_prev_function(pst_handler* h, pst_function* fn) { - return (pst_function*)functions.Last(); + list_node* n = (fn == NULL) ? list_last(&h->functions) : list_prev(&fn->node); + pst_function* ret = NULL; + if(n) { + ret = list_entry(n, pst_function, node); + } + + return ret; } -bool __pst_handler::handle_dwarf() +pst_function* handler_last_function(pst_handler* h) { - ctx.clean_print(&ctx); + list_node* n = list_last(&h->functions); + if(n) { + return list_entry(n, pst_function, node); + } + + return NULL; +} + +bool handler_handle_dwarf(pst_handler* h) +{ + h->ctx.clean_print(&h->ctx); Dl_info info; //for(pst_function* fun = next_function(NULL); fun; fun = next_function(fun)) { - for(pst_function* fun = (pst_function*)functions.Last(); fun; fun = (pst_function*)functions.Prev(fun)) { + for(pst_function* fun = (pst_function*)handler_last_function(h); fun; fun = h->prev_function(h, fun)) { dladdr((void*)(fun->pc), &info); - ctx.module = dwfl_addrmodule(ctx.dwfl, fun->pc); - ctx.base_addr = (uint64_t)info.dli_fbase; - ctx.log(SEVERITY_INFO, "Function %s(...): module name: %s, base address: %p, CFA: %#lX", fun->name.c_str(), info.dli_fname, info.dli_fbase, fun->parent ? fun->parent->sp : 0); - ctx.curr_frame = &fun->cursor; - ctx.sp = fun->sp; - ctx.cfa = fun->cfa; + h->ctx.log(SEVERITY_INFO, "Function %s(...): module name: %s, base address: %p, CFA: %#lX", fun->name, info.dli_fname, info.dli_fbase, fun->parent ? fun->parent->sp : 0); - ctx.curr_frame = &fun->cursor; - get_dwarf_function(fun); + // setup context + h->ctx.module = dwfl_addrmodule(h->ctx.dwfl, fun->pc); + h->ctx.base_addr = (uint64_t)info.dli_fbase; + h->ctx.curr_frame = &fun->cursor; + h->ctx.sp = fun->sp; + h->ctx.cfa = fun->cfa; + h->ctx.curr_frame = &fun->cursor; + + handler_get_dwarf_function(h, fun); } return true; } -void __pst_handler::print_dwarf() +void handler_print_dwarf(pst_handler* h) { - ctx.clean_print(&ctx); - ctx.print(&ctx, "DWARF-based stack trace information:\n"); + h->ctx.clean_print(&h->ctx); + h->ctx.print(&h->ctx, "DWARF-based stack trace information:\n"); uint32_t idx = 0; - for(pst_function* function = next_function(NULL); function; function = next_function(function)) { - ctx.print(&ctx, "[%-2u] ", idx); idx++; - function->print_dwarf(); - ctx.print(&ctx, "\n"); + for(pst_function* fn = h->next_function(h, NULL); fn; fn = h->next_function(h, fn)) { + h->ctx.print(&h->ctx, "[%-2u] ", idx); idx++; + fn->print_dwarf(fn); + h->ctx.print(&h->ctx, "\n"); } } @@ -155,13 +174,13 @@ Dwfl_Callbacks callbacks = { #include -bool __pst_handler::unwind() +bool handler_unwind(pst_handler* h) { - ctx.clean_print(&ctx); + h->ctx.clean_print(&h->ctx); #ifdef REG_RIP // x86_64 - caller = (void *) ctx.hcontext->uc_mcontext.gregs[REG_RIP]; - ctx.sp = ctx.hcontext->uc_mcontext.gregs[REG_RSP]; - ctx.log(SEVERITY_DEBUG, "Original caller's SP: %#lX", ctx.sp); + h->caller = (void *) h->ctx.hcontext->uc_mcontext.gregs[REG_RIP]; + h->ctx.sp = h->ctx.hcontext->uc_mcontext.gregs[REG_RSP]; + h->ctx.log(SEVERITY_DEBUG, "Original caller's SP: %#lX", h->ctx.sp); #elif defined(REG_EIP) // x86_32 caller_address = (void *) uctx->uc_mcontext.gregs[REG_EIP]); #elif defined(__arm__) @@ -180,60 +199,89 @@ bool __pst_handler::unwind() //handle = dlopen(NULL, RTLD_NOW); Dl_info info; - dladdr(caller, &info); - ctx.base_addr = (uint64_t)info.dli_fbase; - ctx.log(SEVERITY_INFO, "Process address information: PC address: %p, base address: %p, object name: %s", caller, info.dli_fbase, info.dli_fname); + dladdr(h->caller, &info); + h->ctx.base_addr = (uint64_t)info.dli_fbase; + h->ctx.log(SEVERITY_INFO, "Process address information: PC address: %p, base address: %p, object name: %s", h->caller, info.dli_fbase, info.dli_fname); - ctx.dwfl = dwfl_begin(&callbacks); - if(ctx.dwfl == NULL) { - ctx.print(&ctx, "Failed to initialize libdw session for parse stack frames"); + h->ctx.dwfl = dwfl_begin(&callbacks); + if(h->ctx.dwfl == NULL) { + h->ctx.print(&h->ctx, "Failed to initialize libdw session for parse stack frames"); return false; } - if(dwfl_linux_proc_report(ctx.dwfl, getpid()) != 0 || dwfl_report_end(ctx.dwfl, NULL, NULL) !=0) { - ctx.print(&ctx, "Failed to parse debug section of executable"); + if(dwfl_linux_proc_report(h->ctx.dwfl, getpid()) != 0 || dwfl_report_end(h->ctx.dwfl, NULL, NULL) !=0) { + h->ctx.print(&h->ctx, "Failed to parse debug section of executable"); return false; } - ctx.print(&ctx, "Stack trace: caller = %p\n", caller); + h->ctx.print(&h->ctx, "Stack trace: caller = %p\n", h->caller); - unw_getcontext(&ctx.context); - unw_init_local(&ctx.cursor, &ctx.context); - ctx.curr_frame = &ctx.cursor; - for(int i = 0, skip = 1; unw_step(ctx.curr_frame) > 0; ++i) { - if(unw_get_reg(ctx.curr_frame, UNW_REG_IP, &addr)) { - ctx.log(SEVERITY_DEBUG, "Failed to get IP value"); + unw_getcontext(&h->ctx.context); + unw_init_local(&h->ctx.cursor, &h->ctx.context); + h->ctx.curr_frame = &h->ctx.cursor; + for(int i = 0, skip = 1; unw_step(h->ctx.curr_frame) > 0; ++i) { + if(unw_get_reg(h->ctx.curr_frame, UNW_REG_IP, &h->addr)) { + h->ctx.log(SEVERITY_DEBUG, "Failed to get IP value"); continue; } unw_word_t sp; - if(unw_get_reg(ctx.curr_frame, UNW_REG_SP, &sp)) { - ctx.log(SEVERITY_DEBUG, "Failed to get SP value"); + if(unw_get_reg(h->ctx.curr_frame, UNW_REG_SP, &sp)) { + h->ctx.log(SEVERITY_DEBUG, "Failed to get SP value"); continue; } - if(addr == (uint64_t)caller) { + if(h->addr == (uint64_t)h->caller) { skip = 0; } else if(skip) { - ctx.log(SEVERITY_DEBUG, "Skipping frame #%d: PC = %#lX, SP = %#lX", i, addr, sp); + h->ctx.log(SEVERITY_DEBUG, "Skipping frame #%d: PC = %#lX, SP = %#lX", i, h->addr, sp); continue; } - ctx.print(&ctx, "[%-2d] ", i); - ctx.module = dwfl_addrmodule(ctx.dwfl, addr); - pst_function* last = last_function(); - pst_function* fun = add_function(NULL); - fun->sp = sp; - ctx.log(SEVERITY_DEBUG, "Analyze frame #%d: PC = %#lX, SP = %#lX", i, addr, sp); - if(!fun->unwind(addr)) { - del_function(fun); + h->ctx.print(&h->ctx, "[%-2d] ", i); + h->ctx.module = dwfl_addrmodule(h->ctx.dwfl, h->addr); + pst_function* last = handler_last_function(h); + pst_function* fn = h->add_function(h, NULL); + fn->sp = sp; + h->ctx.log(SEVERITY_DEBUG, "Analyze frame #%d: PC = %#lX, SP = %#lX", i, h->addr, sp); + if(!fn->unwind(fn, h->addr)) { + h->del_function(fn); } else { if(last) { - last->parent = fun; + last->parent = fn; } //get_frame(fun); } - ctx.print(&ctx, "\n"); + h->ctx.print(&h->ctx, "\n"); } return true; } + +void pst_handler_init(pst_handler* h, ucontext_t* hctx) +{ + // methods + h->clear = handler_clear; + h->add_function = handler_add_function; + h->del_function = handler_del_function; + h->next_function = handler_next_function; + h->prev_function = handler_prev_function; + + // fields + pst_context_init(&h->ctx, hctx); + h->handle = NULL; + h->addr = 0; + h->frame = NULL; + h->caller = NULL; + list_head_init(&h->functions); +} + +void pst_handler_fini(pst_handler* h) +{ + if(h->handle) { + dlclose(h->handle); + } + + h->clear(h); + pst_context_fini(&h->ctx); +} + diff --git a/framework/sysutils.h b/framework/sysutils.h index 9139420..2793a9d 100644 --- a/framework/sysutils.h +++ b/framework/sysutils.h @@ -32,43 +32,27 @@ #include "dwarf_utils.h" #include "dwarf_function.h" -typedef struct __pst_handler { - __pst_handler(ucontext_t* hctx) - { - pst_context_init(&ctx, hctx); - caller = NULL; - frame = NULL; - addr = 0; - handle = 0; - } +typedef struct pst_handler { + // methods + void (*clear) (pst_handler* h); + pst_function* (*add_function) (pst_handler* h, pst_function* fun); + void (*del_function) (pst_function* f); + pst_function* (*next_function) (pst_handler* h, pst_function* f); + pst_function* (*prev_function) (pst_handler* h, pst_function* fn); - ~__pst_handler() - { - if(handle) { - dlclose(handle); - } - - clear(); - pst_context_fini(&ctx); - } - - void clear(); - pst_function* add_function(pst_function* fun); - void del_function(pst_function* f); - pst_function* next_function(pst_function* f); - pst_function* last_function(); - - bool handle_dwarf(); - void print_dwarf(); - bool unwind(); - bool get_dwarf_function(pst_function* fun); + bool (*handle_dwarf) (pst_handler* h); + void (*print_dwarf) (pst_handler* h); + bool (*unwind) (pst_handler* h); + // fields pst_context ctx; // context of unwinding void* handle; // process handle Dwarf_Addr addr; // address of currently processed function Dwarf_Frame* frame; // currently processed stack frame void* caller; // pointer to the function which requested to unwind stack - SC_ListHead functions; // list of functions in stack frame + list_head functions; // list of functions in stack frame } pst_handler; +void pst_handler_init(pst_handler* h, ucontext_t* hctx); +void pst_handler_fini(pst_handler* h); #endif /* SC_SYSUTILS_H_ */ diff --git a/main.cpp b/main.cpp index 56b6208..6a8bbd3 100644 --- a/main.cpp +++ b/main.cpp @@ -62,17 +62,17 @@ void FatalSignalHandler(int sig, siginfo_t* info, void* context) pst_log(SEVERITY_ERROR, "%s signal handled", strsignal(sig)); bool ret = false; - pst_handler handler((ucontext_t*)context); + pst_decl(pst_handler, handler, (ucontext_t*)context); if((context != 0) && (sig == SIGSEGV || sig == SIGABRT || sig == SIGBUS || sig == SIGFPE)) { - ret = handler.unwind(); + ret = handler.unwind(&handler); } if(ret) { pst_log(SEVERITY_INFO, "%s", handler.ctx.buff); - handler.handle_dwarf(); - handler.print_dwarf(); + handler.handle_dwarf(&handler); + handler.print_dwarf(&handler); pst_log(SEVERITY_INFO, "%s", handler.ctx.buff); } else { pst_log(SEVERITY_ERROR, "No stack trace obtained");