summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Diamand <ldiamand@roku.com>2023-05-12 20:11:45 +0100
committerMark Wielaard <mark@klomp.org>2023-05-12 21:56:54 +0200
commit0066e704b9ed21ac4b2070dfdef1611515b68d29 (patch)
tree29b191d045b780e622f9feb46dac917dbd5717e0
parentd16628bb7dc39a020e555e16bf56374fdac84e42 (diff)
downloadelfutils-master.tar.gz
report_r_debug: handle `-z separate-code' and find more modulesHEADmaster
Looking at some cores in eu-stack, I found that they were not being backtraced. This was because elfutils had not found some modules (e.g. libc-2.22.so) in report_r_debug. That is because it has a limit on the number of link map entries it will look at, to avoid loops in corrupted core files. The example I found had: - 36 elements - 109 iterations See also discussion here: https://sourceware.org/pipermail/elfutils-devel/2023q2/006149.html Signed-off-by: Luke Diamand <ldiamand@roku.com>
-rw-r--r--libdwfl/link_map.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/libdwfl/link_map.c b/libdwfl/link_map.c
index 06d85eb6..76f23354 100644
--- a/libdwfl/link_map.c
+++ b/libdwfl/link_map.c
@@ -331,11 +331,17 @@ report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata,
int result = 0;
/* There can't be more elements in the link_map list than there are
- segments. DWFL->lookup_elts is probably twice that number, so it
- is certainly above the upper bound. If we iterate too many times,
- there must be a loop in the pointers due to link_map clobberation. */
+ segments. A segment is created for each PT_LOAD and there can be
+ up to 5 per module (-z separate-code, tends to create four LOAD
+ segments, gold has -z text-unlikely-segment, which might result
+ in creating that number of load segments) DWFL->lookup_elts is
+ probably twice the number of modules, so that multiplied by max
+ PT_LOADs is certainly above the upper bound. If we iterate too
+ many times, there must be a loop in the pointers due to link_map
+ clobberation. */
+#define MAX_PT_LOAD 5
size_t iterations = 0;
- while (next != 0 && ++iterations < dwfl->lookup_elts)
+ while (next != 0 && ++iterations < dwfl->lookup_elts * MAX_PT_LOAD)
{
if (read_addrs (&memory_closure, elfclass, elfdata,
&buffer, &buffer_available, next, &read_vaddr,