libbacktrace: sometimes read debug sections individually
libbacktrace/ * elf.c (elf_add): If debug sections are very large or far apart, read them individually rather than as a single view.
This commit is contained in:
parent
261356844a
commit
31ae7b863a
@ -1,3 +1,8 @@
|
|||||||
|
2020-05-09 Ian Lance Taylor <iant@golang.org>
|
||||||
|
|
||||||
|
* elf.c (elf_add): If debug sections are very large or far apart,
|
||||||
|
read them individually rather than as a single view.
|
||||||
|
|
||||||
2020-05-08 Ian Lance Taylor <iant@golang.org>
|
2020-05-08 Ian Lance Taylor <iant@golang.org>
|
||||||
|
|
||||||
* fileline.c (sysctl_exec_name): New static function.
|
* fileline.c (sysctl_exec_name): New static function.
|
||||||
|
@ -2659,10 +2659,13 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
|
|||||||
uint32_t debugaltlink_buildid_size;
|
uint32_t debugaltlink_buildid_size;
|
||||||
off_t min_offset;
|
off_t min_offset;
|
||||||
off_t max_offset;
|
off_t max_offset;
|
||||||
|
off_t debug_size;
|
||||||
struct backtrace_view debug_view;
|
struct backtrace_view debug_view;
|
||||||
int debug_view_valid;
|
int debug_view_valid;
|
||||||
unsigned int using_debug_view;
|
unsigned int using_debug_view;
|
||||||
uint16_t *zdebug_table;
|
uint16_t *zdebug_table;
|
||||||
|
struct backtrace_view split_debug_view[DEBUG_MAX];
|
||||||
|
unsigned char split_debug_view_valid[DEBUG_MAX];
|
||||||
struct elf_ppc64_opd_data opd_data, *opd;
|
struct elf_ppc64_opd_data opd_data, *opd;
|
||||||
struct dwarf_sections dwarf_sections;
|
struct dwarf_sections dwarf_sections;
|
||||||
|
|
||||||
@ -2687,6 +2690,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
|
|||||||
debugaltlink_buildid_data = NULL;
|
debugaltlink_buildid_data = NULL;
|
||||||
debugaltlink_buildid_size = 0;
|
debugaltlink_buildid_size = 0;
|
||||||
debug_view_valid = 0;
|
debug_view_valid = 0;
|
||||||
|
memset (&split_debug_view_valid[0], 0, sizeof split_debug_view_valid);
|
||||||
opd = NULL;
|
opd = NULL;
|
||||||
|
|
||||||
if (!backtrace_get_view (state, descriptor, 0, sizeof ehdr, error_callback,
|
if (!backtrace_get_view (state, descriptor, 0, sizeof ehdr, error_callback,
|
||||||
@ -3131,6 +3135,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
|
|||||||
|
|
||||||
min_offset = 0;
|
min_offset = 0;
|
||||||
max_offset = 0;
|
max_offset = 0;
|
||||||
|
debug_size = 0;
|
||||||
for (i = 0; i < (int) DEBUG_MAX; ++i)
|
for (i = 0; i < (int) DEBUG_MAX; ++i)
|
||||||
{
|
{
|
||||||
off_t end;
|
off_t end;
|
||||||
@ -3142,6 +3147,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
|
|||||||
end = sections[i].offset + sections[i].size;
|
end = sections[i].offset + sections[i].size;
|
||||||
if (end > max_offset)
|
if (end > max_offset)
|
||||||
max_offset = end;
|
max_offset = end;
|
||||||
|
debug_size += sections[i].size;
|
||||||
}
|
}
|
||||||
if (zsections[i].size != 0)
|
if (zsections[i].size != 0)
|
||||||
{
|
{
|
||||||
@ -3150,6 +3156,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
|
|||||||
end = zsections[i].offset + zsections[i].size;
|
end = zsections[i].offset + zsections[i].size;
|
||||||
if (end > max_offset)
|
if (end > max_offset)
|
||||||
max_offset = end;
|
max_offset = end;
|
||||||
|
debug_size += zsections[i].size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (min_offset == 0 || max_offset == 0)
|
if (min_offset == 0 || max_offset == 0)
|
||||||
@ -3159,11 +3166,45 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!backtrace_get_view (state, descriptor, min_offset,
|
/* If the total debug section size is large, assume that there are
|
||||||
max_offset - min_offset,
|
gaps between the sections, and read them individually. */
|
||||||
error_callback, data, &debug_view))
|
|
||||||
goto fail;
|
if (max_offset - min_offset < 0x20000000
|
||||||
debug_view_valid = 1;
|
|| max_offset - min_offset < debug_size + 0x10000)
|
||||||
|
{
|
||||||
|
if (!backtrace_get_view (state, descriptor, min_offset,
|
||||||
|
max_offset - min_offset,
|
||||||
|
error_callback, data, &debug_view))
|
||||||
|
goto fail;
|
||||||
|
debug_view_valid = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memset (&split_debug_view[0], 0, sizeof split_debug_view);
|
||||||
|
for (i = 0; i < (int) DEBUG_MAX; ++i)
|
||||||
|
{
|
||||||
|
struct debug_section_info *dsec;
|
||||||
|
|
||||||
|
if (sections[i].size != 0)
|
||||||
|
dsec = §ions[i];
|
||||||
|
else if (zsections[i].size != 0)
|
||||||
|
dsec = &zsections[i];
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!backtrace_get_view (state, descriptor, dsec->offset, dsec->size,
|
||||||
|
error_callback, data, &split_debug_view[i]))
|
||||||
|
goto fail;
|
||||||
|
split_debug_view_valid[i] = 1;
|
||||||
|
|
||||||
|
if (sections[i].size != 0)
|
||||||
|
sections[i].data = ((const unsigned char *)
|
||||||
|
split_debug_view[i].data);
|
||||||
|
else
|
||||||
|
zsections[i].data = ((const unsigned char *)
|
||||||
|
split_debug_view[i].data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* We've read all we need from the executable. */
|
/* We've read all we need from the executable. */
|
||||||
if (!backtrace_close (descriptor, error_callback, data))
|
if (!backtrace_close (descriptor, error_callback, data))
|
||||||
@ -3171,22 +3212,25 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
|
|||||||
descriptor = -1;
|
descriptor = -1;
|
||||||
|
|
||||||
using_debug_view = 0;
|
using_debug_view = 0;
|
||||||
for (i = 0; i < (int) DEBUG_MAX; ++i)
|
if (debug_view_valid)
|
||||||
{
|
{
|
||||||
if (sections[i].size == 0)
|
for (i = 0; i < (int) DEBUG_MAX; ++i)
|
||||||
sections[i].data = NULL;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
sections[i].data = ((const unsigned char *) debug_view.data
|
if (sections[i].size == 0)
|
||||||
+ (sections[i].offset - min_offset));
|
sections[i].data = NULL;
|
||||||
++using_debug_view;
|
else
|
||||||
}
|
{
|
||||||
|
sections[i].data = ((const unsigned char *) debug_view.data
|
||||||
|
+ (sections[i].offset - min_offset));
|
||||||
|
++using_debug_view;
|
||||||
|
}
|
||||||
|
|
||||||
if (zsections[i].size == 0)
|
if (zsections[i].size == 0)
|
||||||
zsections[i].data = NULL;
|
zsections[i].data = NULL;
|
||||||
else
|
else
|
||||||
zsections[i].data = ((const unsigned char *) debug_view.data
|
zsections[i].data = ((const unsigned char *) debug_view.data
|
||||||
+ (zsections[i].offset - min_offset));
|
+ (zsections[i].offset - min_offset));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Uncompress the old format (--compress-debug-sections=zlib-gnu). */
|
/* Uncompress the old format (--compress-debug-sections=zlib-gnu). */
|
||||||
@ -3218,6 +3262,13 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
|
|||||||
sections[i].data = uncompressed_data;
|
sections[i].data = uncompressed_data;
|
||||||
sections[i].size = uncompressed_size;
|
sections[i].size = uncompressed_size;
|
||||||
sections[i].compressed = 0;
|
sections[i].compressed = 0;
|
||||||
|
|
||||||
|
if (split_debug_view_valid[i])
|
||||||
|
{
|
||||||
|
backtrace_release_view (state, &split_debug_view[i],
|
||||||
|
error_callback, data);
|
||||||
|
split_debug_view_valid[i] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3250,7 +3301,14 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
|
|||||||
sections[i].size = uncompressed_size;
|
sections[i].size = uncompressed_size;
|
||||||
sections[i].compressed = 0;
|
sections[i].compressed = 0;
|
||||||
|
|
||||||
--using_debug_view;
|
if (debug_view_valid)
|
||||||
|
--using_debug_view;
|
||||||
|
else if (split_debug_view_valid[i])
|
||||||
|
{
|
||||||
|
backtrace_release_view (state, &split_debug_view[i],
|
||||||
|
error_callback, data);
|
||||||
|
split_debug_view_valid[i] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zdebug_table != NULL)
|
if (zdebug_table != NULL)
|
||||||
@ -3297,6 +3355,12 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor,
|
|||||||
backtrace_release_view (state, &buildid_view, error_callback, data);
|
backtrace_release_view (state, &buildid_view, error_callback, data);
|
||||||
if (debug_view_valid)
|
if (debug_view_valid)
|
||||||
backtrace_release_view (state, &debug_view, error_callback, data);
|
backtrace_release_view (state, &debug_view, error_callback, data);
|
||||||
|
for (i = 0; i < (int) DEBUG_MAX; ++i)
|
||||||
|
{
|
||||||
|
if (split_debug_view_valid[i])
|
||||||
|
backtrace_release_view (state, &split_debug_view[i],
|
||||||
|
error_callback, data);
|
||||||
|
}
|
||||||
if (opd)
|
if (opd)
|
||||||
backtrace_release_view (state, &opd->view, error_callback, data);
|
backtrace_release_view (state, &opd->view, error_callback, data);
|
||||||
if (descriptor != -1)
|
if (descriptor != -1)
|
||||||
|
Loading…
Reference in New Issue
Block a user