This is the mail archive of the
elfutils-devel@sourceware.org
mailing list for the elfutils project.
Re: unknown error after dwarf_cfi_addrframe()
- From: Sasha Da Rocha Pinheiro <darochapinhe at wisc dot edu>
- To: "elfutils-devel at sourceware dot org" <elfutils-devel at sourceware dot org>, Mark Wielaard <mjw at redhat dot com>, Ben Woodard <woodard at redhat dot com>
- Date: Tue, 12 Feb 2019 01:15:45 +0000
- Subject: Re: unknown error after dwarf_cfi_addrframe()
- Accept-language: en-US, pt-BR
- References: <BN6PR06MB2932AF6647E5E7108DD46E80A6680@BN6PR06MB2932.namprd06.prod.outlook.com>
I found that when libdw will try to get the base CFI from the ABI, the function ebl_abi_cfi() ends calling default_abi_cfi() which returns -1, when should be calling x86_64_abi_cfi().
In addition, the symbol x86_64_abi_cfi in the file libdw.so is not present, but all the respective default_* ones are.
It seems that the library is being compiled using BACKEND as default and not catching the correct architecture (?).
Sasha
From: Sasha Da Rocha Pinheiro
Sent: Thursday, February 7, 2019 4:57 PM
To: elfutils-devel@sourceware.org; Mark Wielaard
Subject: unknown error after dwarf_cfi_addrframe()
Hi all,
I'm trying to read frame info from .eh_frame section. But I'm getting "unknown error".
I'll copy the snippet where I use libelf functions to print all sections of the file and get the index of .eh_frame, to then use libdw to go through .eh_frame Dwarf_CFI_Entry entries, to count them. The count matches was dwarfdump from libdwarf prints out. I'll attach that too.
Following I create a Dwarf_CFI and try to lock up an address with dwarf_cfi_addrframe(). But got unknown error.
I'll attach the binary too.
As you can see in the GDB output below that I try to get frame info for the address 0x40ae19, and the FDE with index 94 (see dwarfdump output) has addresses of <0x0040ae19:0x0040aed3>.
Regards,
Sasha
============ snippet for what I'm doing ==============
//testing printing count for CIE and FDE in this eh_frame
auto e_ident = elf_getident(dbg_eh_frame, NULL);
Elf_Scn *scn = NULL;
Elf64_Shdr *shdr;
char *section_name;
size_t eh_frame_index = -1, shstrndx;
if(elf_getshdrstrndx(dbg_eh_frame, &shstrndx)!=0)
fprintf(stderr, "elf_getshdrstrndx() failed: %s.", elf_errmsg(-1));
while((scn = elf_nextscn(dbg_eh_frame,scn))!=NULL)
{
if((shdr = elf64_getshdr(scn))!=shdr)
fprintf(stderr, "getshdr() failed: %s.\n", elf_errmsg(-1));
if((section_name = elf_strptr(dbg_eh_frame, shstrndx, shdr->sh_name))==NULL)
fprintf(stderr, "elf_strptr() failed: %s.\n", elf_errmsg(-1));
fprintf(stderr, "Section [%d]: %s\n", elf_ndxscn(scn), section_name);
if(strcmp(section_name, ".eh_frame")==0)
eh_frame_index = elf_ndxscn(scn);
}
assert(eh_frame_index!=-1);
scn = elf_getscn(dbg_eh_frame,eh_frame_index);
fprintf( stderr, "elf_getscn() failed: %s.\n", elf_errmsg(-1));
auto eh_frame_data = elf_getdata(scn, NULL);
fprintf( stderr, "elf_getdata() failed: %s.\n", elf_errmsg(-1));
assert(eh_frame_data!=NULL);
Dwarf_CFI_Entry entry;
Dwarf_Off offset = 0, next_offset, saved_cur_offset;
int res = 0, count_fde=0, count_cie=0;
do{
res = dwarf_next_cfi((const unsigned char *)e_ident, eh_frame_data,
true, offset, &next_offset, &entry);
saved_cur_offset = offset;
offset = next_offset;
if(res==1 && next_offset==(Dwarf_Off)-1) break;
if(res == -1) {
if (offset != saved_cur_offset) {
fprintf(stderr, "dwarf_next_cfi() returns -1. Error: %s\n", dwarf_errmsg(-1));
continue; // Soft error, skip to the next CFI entry
}
// Since offset didn't advance, we can't skip this CFI entry and need to quit
break;
}
if(dwarf_cfi_cie_p(&entry)) count_cie++;
else count_fde++;
}while(true);
cerr << "Count_cie: " << count_cie << endl;
cerr << "Count_fde: " << count_fde << endl;
Dwarf_CFI * cfi = nullptr;
cfi = dwarf_getcfi_elf(dbg_eh_frame);
if(!cfi) assert(false);
auto next_pc = range.first;
while(next_pc < range.second)
{
Dwarf_Frame * frame = NULL;
int result = dwarf_cfi_addrframe(cfi, next_pc, &frame);
fprintf( stderr, "dwarf_cfi_addrframe() failed: %s.\n", dwarf_errmsg(-1));
if(result==-1) break;
============ end of snippet ==============
GDB output:
Thread 1 "test_driver" hit Breakpoint 11, Dyninst::DwarfDyninst::DwarfFrameParser::getRegsForFunction (
this=0x1a70320, range=..., reg=..., locs=std::vector of length 0, capacity 0, err_result=@0x7fffffffd3fc: 32767)
at /<hidden-filepath>...Parser.C:162
162 {
(gdb) until 231
Section [1]: .interp
Section [2]: .note.ABI-tag
Section [3]: .note.gnu.build-id
Section [4]: .gnu.hash
Section [5]: .dynsym
Section [6]: .dynstr
Section [7]: .gnu.version
Section [8]: .gnu.version_r
Section [9]: .rela.dyn
Section [10]: .rela.plt
Section [11]: .init
Section [12]: .plt
Section [13]: .plt.got
Section [14]: .text
Section [15]: .fini
Section [16]: .rodata
Section [17]: .eh_frame_hdr
Section [18]: .eh_frame
Section [19]: .init_array
Section [20]: .fini_array
Section [21]: .jcr
Section [22]: .dynamic
Section [23]: .got
Section [24]: .got.plt
Section [25]: .data
Section [26]: .bss
Section [27]: .gnu_debuglink
Section [28]: .shstrtab
elf_getscn() failed: no error.
elf_getdata() failed: no error.
Count_cie: 2
Count_fde: 205
Dyninst::DwarfDyninst::DwarfFrameParser::getRegsForFunction (this=0x1a70320, range=..., reg=...,
locs=std::vector of length 0, capacity 0, err_result=@0x7fffffffd3fc: Dyninst::DwarfDyninst::FE_No_Error)
at /<hidden-filepath>...Parser.C:231
231 Dwarf_CFI * cfi = nullptr;
(gdb) n
232 cfi = dwarf_getcfi_elf(dbg_eh_frame);
(gdb)
233 if(!cfi) assert(false);
(gdb)
235 auto next_pc = range.first;
(gdb)
236 while(next_pc < range.second)
(gdb)
238 Dwarf_Frame * frame = NULL;
(gdb)
239 int result = dwarf_cfi_addrframe(cfi, next_pc, &frame);
(gdb)
240 fprintf( stderr, "dwarf_cfi_addrframe() failed: %s.\n", dwarf_errmsg(-1));
(gdb)
dwarf_cfi_addrframe() failed: unknown error.
241 if(result==-1) break;
(gdb) p/x next_pc
$73 = 0x40ae19