歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Linux LD_PRELOAD

前些天為了排查我們程序中不知道是庫裡面還是我們自己調用了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是否成對調用)等等問題

Copyright © Linux教程網 All Rights Reserved