我创建了一个小型共享库,它使malloc和co过载。它编译成功,但是当我尝试使用它执行其他程序时,它会导致段错误。
到目前为止,我在尝试解决问题时采取了步骤:
1. Make sure the .so is executable.
2. Tried debugging using Valgrind and gdb.(see GDB output below)
3. Looked at other related questions on SO and tried to adopt the suggestions given.
执行测试.cpp
LD_PRELOAD=/home/absolute/path/mylib.so ./a.out
导致段错误。
测试.cpp
#include <stdlib.h>
#include <iostream>
int main () {
size_t size = sizeof(int);
void* ptr = malloc(size);
std::cout<<"Called malloc() " << ptr << std::endl;
free(ptr);
return 0;
}
这是我的一些共享库代码:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <dlfcn.h>
#include <iostream>
#include "runtime/Firstfit_heap.h"
#include "system/Auslagern.h"
#include "system/VirtualMem.h"
extern "C" {
void* malloc(size_t size) noexcept;
}
Auslagern swap(4,6);
VirtualMem mem(4, 6, swap, true);
Firstfit_heap heap(mem);
void* malloc(size_t size) noexcept{
void* handle = (void*) -1l;
auto fptr = (void* (*)(size_t))dlsym(handle, "malloc");
if (fptr == NULL) {
return NULL;
}
char* foo = "mallocn";
write(2, foo, 7);
// I THINK THE ERROR IS IN THE NEXT LINE BECAUSE "malloc" is printed to the console before the segfault(core dump)
void* ptr = fptr(size);
std::cout<<"malloc"<<std::endl;
return ptr;
}
我为所有.cpp文件编译和链接标志(在制作文件中):
CXXFLAGS = -fPIC -g -Wall -std=c++1z
LDFLAGS = -shared
LIBS = $(XLIBS) $(PTHREADLIBS) -lboost_program_options -lrt -lc -ldl
Gdb 输出:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000000002 in ?? ()
瓦尔格林德输出:
==19131== Jump to the invalid address stated on the next line
==19131== at 0x2: ???
==19131== by 0xFFF000082: ???
==19131== by 0xFFF000092: ???
==19131== Address 0x2 is not stack'd, malloc'd or (recently) free'd
==19131==
==19131==
==19131== Process terminating with default action of signal 11 (SIGSEGV)
==19131== Bad permissions for mapped region at address 0x2
==19131== at 0x2: ???
==19131== by 0xFFF000082: ???
==19131== by 0xFFF000092: ???
由于没有用于 mylib.so 的代码,我无法分辨哪个指令试图解决0x2问题,并且无法想到任何帮助我更接近解决方案的东西。 任何帮助指向我的写作方向都将非常有用。
蒂亚。
此代码:
void* malloc(size_t size) noexcept {
auto fptr = (void* (*)(size_t))dlsym(handle, "malloc");
保证永远重复出现,并在本身malloc
内存的任何dlsym
实现上耗尽堆栈。
此代码:
void* ptr = fptr(size);
std::cout<<"malloc"<<std::endl;
保证对本身malloc
内存的任何std::cout
实现执行相同的操作。
在 Linux 上,你的程序崩溃不是因为上述两个原因,而是因为std::cout
在libstdc++.so.6
本身被初始化之前被调用。
TL;DR:malloc
在这个过程的早期就被调用了,你需要非常小心,你可以从它的实现中调用哪些函数。最好将自己限制为系统调用。
附言 您应该学习使用调试器(例如 GDB)。瓦尔格林德不是解决这类问题的最佳工具。
Gdb 输出:
Program received signal SIGSEGV, Segmentation fault. 0x0000000000000002 in ?? ()
这告诉您程序跳转到地址0x2
并崩溃(该地址没有可执行代码)。
你的第一个问题应该是"我是如何到达这里的?",最有可能回答这个问题的命令是where
或backtrace
。
附言 此代码:
char* foo = "mallocn";
甚至不应该使用任何合理的C++编译器进行编译。