编译 LD_PRELOAD 包装器的冲突类型

标签 c linux printf ld-preload conflicting-libraries

我尝试使用 LD_PRELOAD 来 Hook sprintf function ,所以我将打印到缓冲区的结果:

#define _GNU_SOURCE
#include <stdio.h>
#include<dlfcn.h>

int sprintf (char * src , const char *  format , char* argp)
{
    int (*original_func)(char*,const char * , char*);
    original_func = dlsym(RTLD_NEXT,"sprintf");
    int ret = (*original_func)(src ,format,argp);
    FILE* output = fopen("log.txt","a");
    fprintf(output,"%s \n",src);
    fclose(output);
    return ret;


}
当我编译这段代码时 gcc -Wall -fPIC -shared -o my_lib.so test_ld.c -ldl我有错误
test_ld.c:5:5: error: conflicting types for ‘sprintf’
 int sprintf (char * src , const char *  format , char* argp)
     ^
In file included from test_ld.c:2:0:
/usr/include/stdio.h:364:12: note: previous declaration of ‘sprintf’ was here
 extern int sprintf (char *__restrict __s,
我该如何解决?

最佳答案

您遇到的主要问题是 sprintf 的原型(prototype)和官方的不符。您的函数具有以下签名:

int sprintf (char * src , const char *  format , char* argp);
虽然官方有:
int sprintf(char *str, const char *format, ...);
您需要更改您的函数才能拥有此签名。完成此操作后,您需要使用 va_list得到可变参数。然后你会用它来调用vsprintf它采用这种类型的参数而不是使用 dlsym加载 sprintf .
#include <stdio.h>
#include <stdarg.h>

int sprintf (char * src , const char *  format , ...)
{
    va_list args;
    va_start(args, format);
    int ret = vsprintf(src, format, args);
    va_end(args);

    FILE* output = fopen("log.txt","a");
    fprintf(output,"%s \n",src);
    fclose(output);
    return ret;
}

关于编译 LD_PRELOAD 包装器的冲突类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66951324/

相关文章:

c - Sscanf 和 Sprintf 将字符串转换为十进制?

c - 如何使用 pthread 管理 c 中的多个线程?

c - 您是否应该尝试始终以最大线程数运行 CUDA C 硬件?

linux - 开罗,支持 pdf

c - fprintf C中 '\n'的作用是什么?

c - 我的 sprintf 使用有问题吗?

c++ - 垂直方向的 Gtk3+ Spinbutton (c/c++)

c++ - 可以在函数名上使用#ifndef 吗?

c - 程序收到信号 sigtstp 已停止(用户)

MYSQL数据库重启后拒绝访问