Linux run-time interpositioning调试记录

本文记录了在学习Linux链接器原理时遇到的一个问题,即使用run-time interpositioning进行库替换时引发的segment fault。通过生成dump文件、使用gdb分析,发现因printf调用malloc导致的无限循环调用栈,最终解决方案是避免使用会调用malloc的io函数,改用write等系统调用进行无缓冲I/O。
摘要由CSDN通过智能技术生成

背景介绍

在学习CSAPP第7章后,了解了有关linking的一些原理。仅就该章内容而言,有许多值得思考和注意的地方。作为一名developer,如果不清楚链接器是如何实现symbol resolution和relocation的,那么总有一天他会在这个问题上栽跟头。

举一个很简单的例子,如果在一个project中多个文件中定义了具有相同name的variable或者function, 会发生什么情况呢?
比如:

//file1.c
int x = 1;
int y = 2;
int main()
{
    func();
    printf("x = %d\ty = %d\n", x, y);
    return 0;
}

//file2.c
double x;
void func()
{
    x = 0.0;
}   

如果编译、执行上述两个文件,一定会有意外的惊喜发生!

本人花了一个周末从头到尾学习了一遍第7章中的所有内容, 编译、运行了该章节中的所有代码,确实有许多收获! 整个过程较为顺利,只是7.7节中的内容曾一度令我困惑。好在第二天再看一遍后,也能够彻底的理解了。

bug登场

值得一提的是,这里有一个例外:
在学习7.13节Library Interpositioning技术时,前两个Interpositioning(Comiple-time && Link-time)的代码都可以成功运行。其结果也确实表明interpotioning成功! 但是在尝试Run-time Interpositioning时,发生了segment fault.
源码如下:

    //mymalloc.c
    #ifdef RUNTIME
    #define _GNU_SOURCE
    #include<stdio.h>
    #include<stdlib.h>
    #include<dlfcn.h>

    //malloc wrapper function
    void *malloc(size_t size)
    {
    	void  *(*mallocp)(size_t size);
    	char *error;

    	//printf("trying to get address of libc malloc...\n");
    	mallocp = dlsym(RTLD_NEXT, "malloc"); //Get address of libc malloc
    	if((error = dlerror()) != NULL)
    	{
    		fputs(error, stderr);
    		exit(1);
    	}
    	//printf("Getting address of libc malloc succeeded.\n");
   
    	char *ptr = mallocp(size);  //call libc malloc
    	printf("malloc(%d) = %p\n", (int)size, ptr);
    	return ptr;
    }

    //free wrapper function
    void free(void *ptr)
    {
    	void (*freep)(void *ptr);

    	char *error;


    	if(!ptr)
    	{
    		return;
    	}

    	freep = dlsym(RTLD_NEXT, "free");  //Get address of libc free
    	if((error = dlerror()) != NULL)
    	{
    		fputs(error, stderr);
    		exit(1);
    	}
	
    	freep(ptr);   //call libc free

    	printf("freep(%p)\n", ptr);
    	ptr = NULL; //set ptr to NULL, avoiding bugs resulting from free a pointer twice.
    }
    #endif


    //int.c
    #include<stdio.h>
    #include<malloc.h>

    int main()
    {
    	int *p = (int*)malloc(32);
    	free(p);
    	return 0;
    }

相应的makefile文件内容为:

intr: int.c
	gcc -o -g intr int.c

mymalloc.so: mymalloc.c
	gcc -DRUNTIME -shared -fpic -g -o mymalloc.so mymalloc.c -ldl

run: mymalloc.so intr
	LD_PRELOAD="./mymalloc.so" ./intr

在shell下运行make run, 其结果为:

make: *** [run] Segmentation fault (core dumped)

为什么会这样? 仔细检查了几遍代码之后,发现代码与书中给出的代码确实一致。 于是只能寄希望于调试分

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值