Skip to content

Commit 95e8e96

Browse files
libbacktrace: handle pc == low correctly
* dwarf.c (report_inlined_functions): Handle PC == -1 and PC == p->low. (dwarf_lookup_pc): Likewise.
1 parent c8a81d4 commit 95e8e96

File tree

1 file changed

+27
-11
lines changed

1 file changed

+27
-11
lines changed

dwarf.c

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3891,6 +3891,11 @@ report_inlined_functions (uintptr_t pc, struct function *function,
38913891
if (function->function_addrs_count == 0)
38923892
return 0;
38933893

3894+
/* Our search isn't safe if pc == -1, as that is the sentinel
3895+
value. */
3896+
if (pc + 1 == 0)
3897+
return 0;
3898+
38943899
p = ((struct function_addrs *)
38953900
bsearch (&pc, function->function_addrs,
38963901
function->function_addrs_count,
@@ -3900,9 +3905,12 @@ report_inlined_functions (uintptr_t pc, struct function *function,
39003905
return 0;
39013906

39023907
/* Here pc >= p->low && pc < (p + 1)->low. The function_addrs are
3903-
sorted by low, so we are at the end of a range of function_addrs
3904-
with the same low alue. Walk backward and use the first range
3905-
that includes pc. */
3908+
sorted by low, so if pc > p->low we are at the end of a range of
3909+
function_addrs with the same low value. If pc == p->low walk
3910+
forward to the end of the range with that low value. Then walk
3911+
backward and use the first range that includes pc. */
3912+
while (pc == (p + 1)->low)
3913+
++p;
39063914
match = NULL;
39073915
while (1)
39083916
{
@@ -3969,8 +3977,10 @@ dwarf_lookup_pc (struct backtrace_state *state, struct dwarf_data *ddata,
39693977

39703978
*found = 1;
39713979

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

39843994
/* Here pc >= entry->low && pc < (entry + 1)->low. The unit_addrs
3985-
are sorted by low, so we are at the end of a range of unit_addrs
3986-
with the same low value. Walk backward and use the first range
3987-
that includes pc. */
3995+
are sorted by low, so if pc > p->low we are at the end of a range
3996+
of unit_addrs with the same low value. If pc == p->low walk
3997+
forward to the end of the range with that low value. Then walk
3998+
backward and use the first range that includes pc. */
3999+
while (pc == (entry + 1)->low)
4000+
++entry;
39884001
found_entry = 0;
39894002
while (1)
39904003
{
@@ -4165,9 +4178,12 @@ dwarf_lookup_pc (struct backtrace_state *state, struct dwarf_data *ddata,
41654178
return callback (data, pc, ln->filename, ln->lineno, NULL);
41664179

41674180
/* Here pc >= p->low && pc < (p + 1)->low. The function_addrs are
4168-
sorted by low, so we are at the end of a range of function_addrs
4169-
with the same low alue. Walk backward and use the first range
4170-
that includes pc. */
4181+
sorted by low, so if pc > p->low we are at the end of a range of
4182+
function_addrs with the same low value. If pc == p->low walk
4183+
forward to the end of the range with that low value. Then walk
4184+
backward and use the first range that includes pc. */
4185+
while (pc == (p + 1)->low)
4186+
++p;
41714187
fmatch = NULL;
41724188
while (1)
41734189
{

0 commit comments

Comments
 (0)