[K/N] Patch libbacktrace for columns support

This commit is contained in:
Pavel Kunyavskiy
2021-08-06 18:23:31 +03:00
committed by Space
parent 91dd9dc9b0
commit 45317ca221
5 changed files with 36 additions and 21 deletions
@@ -86,7 +86,7 @@ unwind (struct _Unwind_Context *context, void *vdata)
--pc;
if (!bdata->can_alloc)
bdata->ret = bdata->callback (bdata->data, pc, NULL, 0, NULL);
bdata->ret = bdata->callback (bdata->data, pc, NULL, 0, 0, NULL);
else
bdata->ret = backtrace_pcinfo (bdata->state, pc, bdata->callback,
bdata->error_callback, bdata->data);
@@ -567,6 +567,8 @@ struct line
const char *filename;
/* Line number. */
int lineno;
/* Column number */
int column;
/* Index of the object in the original array read from the DWARF
section, before it has been sorted. The index makes it possible
to use Quicksort and maintain stability. */
@@ -596,6 +598,9 @@ struct function
/* If this is an inlined function, the line number of the call
site. */
int caller_lineno;
/* If this is an inlined function, the column of the call
site. */
int caller_column;
/* Map PC ranges to inlined functions. */
struct function_addrs *function_addrs;
size_t function_addrs_count;
@@ -2611,7 +2616,7 @@ build_address_map (struct backtrace_state *state, uintptr_t base_address,
static int
add_line (struct backtrace_state *state, struct dwarf_data *ddata,
uintptr_t pc, const char *filename, int lineno,
uintptr_t pc, const char *filename, int lineno, int column,
backtrace_error_callback error_callback, void *data,
struct line_vector *vec)
{
@@ -2638,6 +2643,7 @@ add_line (struct backtrace_state *state, struct dwarf_data *ddata,
ln->filename = filename;
ln->lineno = lineno;
ln->column = column;
ln->idx = vec->count;
++vec->count;
@@ -3056,6 +3062,7 @@ read_line_program (struct backtrace_state *state, struct dwarf_data *ddata,
const char *reset_filename;
const char *filename;
int lineno;
int column;
address = 0;
op_index = 0;
@@ -3064,6 +3071,7 @@ read_line_program (struct backtrace_state *state, struct dwarf_data *ddata,
else
reset_filename = "";
filename = reset_filename;
column = 0;
lineno = 1;
while (line_buf->left > 0)
{
@@ -3081,7 +3089,7 @@ read_line_program (struct backtrace_state *state, struct dwarf_data *ddata,
/ hdr->max_ops_per_insn);
op_index = (op_index + advance) % hdr->max_ops_per_insn;
lineno += hdr->line_base + (int) (op % hdr->line_range);
add_line (state, ddata, address, filename, lineno,
add_line (state, ddata, address, filename, lineno, column,
line_buf->error_callback, line_buf->data, vec);
}
else if (op == DW_LNS_extended_op)
@@ -3169,7 +3177,7 @@ read_line_program (struct backtrace_state *state, struct dwarf_data *ddata,
switch (op)
{
case DW_LNS_copy:
add_line (state, ddata, address, filename, lineno,
add_line (state, ddata, address, filename, lineno, column,
line_buf->error_callback, line_buf->data, vec);
break;
case DW_LNS_advance_pc:
@@ -3202,7 +3210,7 @@ read_line_program (struct backtrace_state *state, struct dwarf_data *ddata,
}
break;
case DW_LNS_set_column:
read_uleb128 (line_buf);
column = read_uleb128 (line_buf);
break;
case DW_LNS_negate_stmt:
break;
@@ -3642,6 +3650,10 @@ read_function_entry (struct backtrace_state *state, struct dwarf_data *ddata,
if (val.encoding == ATTR_VAL_UINT)
function->caller_lineno = val.u.uint;
break;
case DW_AT_call_column:
if (val.encoding == ATTR_VAL_UINT)
function->caller_column = val.u.uint;
break;
case DW_AT_abstract_origin:
case DW_AT_specification:
@@ -3884,7 +3896,7 @@ read_function_info (struct backtrace_state *state, struct dwarf_data *ddata,
static int
report_inlined_functions (uintptr_t pc, struct function *function,
backtrace_full_callback callback, void *data,
const char **filename, int *lineno)
const char **filename, int *lineno, int *column)
{
struct function_addrs *p;
struct function_addrs *match;
@@ -3937,12 +3949,12 @@ report_inlined_functions (uintptr_t pc, struct function *function,
/* Report any calls inlined into this one. */
ret = report_inlined_functions (pc, inlined, callback, data,
filename, lineno);
filename, lineno, column);
if (ret != 0)
return ret;
/* Report this inlined call. */
ret = callback (data, pc, *filename, *lineno, inlined->name);
ret = callback (data, pc, *filename, *lineno, *column, inlined->name);
if (ret != 0)
return ret;
@@ -3950,6 +3962,7 @@ report_inlined_functions (uintptr_t pc, struct function *function,
it the appropriate filename and line number. */
*filename = inlined->caller_filename;
*lineno = inlined->caller_lineno;
*column = inlined->caller_column;
return 0;
}
@@ -3976,6 +3989,7 @@ dwarf_lookup_pc (struct backtrace_state *state, struct dwarf_data *ddata,
struct function *function;
const char *filename;
int lineno;
int column;
int ret;
*found = 1;
@@ -4117,7 +4131,7 @@ dwarf_lookup_pc (struct backtrace_state *state, struct dwarf_data *ddata,
if (new_data)
return dwarf_lookup_pc (state, ddata, pc, callback, error_callback,
data, found);
return callback (data, pc, NULL, 0, NULL);
return callback (data, pc, NULL, 0, 0, NULL);
}
/* Search for PC within this unit. */
@@ -4164,13 +4178,13 @@ dwarf_lookup_pc (struct backtrace_state *state, struct dwarf_data *ddata,
entry->u->abs_filename = filename;
}
return callback (data, pc, entry->u->abs_filename, 0, NULL);
return callback (data, pc, entry->u->abs_filename, 0, 0, NULL);
}
/* Search for function name within this unit. */
if (entry->u->function_addrs_count == 0)
return callback (data, pc, ln->filename, ln->lineno, NULL);
return callback (data, pc, ln->filename, ln->lineno, ln->column, NULL);
p = ((struct function_addrs *)
bsearch (&pc, entry->u->function_addrs,
@@ -4178,7 +4192,7 @@ dwarf_lookup_pc (struct backtrace_state *state, struct dwarf_data *ddata,
sizeof (struct function_addrs),
function_addrs_search));
if (p == NULL)
return callback (data, pc, ln->filename, ln->lineno, NULL);
return callback (data, pc, ln->filename, ln->lineno, ln->column, NULL);
/* Here pc >= p->low && pc < (p + 1)->low. The function_addrs are
sorted by low, so if pc > p->low we are at the end of a range of
@@ -4202,19 +4216,20 @@ dwarf_lookup_pc (struct backtrace_state *state, struct dwarf_data *ddata,
--p;
}
if (fmatch == NULL)
return callback (data, pc, ln->filename, ln->lineno, NULL);
return callback (data, pc, ln->filename, ln->lineno, ln->column, NULL);
function = fmatch->function;
filename = ln->filename;
lineno = ln->lineno;
column = ln->column;
ret = report_inlined_functions (pc, function, callback, data,
&filename, &lineno);
&filename, &lineno, &column);
if (ret != 0)
return ret;
return callback (data, pc, filename, lineno, function->name);
return callback (data, pc, filename, lineno, column, function->name);
}
@@ -4264,7 +4279,7 @@ dwarf_fileline (struct backtrace_state *state, uintptr_t pc,
/* FIXME: See if any libraries have been dlopen'ed. */
return callback (data, pc, NULL, 0, NULL);
return callback (data, pc, NULL, 0, 0, NULL);
}
/* Initialize our data structures from the DWARF debug info for a
@@ -330,7 +330,7 @@ backtrace_syminfo_to_full_callback (void *data, uintptr_t pc,
{
struct backtrace_call_full *bdata = (struct backtrace_call_full *) data;
bdata->ret = bdata->full_callback (bdata->full_data, pc, NULL, 0, symname);
bdata->ret = bdata->full_callback (bdata->full_data, pc, NULL, 0, 0, symname);
}
/* An error callback that corresponds to
@@ -98,7 +98,7 @@ extern struct backtrace_state *backtrace_create_state (
invalid after this function returns. */
typedef int (*backtrace_full_callback) (void *data, uintptr_t pc,
const char *filename, int lineno,
const char *filename, int lineno, int column,
const char *function);
/* Get a full stack backtrace. SKIP is the number of frames to skip;
@@ -50,16 +50,16 @@ struct print_data
/* Print one level of a backtrace. */
static int
print_callback (void *data, uintptr_t pc, const char *filename, int lineno,
print_callback (void *data, uintptr_t pc, const char *filename, int lineno, int column,
const char *function)
{
struct print_data *pdata = (struct print_data *) data;
fprintf (pdata->f, "0x%lx %s\n\t%s:%d\n",
fprintf (pdata->f, "0x%lx %s\n\t%s:%d:%d\n",
(unsigned long) pc,
function == NULL ? "???" : function,
filename == NULL ? "???" : filename,
lineno);
lineno, column);
return 0;
}