我创建了一个小型的共享库,它使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. 


用以下命令执行Test.cpp

 LD_PRELOAD=/home/absolute/path/mylib.so ./a.out 


导致段错误。

测试文件

#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 = "malloc\n";
        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文件的编译和链接标志(在makefile中):

  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 ?? ()


Valgrind输出:

 ==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。的代码,所以我无法确定哪个指令试图寻址0x2,也无法考虑任何有助于我进一步了解解决方案的内容。
将我指向写方向的任何帮助将非常有用。

TIA。

最佳答案:

这段代码:

void* malloc(size_t size) noexcept {
    auto fptr = (void* (*)(size_t))dlsym(handle, "malloc");


可以保证永远重复出现并在本身是
dlsym
内存的任何
malloc
实现上用完堆栈。

这段代码:

    void* ptr  = fptr(size);
    std::cout<<"malloc"<<std::endl;


对于任何本身
std::cout
内存的
malloc
实现,都可以保证执行相同的操作。

在Linux上,您的程序崩溃不是由于上述两个原因,而是因为在
std::cout
本身初始化之前调用
libstdc++.so.6


TL; DR:
malloc
在此过程中很早就被调用,您需要非常小心可从其实现中调用的函数。将自己限制为系统调用是最好的。

附言
您应该学习使用调试器(例如GDB)。 Valgrind并不是解决此类问题的最佳工具。


  Gdb输出:
  
  
Program received signal SIGSEGV, Segmentation fault.
  0x0000000000000002 in ?? ()



这告诉您程序跳至地址
0x2
并崩溃了(该地址处没有可执行代码)。

您的第一个问题应该是“我如何到达这里?”,最有可能回答的命令是
where
backtrace


P.P.S.
这段代码:

char* foo = "malloc\n";


甚至不应该使用任何合理的C ++编译器进行编译。