我最近从 Ubuntu 14.04 迁移到 Ubuntu 16.04 来处理代码。这让我从 GCC 4.8.4/GNU ld 2.24 转移到 GCC 5.3.1/GNU ld 2.26。
我一直在为代码编写测试用例,有人决定重写默认的 time() 函数进行测试,但链接行为似乎在这两个版本之间发生了变化。示例代码如下:
nothing.c:
#include <stdio.h>
#include <time.h>
void nothing( )
{
printf( "%lld\n", (long long)time( NULL ) );
}
something.c:
#include <stdio.h>
#include <time.h>
extern void nothing( void );
int main( )
{
printf( "%lld\n", (long long)time( NULL ) );
nothing( );
return 0;
}
faketime.c:
#include <time.h>
time_t time( time_t * ptr )
{
return 42;
}
现在,如果我使用以下代码编译此代码:
gcc -fPIC -c -o nothing.lo nothing.c
gcc -shared -rdynamic -o libnothing.so nothing.lo
gcc -o something something.c faketime.c -Wl,-rpath=. -L. -lnothing
在尝试运行可执行文件的每个环境中,我得到了两个不同的结果。
Ubuntu 14.04 说答案是“42/42”,而 Ubuntu 16.04 说答案是“42/1464287587”(插入您当前的 Unix 时间戳)。
我很好奇这是有意识的改变还是我在这里做错了什么?我有点假设“新方法”实际上更正确,因为它似乎是我覆盖库期望进行的系统调用的漏洞。但是,也许这很正常,也许现在这种“链接器替换”方法在新的编译器/链接器中被破坏了?