我有一个自己的共享库,编译和链接如下:
gcc -g -Wall -fpic -c -o cont.o cont.c
gcc -g -shared -o libcont.so cont.o -lrt
我有一个使用此库的程序(nr
):
gcc -g -Wall -I/include_path -c -o nr.o nr.c
gcc -L/shared_lib_path nr.o -lcont -o nr
如果调用共享库的函数之一,则可能会调用 POSIX 消息发送 (mq_send()
),这可能会导致断言错误。 strace ./nr
对此做了如下说明:
) = 1 (in [5])
mq_timedreceive(5, "\17\0ryName\0stester\0\t\0op\0srate\0\22\0ro"..., 2000, 0, NULL) = 76
mq_open("tester_asdf", O_WRONLY|O_NONBLOCK) = 6
writev(2, [{"Inconsistency detected by ld.so:"..., 33}, {"dl-lookup.c", 11}, {": ", 2}, {"167", 3}, {": ", 2}, {"check_match", 11}, {": ", 2}, {"Assertion `", 11}, {"version->filename == ((void *)0)"..., 79}, {"' failed!\n", 10}], 10Inconsistency detected by ld.so: dl-lookup.c: 167: check_match: Assertion `version->filename == ((void *)0) || ! _dl_name_match_p (version->filename, map)' failed!
) = 164
非常有趣的是,如果我使用默认级别以外的任何优化级别(例如 -O3
)来编译程序,一切都会正常工作:
gcc -g -Wall -O3 -I/include_path -c -o nr.o nr.c
gcc -L/shared_lib_path nr.o -lcont -o nr
在这种情况下strace ./nr
说:
) = 1 (in [5])
mq_timedreceive(5, "\17\0ryName\0stester\0\t\0op\0srate\0\22\0ro"..., 2000, 0, NULL) = 76
mq_open("tester_asdf", O_WRONLY|O_NONBLOCK) = 6
mq_timedsend(6, "\t\0op\0srate\0\22\0root\0scall_rating\0\t"..., 59, 0, NULL) = 0
mq_timedreceive(5, "\t\0op\0srate\0\22\0root\0scall_rating\0\t"..., 2000, 0, NULL) = -1 EAGAIN (Resource temporarily unavailable)
pselect6(6, [5], NULL, NULL, NULL, {~[INT ILL BUS FPE KILL SEGV ALRM TERM STOP RTMIN], 8}
这正是我所期望的独立于优化级别的结果。
造成这种情况的可能原因是什么?
相应的代码片段:
fprintf(stderr, "mqFd: %d, msg: %p, size: %d\n", (int)mqFd, msg, (int)size);
mq_send(mqFd, msg, size, 0);
fprintf
在 mq_send
之前打印:
mqFd: 6, msg: 0x7ffdadef1820, size: 59
这很好,但是调用 mq_send
会产生上述详细的断言。
最佳答案
我认为 gcc 手册页中的这部分可能与您所看到的内容相关:
-shared Produce a shared object which can then be linked with other objects to form an executable. Not all systems support this option. For predictable results, you must also specify the same set of options used for compilation (-fpic, -fPIC, or model suboptions) when you specify this linker option.[1]
这意味着,您需要将 -fpic
添加到库创建的命令行中。
关于c - gcc 优化对共享库操作的影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40091267/