Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
266 views
in Technique[技术] by (71.8m points)

c++ - ASAN not properly intercepting alloc/free in std::ostringstream's str when overriding new/delete?

When running my program with ASAN, I'm getting an error when using std::ostringstream. Something special with the program is that it's overriding the new and delete operators.

The following code is a simplified repro case:

#include <sstream>

char big_chunk[1000000];
char* alloc = big_chunk;

void *operator new(std::size_t sz)  {
   char* a = alloc;
   alloc += ((sz +7)&~7);
   return a;
}

void operator delete(void *p) noexcept {
}

void operator delete(void* p, std::size_t) noexcept {
}

int main() {
  std::ostringstream stream;
  stream << "a long string that will need allocation";
  stream.str();
  return 0;
}

When compiling and running this code with:

clang++ --std=c++17 main.cpp -fsanitize=address -O0 -g && ./a.out

I'm getting the following error:

=================================================================
==17820==ERROR: AddressSanitizer: attempting free on address which was not malloc()-ed: 0x0001081fc380 in thread T0
    #0 0x108392c0d in wrap__ZdlPv+0x7d (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x55c0d)
    #1 0x1081f11dc in main main.cpp:21
    #2 0x7fff20354620 in start+0x0 (libdyld.dylib:x86_64+0x15620)

0x0001081fc380 is located 0 bytes inside of global variable 'big_chunk' defined in 'main.cpp:3:6' (0x1081fc380) of size 1000000
SUMMARY: AddressSanitizer: bad-free (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x55c0d) in wrap__ZdlPv+0x7d
==17820==ABORTING
Abort trap: 6

(main.cpp:21 corresponds to the stream.str(); line)

Is the error caused by my code, or is it caused by a problem in ASAN?

question from:https://stackoverflow.com/questions/65847255/asan-not-properly-intercepting-alloc-free-in-stdostringstreams-str-when-overr

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I added some print statements to your program:


    #include <sstream>
    #include <iostream>
    
    char big_chunk[1000000];
    char* alloc = big_chunk;
    
    void* operator new(std::size_t sz) {
        char* a = alloc;
        alloc += ((sz + 7) & ~7);
        std::cout << '+' << static_cast<void*>(a) << std::endl;
        return a;
    }
    
    void operator delete(void* p) noexcept {
        std::cout << '-' << p << std::endl;
    }
    
    void operator delete(void* p, std::size_t) noexcept {
        std::cout << '-' << p << std::endl;
    }
    
    int main() {
        std::ostringstream stream;
        stream << "a long string that causes allocation";
        stream.str();
        return 0;
    }

And when I run it without sanitize it outputs:

clang++ --std=c++17 main.cpp -O0 -g && ./a.out
+0x6021f0
+0x6023f8
-0x6023f8
-0x6021f0

Which looks fine. When I remove these statements again and build it with sanitizer, clang says:

/tmp/main-96c773.o: In function `operator delete(void*)':
main.cpp:15: multiple definition of `operator delete(void*)'
/usr/lib/llvm-10/lib/clang/10.0.0/lib/linux/libclang_rt.asan_cxx-x86_64.a(asan_new_delete.cpp.o):asan_new_delete.cpp:(.text._ZdlPv+0x0): first defined here
/tmp/main-96c773.o: In function `operator new(unsigned long)':
main.cpp:8: multiple definition of `operator new(unsigned long)'
/usr/lib/llvm-10/lib/clang/10.0.0/lib/linux/libclang_rt.asan_cxx-x86_64.a(asan_new_delete.cpp.o):asan_new_delete.cpp:(.text._Znwm+0x0): first defined here
clang: error: linker command failed with exit code 1 (use -v to see invocation)

From this I deduce that the sanitizer itself also defined placement new and delete. I used clang version 6.0.0-1ubuntu2. Possibly your version mixed up your definition of placement new and delete with the sanitizer version, resulting in this error. But your program is fine.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...