[英]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).
如我所见,主要区别是-O0与-O3(如果需要,我可以提供makefile的相关部分)。 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).
我试图尽可能避免生成syscall,因为我正在syscall仿真模式下模拟此应用程序(在其下不运行任何操作系统)。 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).
我目前遇到的问题是,在Release模式下,编译器会生成一个额外的套接字syscall,我不希望发生(并且在Debug模式下不会发生)。
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*. 我认为可能会创建套接字的原因是我正在使用pthreads,而我的两个线程正在通过volatile char *通信。 So I'm guessing maybe the compiler is trying to implement it in a fancy way when I set the -O3 flag?
所以我猜测也许当我设置-O3标志时,编译器正在尝试以一种奇特的方式实现它? But I'm not sure if that is a reasonable assumption.
但是我不确定这是否是一个合理的假设。
EDIT: BTW the code is in C and C++ 编辑:顺便说一句,代码在C和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!!!
如果有人对编译器为何如此行事有一个解释,请分享!!!
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
如果您使用的是* nix系统,则可以通过查找带有
nm
未定义符号来进行验证
nm -u file1.o file2.o | grep socket
should show somewhere the missing socket
symbol as 应该将缺少的
socket
符号显示为
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
在我的系统(Ubuntu 12.04,gcc 4.6)上,我在
man gcc
发现了以下注意事项
-O2 Optimize even more.
-O2进一步优化。 ...
...
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.注意:在Ubuntu 8.10和更高版本中,默认情况下设置-D_FORTIFY_SOURCE = 2,并在-O设置为2或更高时被激活。 This enables additional compile- time and run-time checks for several libc functions.
这样就可以对几个libc函数进行附加的编译时和运行时检查。 To disable, specify either -U_FORTIFY_SOURCE or -D_FORTIFY_SOURCE=0.
要禁用,请指定-U_FORTIFY_SOURCE或-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
. 因此,也许通过这种或类似的机制,当优化设置为
-O2
或-O3
时,会包含一些代码。
After a whole day of debugging, it turns out that arm-cross-gcc compiles strcpy() differently under -O0 and -O1,-O2,-O3 when the string you are copying from is a volatile char* . 经过一整天的调试,事实证明,当要从中复制的字符串是volatile char *时,arm-cross-gcc在-O0和-O1,-O2,-O3下编译strcpy()的方式有所不同。 -O0 compiles using standard user mode assembly, whereas -O1,-O2,-O3 compile it with extra syscalls, such as socket, connect, and send.
-O0使用标准用户模式汇编进行编译,而-O1,-O2,-O3使用额外的系统调用(例如套接字,连接和发送)进行编译。
So, after all, my initial hunch is justified: 因此,毕竟我最初的直觉是合理的:
"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."
“我认为可能会创建套接字的原因是我正在使用pthreads,而我的两个线程正在通过volatile char *通信。因此,我猜测也许编译器在设置时试图以一种奇特的方式实现它。 -O3标志?但是我不确定这是否合理。”
EDIT: Here are some observations to support this claim: 编辑:这是支持此主张的一些观察:
I compiled my code in 4 versions 我将代码编译为4个版本
1. without strcpy() -O0 => obj.o0
2. with strcpy() -O0 => obj_strcpy.o0
3. without strcpy() -O3 => obj.o3
4. with strcpy() -O3 => obj_strcpy.o3
I ran nm -u on all of the above. 我在所有上述情况上都运行了nm -u。
Here are the diffs: 这是差异:
$> diff obj.o0 obj_strcpy.o0
$> diff obj.o3 obj_strcpy.o3
> U __strcpy_chk
$>
This means that when you add strcpy() to your code and compile with -O0 no external symbols are added, whereas when you add strcpy() to your code and compile with -O3 U __strcpy_chk
symbol is added to the object file. 这意味着,当您将strcpy()添加到代码中并使用-O0进行编译时,不会添加任何外部符号,而当您将strcpy()添加到您的代码中并使用-O3进行编译时,
U __strcpy_chk
符号添加到目标文件中。 I will look into the implementation of U __strcpy_chk
on ARM to figure out where the syscalls are coming from. 我将研究ARM上
U __strcpy_chk
的实现,以确定系统调用来自何处。 As of right now it seems like U __strcpy_chk
is doing buffer overflow checks - here is the reference: 截至目前,似乎
U __strcpy_chk
正在执行缓冲区溢出检查-这是参考:
http://refspecs.linux-foundation.org/LSB_4.0.0/LSB-Core-generic/LSB-Core-generic/libc---strcpy-chk-1.html http://refspecs.linux-foundation.org/LSB_4.0.0/LSB-Core-generic/LSB-Core-generic/libc---strcpy-chk-1.html
EDIT: So there are two solutions so far: one proposed by Olaf Dietsche to use another compiler flag in addition to -O3. 编辑:到目前为止,有两种解决方案:一种由Olaf Dietsche提出,除了-O3之外还使用另一种编译器标志。 The other option is to avoid strcpy() altogether and use something as follows:
另一种选择是完全避免使用strcpy()并使用如下所示的内容:
for(int i=0;i<64;i++)
{
cmd[i] = msg[i];
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.