0

我有一个自己的共享库,编译和链接如下:

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);

fprintfmq_send在:之前打印

mqFd: 6, msg: 0x7ffdadef1820, size: 59

这很好,但是调用mq_send会产生上述详细的断言。

4

1 回答 1

0

我认为 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到库创建的命令行。

于 2016-10-20T01:51:34.960 回答