前些天为了排查我们程序中不知道是库里面还是我们自己调用了assert断言,导致我们程序死亡。想通过hook拦截到调用这个函数的调用者,偶然间想起proload(预加载),小试牛刀使用如下代码

#include <syscall.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
void abort(void)
{
    printf("****************my abort, getpid():%u\n", __FILE__, __LINE__, getpid());
    int *a = NULL;
    *a = 1;
    while(1)
    {
        sleep(10000);
    }
}

gcc --shared -fPIC preload.c -o libpreload.so 编译成so的形式

使用如下代码进行测试

#include <stdlib.h>
#include <stdio.h>
int main ( int argc, char *argv[] )
{
    printf("file:%s, line:%d, getpid():%u\n", __FILE__, __LINE__, getpid());
    abort();
    printf("file:%s, line:%d\n", __FILE__, __LINE__);
    void *p = malloc(3);
    return p == NULL;
    return EXIT_SUCCESS;
}

gcc testpreload.c -o testpreload 编译可执行程序,默认链接到了glibc中的assert

启动方式,

将libpreload.so放到和可执行程序testpreload同级目录下

LD_LIBRARY_PATH=".:$LD_LIBRARY_PATH" LD_PRELOAD="libpreload.so" ./testpreload

加入LD_LIBRARY_PATH 对当前目录的搜索,使用LD_PRELOAD 设定预加载的so,启动后输出如下结果

file:testpreload.c, line:31, getpid():9960
****************my abort, getpid():3086001460
./run.sh: line 1:  9960 段错误               LD_LIBRARY_PATH=".:$LD_LIBRARY_PATH" LD_PRELOAD="libpreload.so" ./testpreload

我故意产生了一个SIGV错误,暂时弄不清楚为什么getpid()的系统调用返回值不对,printf却可以运行无误。

主要用途:

        可以代替ptrace拦截系统调用,或者对函数的调用,可以用来分析一些比如内存泄露(malloc free是否成对调用)等等问题

GitHub 加速计划 / li / linux-dash
13
2
下载
A beautiful web dashboard for Linux
最近提交(Master分支:4 个月前 )
186a802e added ecosystem file for PM2 5 年前
5def40a3 Add host customization support for the NodeJS version 5 年前
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐