| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Calls to the gettext _() macro in hotpaths cause many runtime lookups
of the same translation strings. This patch introduces macro __()
which caches the result of _() at each call site where __() is used.
When a cached translation string is used as the format string for
fprintf, the compiler might raise a -Wformat-nonliteral warning.
To avoid this, the -Wformat-nonliteral warning is suppressed using _Pragma
around affected fprintf calls, using IGNORE_FMT_NONLITERAL_BEGIN and
_END wrappers.
To avoid suppressing -Wformat-nonliteral across every printf-style
function using _(), __() and IGNORE_FMT_NONLITERAL_* are mostly used
within hotpath loops where caching makes a signficant difference.
Runtime improvements of up to 13% faster have been observed with this patch
applied.
Signed-off-by: Aaron Merey <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Implement concurrent execution of print_debug_* functions during handling
of -w, --debug-dump using libthread.a.
A new `-C, --concurrency=NUM` command line option controls the maximum
number of threads that may be used. This value defaults to the number of CPUs.
Job output is buffered and printed in the order that jobs were added to
the queue. This helps preserve the existing order of stdout output.
* src/readelf.c (default_concurrency): Function estimating the
maximum number of threads.
(parse_opt): Handle -C, --concurrency=NUM.
(do_job): Entry point function for threads.
(schedule_job): If thread safety is enabled, add job to the
job queue. Otherwise just run the job from the main thread.
(print_debug): Pass print_debug_* function pointers and
args to schedule_job. Also call run_jobs if thread safety
is enabled.
Signed-off-by: Aaron Merey <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Safely handle stdout output during concurrent calls to print_debug_*
functions.
For any print_debug_* function and any function that could be called
from print_debug_* which also prints to stdout: add a FILE * argument
and replace all printf, puts, putchar with fprintf. All printing
to stdout will now be written to this FILE instead.
The FILE * is an interface to a per-thread dynamically-sized buffer.
libthread.a manages the allocation, printing and deallocation of
these buffers.
Signed-off-by: Aaron Merey <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add new internal static library libthread.a that provides infrastructure
for eu-* tools to run functions concurrently using pthreads.
threadlib.c manages per-job threads as well as per-job buffers for stdout
output. Output for each job is printed to stdout in the order that the
jobs were added to the job queue. This helps preserve the order of
output when parallelization is added to an eu-* tool.
threadlib.h declares functions add_job and run_jobs. Jobs are added to
a threadlib.c internal job queue using add_job. run_jobs concurrently
executes jobs in parallel.
eu-readelf now links against libthread.a when elfutils is configured
with --enable-thread-safety.
* src/Makefile.am: libthread.a is compiled and and linked with
readelf when USE_LOCKS is defined.
* src/threadlib.c: New file. Manages job creation, concurrent
execution and output handling.
* src/threadlib.h: New file. Declares functions add_job and
run_jobs.
Signed-off-by: Aaron Merey <[email protected]>
|
|
|
|
|
|
|
|
|
| |
If some section doesn't match between the stripped and unstripped file
we invent a new one. Make sure to also update the shnum value.
* src/unstrip.c (copy_elided_sections): Update unstripped_shnum.
Signed-off-by: Mark Wielaard <[email protected]>
|
|
|
|
|
|
|
|
|
|
| |
If there is only section zero that shouldn't count. Then we would
still try to work on an empty set of sections and give an obscure
error later.
* src/unstrip.c (copy_elided_sections): Check stripped_shnum <= 1.
Signed-off-by: Mark Wielaard <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
handle_dynamic_symtab can attempt to read symbol and version data from
file offset of 0 or address of 0 if the associated DT_ tags aren't found.
Fix this by only reading symbol and version data when non-zero file
offsets/addresses have been found.
https://sourceware.org/bugzilla/show_bug.cgi?id=32864
Suggested-by: Constantine Bytensky <[email protected]>
Signed-off-by: Aaron Merey <[email protected]>
|
|
|
|
|
|
|
|
| |
* src/unstrip.c (copy_elided_sections): Check elf_getdata result
for symtab and strtab sections.
Suggested-by: Anton Moryakov <[email protected]>
Signed-off-by: Mark Wielaard <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
handle_core_item calls gelf_getehdr for each item without checking if
the call succeeds. It should always succeed because process_elf_file
already checked gelf_getehdr returned a valid Ehdr before passing it
to handle_notes. Just pass the Ehdr down a couple more function calls.
* readelf.c (handle_core_item): Take const Gelf_Ehdr and use it.
(handle_core_items): Take const Gelf_Ehdr and pass it to
handle_core_item.
(handle_core_note): Take const Gelf_Ehdr and pass it to
handle_core_items.
(handle_notes_data): Pass ehdr to handle_core_note.
Signed-off-by: Mark Wielaard <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
| |
When elf_getahdr returns NULL we shouldn't even try to handle the ar
header, but immediately go to the next entry.
* src/ar.c (do_oper_extract): If elf_getahdr goto next.
(do_oper_delete): Likewise.
(do_oper_insert): Likewise.
Suggested-by: Anton Moryakov <[email protected]>
Signed-off-by: Mark Wielaard <[email protected]>
|
|
|
|
| |
Signed-off-by: Aaron Merey <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Remove the code from src/stacktrace.c that is now covered by
libdwfl_stacktrace/dwflst_perf_frame.c and
dwflst_perf_sample_getframes.
* src/stacktrace.c (show_memory_reads): Remove this verbose option as
the relevant code is inside libdwfl_stacktrace now.
(struct __sample_arg): Remove, handled by
libdwfl_stacktrace/dwflst_perf_frame.c.
(sample_next_thread): Ditto.
(sample_getthread): Ditto.
(copy_word_64): Ditto.
(copy_word_32): Ditto.
(elf_memory_read): Ditto.
(sample_memory_read): Ditto.
(sample_set_initial_registers): Ditto.
(sample_detach): Ditto.
(sample_thread_callbacks): Ditto.
(sysprof_find_dwfl): Now also return the Elf* so that it can be
passed to dwflst_perf_sample_getframes. Don't create sample_arg. Do
record sp in sui->last_sp. Don't dwfl_attach_state,
dwflst_perf_sample_getframes handles that now.
(sysprof_unwind_cb): Adapt to sysprof_find_dwfl changes,
now invoke dwflst_perf_sample_getframes instead of
dwfl_getthread_frames.
(parse_opt): Remove show_memory_reads.
(main): Remove show_memory_reads.
Signed-off-by: Serhei Makarov <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Initial minimal change to ensure dwflst_tracker_find_pid is
tested. For now, we keep the additional dwfltab implementation in
stacktrace.c, since it's being used to track statistics.
In future follow-ups, it will be good to switch to storing
eu-stacktrace statistics e.g. in dwfl->process->callbacks_arg. This
requires some additional design to keep the statistics from being lost
when a pid is reused and the corresponding processtracker table entry
is replaced.
* src/stacktrace.c (sysprof_init_dwfl): New function.
(sysprof_find_dwfl): Rename the existing sysprof_init_dwfl.
Also use dwflst_tracker_find_pid with callback.
(sysprof_unwind_cb): Rename the existing sysprof_init_dwfl.
Signed-off-by: Serhei Makarov <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
| |
* src/Makefile.am (AM_CPPFLAGS): Include headers from
../libdwfl_stacktrace.
* src/stacktrace.c (tracker): New global variable.
(sample_callbacks): Use dwflst_tracker_linux_proc_find_elf for
caching.
(sysprof_init_dwfl): Use dwflst_tracker_dwfl_begin.
(main): Initialize and clean up tracker.
Signed-off-by: Serhei Makarov <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Dummy commit to show how the sample_set_initial_registers callback in
eu-stacktrace would use the proper libebl
ebl_set_initial_registers_sample function (if it were public).
* src/Makefile.am (stacktrace_LDADD): Add libebl.
* src/stacktrace.c (sample_registers_cb): New function,
though identical to pid_thread_state_registers_cb.
(sample_set_initial_registers): (XXX Invoke
ebl_set_initial_registers_sample instead of containing
platform-specific code directly. This is now commented out.
Patch12 in the series replaces with code in
libdwfl_stacktrace/dwflst_perf_frame.c.)
Signed-off-by: Serhei Makarov <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When printing section headers, also include a key to what each flag
is at the end of the section header output.
* src/readelf.c (print_flag_info): New function.
(print_shdr): Call print_flag_info.
* tests/run-copyadd-sections.sh: Fix .extra grep by escaping \.
* tests/run-large-elf-file.sh: Likewise.
* tests/test-copymany-subr.sh: Likewise.
* tests/run-readelf-z.sh: Add Key to Flags to expected output.
* tests/run-retain.sh: Likewise.
* tests/run-strip-remove-keep.sh: Likewise.
https://sourceware.org/bugzilla/show_bug.cgi?id=29571
Signed-off-by: Samuel Zeter <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add a testfile using GCC 15 (experimental).
* libdw/dwarf.h: Add DW_LNAME_lo_user and DW_LNAME_hi_user.
* src/readelf.c (dwarf_lname_string): New function.
(dwarf_lname_name): Likewise.
(attr_callback): Handle DW_AT_language_name by calling
dwarf_lname_name.
* run-readelf-lnames.sh: New test.
* testfile-lnames.bz2: New testfile.
* tests/Makefile.am (TESTS): Add run-readelf-lnames.sh.
(EXTRA_DIST): Add run-readelf-lnames.sh and
testfile-lnames.bz2.
Signed-off-by: Mark Wielaard <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
elf_scnshndx is a elfutils extension to libelf that given a SHT_SYMTAB
section returns the index to the corresponding SHT_SYMTAB_SHNDX
section, if it exists. This is needed when there are more than 64K
sections and there are symbols that have to refer to a section with an
index larger than 64K, because the Elf Sym st_shndx field is only
16 bits.
This was implemented by adding an shndx_index field to the Elf_Scn
struct which is updated when reading the section headers. This takes
up space in every section and is hard to proof correct. In the case of
using ELF_C_READ_MMAP the shndx_index field was only updated when the
shdrs needed to be converted from file to memory order.
And the two places were this function was used in readelf.c and
elf-print-reloc-syms.c the wrong section was used to lookup the
extended index table. There were also no tests for this functionality.
Replace the elf_scnshndx implementation with a simpler lookup over all
sections. This sounds inefficient, but in practice the
SHT_SYMTAB_SHNDX section is the next section after the SHT_SYMTAB
section. elf_scnshndx only needs to be called when there are more than
SHN_LORESERVE (0xff00) sections. And normally a user would just lookup
the SHT_SYMTAB and SHT_SYMTAB_SHNDX sections at the same time (which
is what readelf does when showing the symbol table, as does nm,
objcopy and libdwfl).
Add a testfile manyfuncs.c that when compiled contains 64K symbols and
sections. Make sure to use -fasynchronous-unwind-tables so there is at
least one relocatable section that uses all function symbols (e.g. on
arm32 where there is no .eh_frame by default). This can then be used
to verify the readelf --relocs support. Add another test,
test-manyfuncs that explicitly goes through the symbol table and
associated extended index table and verify each function symbol
matches the section name.
There are For riscv there are local, notype, symbols at the start of each
executable section which relocations refer to instead of the section
symbol. Since all these local symbols are called ".L0" this isn't very
useful, so print the section name instead. For powerpc ELFv1 all
function symbols go through the .opd section. Allow this in the new
test-manyfuncs test.
* libelf/elf32_getshdr.c (load_shdr_wrlock): Remove handling
of shndx_index.
* libelf/elf_begin.c (file_read_elf): Likewise.
* libelf/elf_scnshndx.c (elf_scnshndx): Rewritten.
* libelf/libelf.h (elf_scnshndx): Added full documentation.
* libelf/libelfP.h (struct Elf_Scn): Remove shndx_index field.
(__elf_scnshndx_internal): Removed.
* src/readelf.c (handle_relocs_rel): Use symscn in call to
elf_scnshndx. Print section name for local start section label.
(handle_relocs_rela): Likewise.
* tests/Makefile.am (check_PROGRAMS): Add test-manyfuncs.
(manyfuncs.o): New target.
(check-local): New target, depends on manyfuncs.o.
(TESTS): Add run-readelf-r-manyfuncs.sh and
run-test-manyfuncs.sh.
(EXTRA_DIST): Add run-readelf-r-manyfuncs.sh,
run-test-manyfuncs.sh and manyfuncs.c.
(test_manyfuncs_LDADD): New variable.
(EXTRA_test_manyfuncs_DEPENDENCIES): New variable.
(CLEANFILES): Add manyfuncs.o.
* tests/elf-print-reloc-syms.c (print_reloc_symnames):
Use symscn in call to elf_scnshndx.
* tests/manyfuncs.c: New test file to generate 64K symbols and
sections.
* tests/run-readelf-r-manyfuncs.sh: New test wrapper.
* tests/run-test-manyfuncs.sh: Likewise.
* tests/test-manyfuncs.c: New test.
Signed-off-by: Mark Wielaard <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
| |
All other print_debug_* functions use section_name (ebl, shdr) to get
the current section name. Be consistent and use the same method in
print_debug_frame_section to make static analyzers happy who might
think elf_strptr can return NULL in this case.
* src/readelf.c (print_debug_frame_section): Use section_name
instead of elf_strptr to get the section name.
Signed-off-by: Mark Wielaard <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Report of the static analyzer:
DEREF_OF_NULL.RET Pointer, returned from function 'elf_getarhdr' at
readelf.c:13551, may be NULL and is dereferenced at readelf.c:13553.
* src/readelf.c (dump_archive_index): Check elf_getarhdr doesn't
return NULL.
Triggers found by static analyzer Svace.
Signed-off-by: Anton Moryakov <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We didn't check the symbol table referenced from the relocation table
was a real symbol table. This could cause a crash if that section
happened to be an SHT_NOBITS section without any data. Fix this by
adding an explicit check.
* src/strip.c (INTERNAL_ERROR_MSG): New macro that takes a
message string to display.
(INTERNAL_ERROR): Use INTERNAL_ERROR_MSG with elf_errmsg (-1).
(remove_debug_relocations): Check the sh_link referenced
section is real and isn't a SHT_NOBITS section.
https://sourceware.org/bugzilla/show_bug.cgi?id=32673
Signed-off-by: Mark Wielaard <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When combining eu-readelf -z with -x or -p to dump the data or strings
in an (corrupted ELF) unnamed numbered section eu-readelf could crash
trying to check whether the section name starts with .zdebug. Fix this
by skipping sections without a name.
* src/readelf.c (dump_data_section): Don't try to gnu decompress a
section without a name.
(print_string_section): Likewise.
https://sourceware.org/bugzilla/show_bug.cgi?id=32656
Signed-off-by: Mark Wielaard <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
A corrupt ELF file can have broken program headers, in which case
gelf_getphdr returns NULL. This could crash handle_dynamic_symtab
while searching for the PT_DYNAMIC phdr. Fix this by checking whether
gelf_phdr returns NULL.
* src/readelf.c (handle_dynamic_symtab): Check whether
gelf_getphdr returns NULL.
https://sourceware.org/bugzilla/show_bug.cgi?id=32655
Signed-off-by: Mark Wielaard <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When dynsym/str was read through eu-readelf --dynamic by readelf
process_symtab the string data was not validated, possibly printing
unallocated memory past the end of the symstr data. Fix this by
turning the elf_strptr validate_str function into a generic
lib/system.h helper function and use it in readelf to validate the
strings before use.
* libelf/elf_strptr.c (validate_str): Remove to...
* lib/system.h (validate_str): ... here. Make inline, simplify
check and document.
* src/readelf.c (process_symtab): Use validate_str on symstr_data.
https://sourceware.org/bugzilla/show_bug.cgi?id=32654
Signed-off-by: Mark Wielaard <[email protected]>
|
|
|
|
|
|
|
|
|
| |
Add an assert of this property to help static analyzers (or humans)
reading this code.
* src/elflint.c (process_file): Add assert.
Signed-off-by: Mark Wielaard <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Report of the static analyzer:
Pointer, returned from function 'elf_getarhdr' at objdump.c:314,
may be NULL and is dereferenced at objdump.c:317. (CWE-476, CWE-690)
Corrections explained:
When processing archive elements, the code could dereference a NULL
pointer if 'elf_getarhdr' returns NULL. This patch adds a check to
ensure 'arhdr' is not NULL before using it. The fix ensures that the
function safely handles cases where 'elf_getarhdr' fails, avoiding
potential crashes.
Triggers found by static analyzer Svace.
Signed-off-by: Anton Moryakov <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
| |
The missing header is only obvious on musl and on glibc when you don't
have optimizations enabled.
Normally the header would transitively come from config.h -> ./lib/eu-config.h
-> glibc libintl.h. with __OPTIMIZE__.
https://sourceware.org/git/?p=glibc.git;a=blob;f=intl/libintl.h;hb=HEAD#l103
Signed-off-by: Alfred Wingate <[email protected]>
|
|
|
|
|
|
|
|
|
| |
skel_fd is passed to create_dwfl, which calls dup() on skel_fd.
create_dwfl handles closing the duped fd but not the original.
Ensure the original skel_fd is closed after it's passed to create_dwfl.
Signed-off-by: Aaron Merey <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The ar program is called to assemble a list of objects
within each archive to assist in building combined libraries,
however make already has this information
when processing the subdirectory for that respective library.
The list can be saved in a "manifest" file
instead of being generated whenever it is needed
for use with other subdirectories.
Even though the difference in time is insignificant,
a simple "echo" and "cat" is as much as 10 times faster
than a call to "ar t" for printing the archive members.
Since elfutils builds ar,
this also removes the awkward circular dependency
where an installation of ar is required
to build the libraries for ar.
Additionally, not every version of ar is equally portable,
as native versions of ar on macOS and other BSD-like distributions
may print out a special archive member like "__.SYMDEF"
which is not a compiled object but rather just metadata
from ranlib, leading to a build failure.
Avoid these limitations by removing usage of ar
and adding build and clean rules
for the usage of archive manifest files.
* .gitignore: exclude ".manifest" file extension.
* backends/Makefile.am: add manifest file build and clean rules.
* debuginfod/Makefile.am: Likewise.
* lib/Makefile.am: Likewise.
* libasm/Makefile.am: Likewise.
* libcpu/Makefile.am: Likewise.
* libdw/Makefile.am: Likewise,
and set object lists to manifest contents.
* libdwelf/Makefile.am: Likewise.
* libdwfl/Makefile.am: Likewise.
* libebl/Makefile.am: Likewise.
* libelf/Makefile.am: Likewise,
and set object lists to manifest contents.
* src/Makefile.am: Likewise.
Signed-off-by: Michael Pratt <[email protected]>
|
|
|
|
|
|
|
| |
Make sure to free fd and the archive entry if an error is encountered
while adding source files to the archive.
Signed-off-by: Aaron Merey <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
To increase the consistency of how automatic clean targets run,
define the variables together without +=, default to MOSTLYCLEANFILES
when there is no need for different levels or
add more clean levels to match other subdirectories,
add more files that are built, remove duplication, and cleanup.
Do the same for EXTRA_DIST where it is equally messy.
* backends/Makefile.am: add more objects to clean, improve spacing.
* debuginfod/Makefile.am: Likewise, and remove duplicates.
* lib/Makefile.am: improve spacing.
* libasm/Makefile.am: add more objects to clean, split similar to debuginfod.
* libcpu/Makefile.am: use normal =, add more objects to clean.
* libdw/Makefile.am: add more objects to clean, split similar to debuginfod.
* libdwelf/Makefile.am: add more objects to clean, use lowest clean level.
* libdwfl/Makefile.am: Likewise.
* libebl/Makefile.am: add more objects to clean.
* libelf/Makefile.am: add more objects to clean, split similar to debuginfod.
* src/Makefile.am: consolidate including EXTRA_DIST, split clean levels,
define with normal =, define with variables.
* tests/Makefile.am: Likewise, but not including EXTRA_DIST.
Signed-off-by: Michael Pratt <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
strip --reloc-debug-sections-only is expected to be a no-op for
non-ET_REL files. This was not enforced in the code. Sections
were copied over to a new output file and normally its contents
would be identical to the input file.
However the output file is not identical to a non-ET_REL input
file if the linker organized sections such that the indices of
SHF_ALLOC sections are not in a contigous group.
In this case strip will modify sections in order to keep all SHF_ALLOC
sections in a contiguous group.
Fix this by ignoring --reloc-debug-sections-only for non-ET_REL files.
https://sourceware.org/bugzilla/show_bug.cgi?id=32253
Signed-off-by: Aaron Merey <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When building with LTO gcc believes elf_fd can be used uninitialized:
In function ‘sysprof_init_dwfl’,
inlined from ‘sysprof_unwind_cb’ at stacktrace.c:1235:16:
stacktrace.c:1087:7: error: ‘elf_fd’ may be used uninitialized [-Werror=maybe-uninitialized]
1087 | close (elf_fd);
| ^
This code won't be reached because if find_procfile doesn't initialize
elf_fd, it will return an error. But help the compiler by initializing
elf_fd to -1.
* src/stacktrace.c (sysprof_init_dwfl): Init elf_fd to -1.
Signed-off-by: Mark Wielaard <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Since we obtain diagnostics about unwind method, another logical place
to show them is in eu-stack.
* src/stack.c (show_unwound_source): New global variable.
(struct frame): Add unwound_source field.
(frame_callback): Copy over unwound_source from Dwfl_Frame.
(print_frame): Take unwound_source string and print it.
(print_inline_frames): Take unwound_source argument and pass it on,
except for subsequent frames where we pass the string "inline".
(print_frames): Take unwound_source field from struct frame and pass
it on.
(parse_opt): Add --cfi-type,-c option to set show_unwound_source.
(main): Ditto.
* tests/run-stack-i-test.sh: Add testcase for --cfi-type.
Signed-off-by: Serhei Makarov <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Track the method used to unwind each Dwfl_Frame using an enum field
unwound_source; provide access to the field. Then use that in
eu-stacktrace to display the unwind methods used for each process.
This is an important diagnostic to verify how many processes are
adequately covered by the eh_frame unwinder.
* libdw/libdw.map (ELFUTILS_0.192): Add dwfl_frame_unwound_source,
dwfl_unwound_source_str.
* libdwfl/libdwfl.h (Dwfl_Unwound_Source): New enum.
(dwfl_frame_unwound_source)
(dwfl_unwound_source_str): New functions.
* libdwfl/dwfl_frame.c (dwfl_frame_unwound_source)
(dwfl_unwound_source_str): New functions.
* libdwfl/libdwflP.h: Add INTDECL for dwfl_frame_unwound_source,
dwfl_unwound_source_str.
(struct Dwfl_Frame): Add unwound_source field.
* libdwfl/frame_unwind.c (__libdwfl_frame_unwind): Set
state->unwound_source depending on the unwind method used.
* src/stacktrace.c (struct sysprof_unwind_info): Add last_pid
field to provide access to the current sample's dwfltab entry.
(sysprof_unwind_frame_cb): Add unwound_source to the data displayed
with the show_frames option.
(sysprof_unwind_cb): Set last_pid when processing a sample.
(main): Add unwind_source to the data displayed in the final summary
table.
Signed-off-by: Serhei Makarov <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Due to the x86-specific code in the initial version the configury has
significant restrictions. If --enable-stacktrace is not explicitly
provided, then eu-stacktrace will be disabled by default.
The way we test for x86 is a bit unusual. What we actually care about
is that the register file provided by perf_events on the system is an
x86 register file; this is done by checking that <asm/perf_regs.h> is
Linux kernel arch/x86/include/uapi/asm/perf_regs.h.
Once eu-stacktrace is properly portable across architectures,
these grody checks can be simplified. Enablement of the feature
by default depends on a released Sysprof version we can point to
for the patches.
* configure.ac: Add configure checks and conditionals for stacktrace tool.
* src/Makefile.am: Add stacktrace tool conditional on ENABLE_STACKTRACE.
Signed-off-by: Serhei Makarov <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
eu-stacktrace is a utility to process a stream of raw stack
samples (such as those obtained from the Linux kernel's
PERF_SAMPLE_STACK facility) into a stream of stack traces (such as
those obtained from PERF_SAMPLE_CALLCHAIN), freeing other profiling
utilities from having to implement their own backtracing logic.
eu-stacktrace accepts data from a profiling tool via a pipe or
fifo. The initial version of the tool works on x86 architectures and
accepts data from Sysprof [1]. For future work, it will make sense
to expand support to other profilers, in particular perf tool.
Further patches in this series provide configury, docs, and improved
diagnostics for tracking the method used to unwind each frame in the
stack trace.
[1]: The following patched version of Sysprof (upstream submission ETA
~very_soon) can produce data with stack samples:
https://git.sr.ht/~serhei/sysprof-experiments/log/serhei/samples-via-fifo
Invoking the patched sysprof with eu-stacktrace:
$ sudo sysprof-cli --use-stacktrace
$ sudo sysprof-cli --use-stacktrace --stacktrace-path=/path/to/eu-stacktrace
Invoking the patched sysprof and eu-stacktrace manually through a fifo:
$ mkfifo /tmp/test.fifo
$ sudo eu-stacktrace --input /tmp/test.fifo --output test.syscap &
$ sysprof-cli --sample-method=stack --use-fifo=/tmp/test.fifo test.syscap
Note that sysprof polkit actions must be installed systemwide
(e.g. installing the system sysprof package will provide these).
Otherwise, "Action org.gnome.sysprof3.profile is not registered"
error will result.
* src/stacktrace.c: Add new tool.
Signed-off-by: Serhei Makarov <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
These "unlocked" Linux Standard Base variants of standard functions
are not available on some systems that are still capable
of building Linux and ELFs.
The difference is negligible for simple printing to stdout.
POSIX also states for the similar putc_unlocked():
These functions can safely be used in a multi-threaded program
if and only if they are called while the invoking thread owns
the (FILE *) object, as is the case after a successful call
to the flockfile() or ftrylockfile() functions.
...
These unlocked versions can be safely used
only within explicitly locked program regions,
using exported locking primitives.
and these precautions were never done.
Use the standard forms of these print functions.
There is inconsistent use of fputc_unlocked() with putc_unlocked(),
so consistently use the safer fputc() instead.
Signed-off-by: Michael Pratt <[email protected]>
|
|
|
|
|
|
|
|
|
| |
Dynamic memory, referenced by 'collected', is allocated at elflint.c:2235
and lost at elflint.c:2296.
Found by RASU JSC with SVACE.
Signed-off-by: Maks Mishin <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
| |
The .gdb_index const table can be empty, if no symbol table entry
refers to a name or CU. Which technically means the symbol table is
empty or has only zero members.
* src/readelf.c (print_gdb_index_section): Check const_off is
not past the end of the data section, it can be at the end.
Signed-off-by: Mark Wielaard <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The eu-srcfiles --no-backup option is only valid when build with
libdebuginfod support. Adjust the ENABLE_LIBDEBUGINFOD conditional
to not use no_backup anywhere. Also only run the run-srcfiles-self.sh
test when debuginfod is enabled.
* src/srcfiles.cxx (zip_files): Move endif ENABLE_LIBDEBUGINFOD
after no_backup check.
* tests/Makefile.am (TESTS): Only add run-srcfiles-self.sh
if DEBUGINFOD and !DUMMY_LIBDEBUGINFOD.
* tests/run-srcfiles.self.sh: Use local DEBUGINFOD_CACHE_PATH.
https://sourceware.org/bugzilla/show_bug.cgi?id=32155
Signed-off-by: Mark Wielaard <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We were printing the addr_off instead of the sym_off. And the
testcases all expected the address offset instead of the symbol table
offset.
* src/readelf.c (print_gdb_index_section): Print sym_off as
Symbol table offset.
* tests/run-readelf-gdb_index.sh: Fix up all symbol table
offsets that were the same as the address offset.
Signed-off-by: Mark Wielaard <[email protected]>
|
|
|
|
|
|
|
|
|
| |
commit 742fb81f3 did most of the work for supporting --enable-gcov,
but one debuginfod client is hiding in the src/ directory, namely
srcfiles, which also needs this enumeration of dependent libraries
for static linkage.
Signed-off-by: Frank Ch. Eigler <[email protected]>
|
|
|
|
|
|
|
|
|
|
| |
Replace -I with -iquote to avoid overriding stack system header from libcxx-18
with the previously built stack binary. Override DEFAULT_INLCUDES because m4
adds -I. by default.
https://bugs.gentoo.org/925241
Signed-off-by: Aaron Merey <[email protected]>
|
|
|
|
|
|
|
|
|
| |
The --permissive command line option is applied when writing the binary
being stripped but is not applied when writing its separate debug file.
Change this so that --permissive applies to writing the debug file as well.
Signed-off-by: Aaron Merey <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
| |
Use the dwfl_set_sysroot() function to set the sysroot to be
used when analysing a core:
e.g.
$ eu-stack --core core --sysroot /path/to/sysroot -e crashing_prog
Signed-off-by: Luke Diamand <[email protected]>
Signed-off-by: Michal Sekletar <[email protected]>
|
|
|
|
| |
Signed-off-by: Maks Mishin <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Found by GCC14 -Wanalyzer-fd-double-close.
close always closes the given file descriptor even on error. So don't
try to close a file descriptor again on error (even on EINTR). This
could be bad in a multi-threaded environment.
* src/ar.c (do_oper_extract): Call close and set newfd to -1.
(do_oper_delete): Likewise.
(do_oper_insert): Likewise.
* src/ranlib.c (handle_file): Likewise.
Signed-off-by: Mark Wielaard <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
print_form_data didn't take the offset_len (4 or 8 bytes) into account
causing the wrong entry to be read from .debug_str_offsets.
print_debug_macro_section did sanity checking before calling
print_form_data, which does sanity checking itself. The sanity check
for DW_FORM_strx was wrong in print_debug_macro_section (but correct
in print_form_data).
Add a new testfile for run-readelf-macro.sh, this one compiled with
clang -gdwarf-5 -fdebug-macro.
* src/readelf.c (print_form_data): Multiply by offset_len for
strx_val.
(print_debug_macro_section): Remove sanity checks before calling
print_form_data.
* tests/testfileclangmacro.bz2: New testfile.
* tests/Makefile.am (EXTRA_DIST): Add testfileclangmacro.bz2.
* tests/run-readelf-macro.sh: Add testfileclangmacro output.
Signed-off-by: Mark Wielaard <[email protected]>
|
|
|
|
|
|
|
|
|
|
|
| |
This alloca use is inside a lexical block and is used to replace one
element of argv. Use a function local variable, xmalloc and free to
make memory usage pattern more clear.
* src/ar.c (main): Move newp char pointer declaration up.
Use xmalloc to allocate space. free at end of main.
Signed-off-by: Mark Wielaard <[email protected]>
|