fix most of compilation warnings

This commit is contained in:
2020-02-02 12:28:43 +04:00
parent abba9f735b
commit dbaffdf689
17 changed files with 371 additions and 331 deletions
+1
View File
@@ -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
+1 -1
View File
@@ -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;
+5 -3
View File
@@ -6,11 +6,13 @@
*/
#include <dwarf.h>
#include <elfutils/libdw.h>
#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;
+7 -1
View File
@@ -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
// -----------------------------------------------------------------------------------
+6 -6
View File
@@ -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);
}
+28 -13
View File
@@ -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);
}
}
+12 -11
View File
@@ -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_ */
+14 -14
View File
@@ -50,12 +50,12 @@ bool param_print_dwarf(pst_parameter* param)
if(list_count(&param->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 = <undefined>", param->next_type(NULL)->name, param->name);
param->ctx->print(param->ctx, "%s %s = <undefined>", 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, &param->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);
}
+3 -5
View File
@@ -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");
+2 -2
View File
@@ -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 {
+49 -38
View File
@@ -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 <string.h>
#include <stdlib.h>
#include <errno.h>
#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 {
}
else
return ENOMEM;
}
} else {
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;
}
+21 -36
View File
@@ -1,21 +1,6 @@
#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 <stdint.h>
#include "list_head.h"
#define HASH_MIN_SHIFT (8)
@@ -29,12 +14,12 @@
@param key_size hash key size in bytes
@param node uplink to hash multimap table
*/
typedef struct hash_node
struct hash_node
{
list_node node;
char* key;
char *key;
int key_size;
} hash_node;
struct list_node node;
};
/** Hash function prototype
@@ -42,7 +27,7 @@ typedef struct hash_node
@param key_size hash key size in bytes
@return hash value
*/
typedef unsigned int (* _hash_fn)(const char *key, int key_size);
typedef unsigned int (* _hash_fn)(const void *key, int key_size);
/** Compare function prototype
*
@@ -52,7 +37,7 @@ typedef unsigned int (* _hash_fn)(const char *key, int key_size);
*
* @return zero if keys equals each other, othervize 1
*/
typedef int (*_compare_fn)(const char *key1, const char *key2, int size);
typedef int (*_compare_fn)(const void *key1, const void *key2, int size);
/** Hash multimap table descriptor
@@ -63,15 +48,17 @@ typedef int (*_compare_fn)(const char *key1, const char *key2, int size);
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;
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_head;
};
/** Hash table iterator
@@ -79,25 +66,23 @@ typedef struct hash_head {
@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
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);
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);
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, void *key, int key_size);
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);
+2 -2
View File
@@ -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;
-11
View File
@@ -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);
+128 -80
View File
@@ -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 <dlfcn.h>
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);
}
+14 -30
View File
@@ -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_ */
+4 -4
View File
@@ -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");