Segfault of executables with shared libraries.

Colin Whittaker colinw at occamnetworks.com
Tue Mar 3 00:13:27 UTC 2009


Carmelo Amoroso wrote:
> Colin Whittaker wrote:
>   
>> Carmelo Amoroso wrote:
>>     
>>> Colin Whittaker wrote:
>>>  
>>>       
>>>> Carmelo Amoroso wrote:
>>>>    
>>>>         
>>>>> Try enabling debug early support into dynamic linker and run again.
>>>>> Just to see if it is failing in the dynamic linker or in the
>>>>> application.
>>>>> I suggest to build uclibc with full debug symbols too and start a
>>>>> real debuggging session
>>>>> with gdb.
>>>>> I'd suggest to set bp in __uClibc_main (unless you are failing
>>>>> before entering in this
>>>>> function), and then go step by step.
>>>>>
>>>>> I successfully debugged the ld.so in the past, so it is not impossible.
>>>>>
>>>>> Carmelo
>>>>>         
>>>>>           
>>>> Thanks Carmelo,
>>>> I enabled debug early support into dynamic linker and have the same
>>>> results.
>>>> I tried to break at __uClibc_main, and it segfaults before that.
>>>>
>>>> Any hints on how to debug ld.so ?
>>>> Where does it get invoked ?
>>>>
>>>> Colin..
>>>>
>>>>     
>>>>         
>>> Hi,
>>> may you post the output, and readelf -a ? it may helps.
>>> (if you prefer send me privately)
>>>
>>> For debugging the ld.so
>>> 1) hack ld.so Makefile file to add -g to  (it was removed in trunk)
>>> 2) install uclibc in a glibc/uclibc working system into a non system path
>>>   (let's say /broken/lib/)
>>> 3) compile your hello world by overriding the dynamic linker with
>>>    -Wl,--dynamic-linker,/broken/lib/ld-uClibc.so.0
>>> 4) install helloworl on the mips target
>>> 5) on the target launch gdbserver localhost:xxx ./helloworld
>>> 6) on the host, from within the source dir, launch xxx-gdb
>>> ./lib/ld-uClibc.so.0
>>> 7) connect from gdb console to the remote target as usual
>>> 8) now you can set bp in _dl_start, _dl_get_ready_to_run and so on
>>> (you cannot step in libc.so.0, but
>>>    if you are ure something wrong happens in ld.so, that's the way)
>>>
>>>
>>> Not a standard way, but really an interesting debugging session for
>>> what are
>>> involved into the ld.so internals ;)
>>>
>>> Cheers,
>>> Carmelo
>>>   
>>>       
>> Thanks for the debugging help. That is a great trick.
>>     
> I was sure you liked it ;)
>
>   
>> So, I did this and found the segfault happens when we try to execute:
>> DL_BOOT_COMPUTE_GOT(got);  in _dl_start() on line 195 dl-startup.c
>>
>> The assembly code for that line is:
>>    lw      v0,-32736(gp)
>>    addiu  t9,v0,9476
>>    jalr      t9
>>    nop
>>
>> The data at -32736+gp = 0, so t9 = 0x2504, causing the segfault.
>>
>>     
> so it seems that the got is not correctly set.
> continue with gdb to track down why it is NULL.
>
>   
>> Looks like pretty fundamental stuff. Any thoughts ?
>>
>> Colin..
>>     
> Carmelo
>   
Well, it is 0 because the .got table is not fixed up yet when we are in 
_dl_start().
The comment on line 126 of dl-startup.c says " WARNING! -- we cannot 
make _any_ function calls......"

So why is the macro DL_BOOT_COMPUTE_GOT() compiled to do a jalr ?
That macro is defined as a couple of __inline__ functions for mips:
elf_machine_dynamic() and elf_mips_got_forom_gpreg().

Does one of the buildroot debug flags turn off __inline__ ? (I currently 
have them all on.) If so, that is catastrophic for this function.
Is there a way to force __inline__ to work no matter the compile time 
flags ?

Colin..



More information about the uClibc mailing list