相关疑难解决方法(0)

GNU gcc/ld - 使用在同一目标文件中定义的调用者和被调用者包装对符号的调用

为了澄清,我的问题是当调用者和被调用者在与GCC编译器和链接器的同一编译单元中定义时,包装/拦截从一个函数/符号到另一个函数/符号的调用.

我的情况类似于以下情况:

/* foo.c */
void foo(void)
{
  /* ... some stuff */
  bar();
}

void bar(void)
{
  /* ... some other stuff */
}
Run Code Online (Sandbox Code Playgroud)

我想包装对这些函数的调用,我可以用ld的--wrap选项(到某一点)用ld的选项(然后我实现__wrap_foo和__wrap_bar,然后按照ld --wrap选项的结果调用__real_foo和__real_bar ).

gcc -Wl,--wrap=foo -Wl,--wrap=bar ...
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是,这只对来自此编译单元外部的foo和bar的引用生效(并在链接时解析).也就是说,从foo.c中的其他函数调用foo和bar 不会被包装.

在链接器包装之前,编译单元内的调用将得到解析

我尝试使用objcopy --redefine-sym,但只重命名符号及其引用.

我想将调用替换为foobar(在foo.o中)__wrap_foo以及__wrap_bar(就像它们通过链接器--wrap选项在其他目标文件中解析一样)之前我将*.o文件传递给链接器的--wrap选项,而不必修改foo .c的源代码.

这样,包装/拦截发生在所有调用foobar,而不仅仅是发生在foo.o之外的调用.

这可能吗?

linker gcc mocking ld interceptor

33
推荐指数
5
解决办法
2万
查看次数

C/C++中的自定义FILE类型

在C/C++中是否可以创建我自己的FILE(stdio.h)类型的自定义流,例如可以与fputs()一起使用?

c c++

7
推荐指数
2
解决办法
4842
查看次数

覆盖静态库中定义的C函数

我有一个C文件的静态库,在Cygwin上用g ++编译.我希望单元测试库中定义的一个函数.该函数调用该库中定义的另一个函数,我希望覆盖依赖项以将其替换为我自己的该函数版本.我无法修改静态库中的内容,因此此解决方案[ 覆盖C中的函数调用 ]不适用.

通常,我可以编写.cpp文件并包含.c文件,其中包含我想要单元测试的函数,它实际上使用我添加的代码扩展了该文件.这是一个我从未用于生产代码的肮脏技巧,但它对于单元测试C文件很方便,因为它使我的测试代码能够访问该C文件中的静态内容.然后,我可以写我的假依赖版本,以及调用我正在测试的函数的单元测试函数.我编译my.cpp来获取my.o,然后将其与静态库链接.从理论上讲,由于链接器已经找到了依赖关系的定义(我提供的那个),因此它不会在库中查找,也不会发生冲突.通常这可行,但现在我得到一个"多重定义"错误,链接器首先找到我的假,然后找到真正的假.我不知道是什么原因引起的,不知道该找什么.我也不能把它归结为一个简单的例子,因为我的简单例子没有这个问题.

想法好吗?

c gcc cygwin g++

7
推荐指数
1
解决办法
7587
查看次数

从同一编译单元覆盖C中的函数调用

我试图在C中覆盖一个函数调用,但是当在同一个编译单元中使用该函数时,我遇到了问题.在下面的代码中,我试图替换函数get_resolution(),但我只能在test.c中完成但不能从display.c中实现它.

// display.c -------------------------------------------------------------

#include <stdio.h>

void get_resolution()
{
    printf("Original get_resolution\n");
}

void display()
{
    get_resolution();
}

// test.c ----------------------------------------------------------------

#include <stdio.h>

void __wrap_get_resolution()
{
    printf("Mock get_resolution\n");
    // __real_get_resolution(); // Should be possible to call original
}

int main()
{
    display();         // **ISSUE** Original get_resolution() is called
    get_resolution();  // __wrap_get_resolution() is called
    return 0;
}

// gcc -Wl,--wrap,get_resolution display.c test.c
Run Code Online (Sandbox Code Playgroud)

我的要求是,当我从main()调用display()时,我希望执行__wrap_get_resolution(),但我总是看到正在调用原始的get_resolution().对拆卸的一点分析表明函数get_resolution被不同地调用:

在display() - > get_resolution()的地址已经解析

00000000 <_get_resolution>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   83 …
Run Code Online (Sandbox Code Playgroud)

c linker gcc overriding function

6
推荐指数
2
解决办法
4388
查看次数

如何取消定义库函数以使用我们版本的相同函数

如何取消定义库函数以使用我的同一函数版本。请注意,我需要包含同一文件的其他函数的头文件。所以不包括不是一个选择。有没有什么方法可以不改名字就可以使用呢?

c

6
推荐指数
2
解决办法
9379
查看次数

c中具有相同功能的两个声明

我在测试中遇到了这个问题,我仍然不明白给出的答案:

假设我写了以下代码:

#include <math.h>
#include <stdio.h>

float cos(float x){
    return 1-x*x/4;
}

int main()
{
    printf("%0f",cos(0.05f)+sin(0.05f));
}
Run Code Online (Sandbox Code Playgroud)

让我们假设cossin在数学库中声明和定义(接收和返回double),并且我试图将我的代码与数学库链接起来.

另一个假设是cos定义于math.c.

问题是:

"代码是否会成功编译/链接?如果是,将调用哪个cos函数?"

答案是:

"是的,代码将编译,我的cos将被调用".

怎么解释这种行为?这些多个定义不是同一个函数吗?

c

6
推荐指数
1
解决办法
722
查看次数

带有默认函数的 Windows 静态库

我想在 Windows 中创建一个静态库 (.lib),可以在后续构建中用作未定义函数的“备份”。

例如,假设我有 foobar.lib,它具有以下定义:

FOO
BAR
Run Code Online (Sandbox Code Playgroud)

我还有一些其他程序,FOO它只定义并且将被构建到一个必须导出的 DLLFOOBAR. 我希望能够使用 foobar.lib 自动导出BAR生成的 DLL 中的默认定义(并忽略FOOfoob​​ar.lib 中的定义)。

我曾尝试将 foobar.lib 发送到链接器,但出现多个定义的符号错误(/FORCE 应该覆盖它,但强烈警告它可能无法按预期工作)。我也试过使用 /NODEFAULTLIB:foobar.lib 但它完全忽略了库并说BAR是未定义的。

我几乎 100% 肯定有一种方法可以做到这一点,因为我使用一个执行此操作的应用程序 (Abaqus) 来允许用户编写插件,而不必为插件 DLL 定义所有必需的导出。他们不使用 /FORCE 选项。

windows linker static-libraries

5
推荐指数
1
解决办法
1169
查看次数

双重自由问题

如何通过编写一个名为free的包装函数来解决双重自由问题,这样我就不需要在源代码中更改每个免费调用了?

c

3
推荐指数
3
解决办法
3491
查看次数

我可以用自己的版本替换静态库中的符号吗?

使用gcc / ld,我要使用libfoo.a,其中包含一个符号symbol_foo(这是一个函数-如果重要的话,请参阅ISR)。其他libfoo功能显然在使用该功能。我想做的是使用编译我自己的二进制文件libfoo.a,而是链接自己的版本symbol_foo

这可能吗?当前,由于符号的多个定义,我得到ld错误。也就是说,在原始静态库中未将其声明为“软链接”或类似内容。

理想情况下,我希望那里存在类似的__attribute__((ld_override))东西,但是我猜那里不存在。有任何想法吗?

c linker

3
推荐指数
1
解决办法
405
查看次数

使用LD_PRELOAD重载调用共享库的C函数

我正在按照这个答案来覆盖对C库的C函数的调用.

我想我做的一切都正确,但它不起作用:

我想覆盖"DibOpen"功能.这是我在运行应用程序时传递给LD_PRELOAD环境变量的库代码:

DIBSTATUS DibOpen(void **ctx, enum Board b)
{
    printf("look at me, I wrapped\n");

    static DIBSTATUS (*func)(void **, enum Board) = NULL;
    if(!func)
        func = dlsym(RTLD_NEXT, "DibOpen");
    printf("Overridden!\n");
    return func(pContextAddr, BoardType, BoardHdl);
}
Run Code Online (Sandbox Code Playgroud)

nm lib.so | grep DibOpen节目的输出

000000000001d711 T DibOpen
Run Code Online (Sandbox Code Playgroud)

当我像这样运行我的程序时

LD_PRELOAD=libPreload.so ./program
Run Code Online (Sandbox Code Playgroud)

program用-ldl 链接我,但ldd program没有显示libdl.so的链接

它停止了

 symbol lookup error: libPreload.so: undefined symbol: dlsym
Run Code Online (Sandbox Code Playgroud)

.我该怎么做才能进一步调试?我的错误在哪里?

c gcc dynamic-linking ld

2
推荐指数
1
解决办法
2296
查看次数