This is the mail archive of the mailing list for the elfutils project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: unknown error after dwarf_cfi_addrframe()

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 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 (?). 


From: Sasha Da Rocha Pinheiro
Sent: Thursday, February 7, 2019 4:57 PM
To:; 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>.


============  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);                               
        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));        
        Dwarf_CFI_Entry entry;                                                  
        Dwarf_Off offset = 0, next_offset, saved_cur_offset;                    
        int res = 0, count_fde=0, count_cie=0;                                  
            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
            if(dwarf_cfi_cie_p(&entry)) count_cie++;                            
            else count_fde++;                                                   
        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]:
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]:
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);
233             if(!cfi) assert(false);
235             auto next_pc = range.first;
236             while(next_pc < range.second)
238                 Dwarf_Frame * frame = NULL;
239                 int result = dwarf_cfi_addrframe(cfi, next_pc, &frame);
240                 fprintf( stderr, "dwarf_cfi_addrframe() failed: %s.\n", dwarf_errmsg(-1));
dwarf_cfi_addrframe() failed: unknown error.
241                 if(result==-1) break;
(gdb) p/x next_pc
$73 = 0x40ae19

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]