unknown error after dwarf_cfi_addrframe()

Sasha Da Rocha Pinheiro darochapinhe@wisc.edu
Thu Feb 7 22:57:00 GMT 2019


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



-------------- next part --------------
A non-text attachment was scrubbed...
Name: dyninst_group_test.dyn_g++_64_none_none
Type: application/octet-stream
Size: 91456 bytes
Desc: dyninst_group_test.dyn_g++_64_none_none
URL: <http://sourceware.org/pipermail/elfutils-devel/attachments/20190207/8cab3735/attachment.obj>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: dwarfdump_minusF_output.txt
URL: <http://sourceware.org/pipermail/elfutils-devel/attachments/20190207/8cab3735/attachment.txt>


More information about the Elfutils-devel mailing list