Skip to content

Commit

Permalink
libbacktrace: handle pc == low correctly
Browse files Browse the repository at this point in the history
	* dwarf.c (report_inlined_functions): Handle PC == -1 and PC ==
	p->low.
	(dwarf_lookup_pc): Likewise.
  • Loading branch information
ianlancetaylor committed Sep 28, 2020
1 parent c8a81d4 commit 95e8e96
Showing 1 changed file with 27 additions and 11 deletions.
38 changes: 27 additions & 11 deletions dwarf.c
Original file line number Diff line number Diff line change
Expand Up @@ -3891,6 +3891,11 @@ report_inlined_functions (uintptr_t pc, struct function *function,
if (function->function_addrs_count == 0)
return 0;

/* Our search isn't safe if pc == -1, as that is the sentinel
value. */
if (pc + 1 == 0)
return 0;

p = ((struct function_addrs *)
bsearch (&pc, function->function_addrs,
function->function_addrs_count,
Expand All @@ -3900,9 +3905,12 @@ report_inlined_functions (uintptr_t pc, struct function *function,
return 0;

/* Here pc >= p->low && pc < (p + 1)->low. The function_addrs are
sorted by low, so we are at the end of a range of function_addrs
with the same low alue. Walk backward and use the first range
that includes pc. */
sorted by low, so if pc > p->low we are at the end of a range of
function_addrs with the same low value. If pc == p->low walk
forward to the end of the range with that low value. Then walk
backward and use the first range that includes pc. */
while (pc == (p + 1)->low)
++p;
match = NULL;
while (1)
{
Expand Down Expand Up @@ -3969,8 +3977,10 @@ dwarf_lookup_pc (struct backtrace_state *state, struct dwarf_data *ddata,

*found = 1;

/* Find an address range that includes PC. */
entry = (ddata->addrs_count == 0
/* Find an address range that includes PC. Our search isn't safe if
PC == -1, as we use that as a sentinel value, so skip the search
in that case. */
entry = (ddata->addrs_count == 0 || pc + 1 == 0
? NULL
: bsearch (&pc, ddata->addrs, ddata->addrs_count,
sizeof (struct unit_addrs), unit_addrs_search));
Expand All @@ -3982,9 +3992,12 @@ dwarf_lookup_pc (struct backtrace_state *state, struct dwarf_data *ddata,
}

/* Here pc >= entry->low && pc < (entry + 1)->low. The unit_addrs
are sorted by low, so we are at the end of a range of unit_addrs
with the same low value. Walk backward and use the first range
that includes pc. */
are sorted by low, so if pc > p->low we are at the end of a range
of unit_addrs with the same low value. If pc == p->low walk
forward to the end of the range with that low value. Then walk
backward and use the first range that includes pc. */
while (pc == (entry + 1)->low)
++entry;
found_entry = 0;
while (1)
{
Expand Down Expand Up @@ -4165,9 +4178,12 @@ dwarf_lookup_pc (struct backtrace_state *state, struct dwarf_data *ddata,
return callback (data, pc, ln->filename, ln->lineno, NULL);

/* Here pc >= p->low && pc < (p + 1)->low. The function_addrs are
sorted by low, so we are at the end of a range of function_addrs
with the same low alue. Walk backward and use the first range
that includes pc. */
sorted by low, so if pc > p->low we are at the end of a range of
function_addrs with the same low value. If pc == p->low walk
forward to the end of the range with that low value. Then walk
backward and use the first range that includes pc. */
while (pc == (p + 1)->low)
++p;
fmatch = NULL;
while (1)
{
Expand Down

0 comments on commit 95e8e96

Please sign in to comment.