Когда я бросаю что-то, например int или char const *, и использовать printf для проверки ошибки, я получаю Address Sanitizer Error.
Я не смог найти ничего похожего в сети, и мой пример кода настолько прост, что я действительно не понимаю, как это может привести к ошибке.
Пример уменьшенного кода:
#include <stdio.h>
int main()
{
try {
throw 42;
} catch (int msg) {
printf("%d\n", msg);
}
return 0;
}
Консольный вывод при запуске кода:
ASAN:SIGSEGV
=================================================================
==16533==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f3eb9c1a76c bp 0x7ffde2b6fde0 sp 0x7ffde2b6fdd0 T0)
#0 0x7f3eb9c1a76b (/home/[...]/build/test/sample+0xc476b)
#1 0x7f3eb7e38b44 (/lib/x86_64-linux-gnu/libc.so.6+0x21b44)
#2 0x7f3eb9c1a5d9 (/home/[...]/build/test/sample+0xc45d9)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV ??:0 ??
==16533==ABORTING
При отключении флагов -fsanitize Valgrind дает следующие подсказки:
==18103== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==18103== Command: ./build/test/sample
==18103==
==18103== Invalid read of size 4
==18103== at 0x109205: main (sample.cpp:11)
==18103== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==18103==
==18103==
==18103== Process terminating with default action of signal 11 (SIGSEGV)
==18103== Access not within mapped region at address 0x0
==18103== at 0x109205: main (sample.cpp:11)
==18103== If you believe this happened as a result of a stack
==18103== overflow in your program's main thread (unlikely but
==18103== possible), you can try to increase the size of the
==18103== main thread stack using the --main-stacksize= flag.
==18103== The main thread stack size used in this run was 8388608.
==18103==
==18103== HEAP SUMMARY:
==18103== in use at exit: 148 bytes in 2 blocks
==18103== total heap usage: 2 allocs, 0 frees, 148 bytes allocated
==18103==
==18103== LEAK SUMMARY:
==18103== definitely lost: 0 bytes in 0 blocks
==18103== indirectly lost: 0 bytes in 0 blocks
==18103== possibly lost: 132 bytes in 1 blocks
==18103== still reachable: 16 bytes in 1 blocks
==18103== suppressed: 0 bytes in 0 blocks
==18103== Rerun with --leak-check=full to see details of leaked memory
==18103==
==18103== For counts of detected and suppressed errors, rerun with: -v
==18103== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 1 from 1)
Настройки компилятора: Использование clang 3.5.0-10 в Debian Jessie со следующими флагами (выдержка из Makefile):
CXX:=clang++
## generic warning-related stuff
WARNFLAGS:=-Wall -Wextra -Wextra-semi -pedantic
WARNFLAGS+= -Wsign-conversion -Wshorten-64-to-32
WARNFLAGS+= -Werror
## generic debugging-related stuff
DEBUGFLAGS:=-O2 -g3 -ggdb -fno-omit-frame-pointer
## harden program by performing additional checks
SANITIZER:=-fsanitize=address,signed-integer-overflow,shift,bool,bounds,vptr,integer-divide-by-zero,float-cast-overflow,float-divide-by-zero,enum
HARDENCXXFLAGS:=-ftrapv -D_FORTIFY_SOURCE=2 -DDEBUG=1 -UNDEBUG -fstack-protector-all -fPIE -Wformat -Wformat-security -Wformat-nonliteral $(SANITIZER)
## C++ compiler flags
DEF += -D_XOPEN_SOURCE_EXTENDED
CXXFLAGS:=$(WARNFLAGS) -stdlib=libc++ -std=c++14 -maes $(DEBUGFLAGS) $(HARDENCXXFLAGS) $(INCLUDEFLAGS) $(DEF) -Xclang -fcolor-diagnostics
Есть идеи?
Оказывается, проблема появляется только после ссылки на файл с такими строками, как std::cerr << "Error message" << std::endl;
— удаление этих строк приводит к исчезновению ошибки Address Sanitizer.
Если копнуть глубже, то, похоже, проблема связана с использованием виртуальных функций и / или с определенной комбинацией флагов компиляции.
Чтобы увидеть изолированную проблему, см. AddressSanitizer / LeakSanitizer Ошибка с -lsupc ++ и -stdlib = libc ++ в никогда не вызываемой виртуальной функции, которая пишет в поток
Других решений пока нет …