Monday, September 16, 2013

Don't wait for the signal

I have been looking into a crazy issue in libcurl. An Android application was crashing and according to the crash report the reason was a bad pointer. That's not interesting at all and I wouldn't post about it if the circumstances hadn't made me ponder about the deepness of the hole we get into sometimes.

The back trace was nearly equivalent to what can be seen here.
backtrace:
#00 pc 00626916 /data/app-lib/com.pmon.app1-1/libvgc.so
#01 pc 00626bb3 /data/app-lib/com.pmon.app1-1/libvgc.so
#02 pc 0062792d /data/app-lib/com.pmon.app1-1/libvgc.so (curl_mvsnprintf+20)
#03 pc 00621c01 /data/app-lib/com.pmon.app1-1/libvgc.so (Curl_failf+24)
#04 pc 0061c0cd /data/app-lib/com.pmon.app1-1/libvgc.so (Curl_resolv_timeout+188)

So the crashed thread id was the same as the process id, meaning the main thread crashed. Now the interesting part was that libcurl is not used from the application's main thread. For sure...

How comes that the crashed thread (again, the main) was running libcurl code at the time of the crash?

Sure you think, well, the stack was corrupted. Or there was something wrong with the crash report. No no, everything was fine. The stack frames seemed to be in order, everything was OK except that last pointer which contained an address to no man's land.

The question was what could be the reason to see a thread running a code which it shouldn't. It took me a while to remember that Linux signals may do this trick. I mean if libcurl (and this theory has been proved later) is registering its code for signal handling then yes, some of the signal handlers will indeed run from the main thread of the process!

See this for more info on the subject.

Just to complete the story, the reason for the crash was a canceled request caused a timeout. Some of the related data containers were already released by the time of the timeout so the signal handler went to play on the minefield. What a pity... :-/

To disable the use of signals in curl you can do two things:

  • Use the "CURLOPT_NOSIGNAL" option when initializing curl. Keep in mind that this will disable timeouts automatically (less idea for most applications)

  • Compile curl with threaded-resolver. It requires pthread support in the toolchain and the target system.


 

 

 

 

Thursday, September 12, 2013

Don't you dare to deny my morning COFFee, PEople

This week I have been involved in a courageous project related Microsoft's linker for WP8 (part of VS2012). It required some knowledge of PE/COFF formats which I didn't have before and I have decided to learn these formats through wrinting a tool for reading this file the way we have "readelf" for ELF and "otool" for Mach-O formats.

Side-note: understanding PE/COFF after knowing ELF and Mach-O is a piece of cake. Most of the differences are merely syntactic...

So the product is a python parser of PE/COFF files. It works just as readelf:
c:\Users\pmon\Desktop\petools>readcoff.py -h winp8.o
COFF Header:
Machine: 0x01c4
Number of sections: 0x0006
Time of creation: 2013-09-08 12:44:38
Pointer to symbol table: 0x00003eff
Number of symbols: 0x0000007b
Size of optional headers: 0x0000
Characteristics: 0x0000

The thing is not complete but you can use it to investigate object files.

It can be taken from:

https://bitbucket.org/pmon/petools