导致段错误的共享库

时间:2018-03-10 21:52:38

标签: c++ segmentation-fault shared-libraries

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

会导致段错误。

Test.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 = "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。

1 个答案:

答案 0 :(得分:1)

此代码:

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在此过程中很早就被调用,您需要非常小心可以从其实现中调用哪些函数。限制自己使用系统调用是最好的。

P.S。 您应该学会使用调试器(例如GDB)。 Valgrind 是解决此类问题的最佳工具。

  

Gdb输出:

     

Program received signal SIGSEGV, Segmentation fault. 0x0000000000000002 in ?? ()

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

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

P.P.S。 这段代码:

char* foo = "malloc\n";

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