Search code examples
c++csocketscross-compiling

Compiler optimization creating a syscall?


I am compiling a fairly sophisticated application in two modes: Debug and Release. The main difference, as I see it, is -O0 vs -O3 (I can provide the relevant part of makefile if needed). I am trying to avoid syscall generation as much as possible, as I am simulating this application in syscall emulation mode (no OS running underneath). The problem that i am currently having is that in Release mode the compiler generates an extra socket syscall, which I prefer not to happen (and which does not happen in Debug mode).

The reason that I think the socket might be created is that I am using pthreads and two of my threads are communicating through a volatile char*. So I'm guessing maybe the compiler is trying to implement it in a fancy way when I set the -O3 flag? But I'm not sure if that is a reasonable assumption.

  1. Is it possible that the socket syscall is being generated because of the -O3 flag? (doesn't make too much sense)
  2. If so, how can I hint to the compiler to avoid generating this syscall?

EDIT: BTW the code is in C and C++

EDIT: The code is statically linked against the following shared libraries:

libstdc++.a 
libm.a 
libglib-2.0.a 
-static-libgcc 
*special pthreads library*

Also, I found where in the binary the call to socket is happening:

8c716:       db28            blt.n   8c76a <openlog_internal+0xf2>
8c718:       f8d9 1008       ldr.w   r1, [r9, #8]
8c71c:       4620            mov     r0, r4
8c71e:       2200            movs    r2, #0
8c720:       f441 2100       orr.w   r1, r1, #524288 ; 0x80000
8c724:       f001 e97c       blx     8da20 <__socket>
8c728:       4b20            ldr     r3, [pc, #128]  ; (8c7ac <openlog_internal+0x134>)
8c72a:       681b            ldr     r3, [r3, #0]
8c72c:       f8c9 0004       str.w   r0, [r9, #4]
8c730:       b943            cbnz    r3, 8c744 <openlog_internal+0xcc>
8c732:       1c43            adds    r3, r0, #1

EDIT: I found out why this is happening (see my answer below). If anyone has an explanation as to why the compiler behaves like that please share!!!


Solution

  • Although, one can imagine such an optimization, I haven't heard of such and I really doubt it, because any system call is usually very expensive.

    If you are on a *nix system, you can verify it by looking for undefined symbols with nm

    nm -u file1.o file2.o | grep socket
    

    should show somewhere the missing socket symbol as

            U socket
    

    if there is somewhere a call to socket.

    As I mentioned, I doubt, that there is an optimization inserting any system call and I expect no output from the command line above.

    Update:

    On my system (Ubuntu 12.04, gcc 4.6), I found the following note in man gcc

    -O2 Optimize even more. ...
    NOTE: In Ubuntu 8.10 and later versions, -D_FORTIFY_SOURCE=2 is set by default, and is activated when -O is set to 2 or higher. This enables additional compile- time and run-time checks for several libc functions. To disable, specify either -U_FORTIFY_SOURCE or -D_FORTIFY_SOURCE=0.

    So, maybe through this or a similar mechanism, there is some code included when the optimization is set to -O2 or -O3.