использование электрического забора в программе на С++

В последнее время я экспериментировал с Electric Fence и не могу понять, как использовать его с кодом C++.

Вот пример:

// test.cpp
#include <cstdlib>                                                                                                                                         

using namespace std;                                                                                                                                       

int main()                                                                                                                                                 
{                                                                                                                                                                                                                                                                                                     
        int *a = new int(10);                                                                                                                              
        delete a;                                                                                                                              
}  

Я скомпилировал его с

g++ ./test.cpp -o test -lefence -L/home/bor/efence_x86_64/lib -lpthread

И я не вижу баннер Electric Fence при запуске и не могу найти символы EF в исполняемом файле (используя команду nm).

Но если я изменю программу так:

// test.cpp
#include <cstdlib>                                                                                                                                         

using namespace std;                                                                                                                                       

int main()                                                                                                                                                 
{                                                                                                                                                          
        char *p = (char*)malloc(20);                                                                                                                       
        free(p);                                                                                                                                           
        int *a = new int(10);                                                                                                                              
        delete a;
}

все хорошо - появляется EF. Я знаю, что это решает проблему, я знаю :). Я просто хочу понять, почему это не сработало, потому что new() должен звонить malloc(), а delete() звонит free(), нет?

Причина, по которой я занялся этим, — большой проект с использованием библиотек boost и некоторых других. И эта программа никогда не вызывает malloc() или free() напрямую. И когда я собираю его с помощью EF, я не только связываю EF с окончательным исполняемым файлом, но и пересобираю все библиотеки, пытаясь связать с ними EF. И я не могу найти символы EF ни в одном из них. Это правильный подход? Или это неправильно, и EF должен быть связан только с исполняемым файлом, в конце концов, библиотеки должны быть оставлены нетронутыми? Но снова я не могу найти символы EF в исполняемом файле.


person Nick Borodulin    schedule 29.02.2012    source источник
comment
почему вы предпочитаете efence valgrind?   -  person Anycorn    schedule 29.02.2012
comment
потому что мне нужно отладить программу, работающую на ARMv5 (stackoverflow.com/q/9456194/4378). Валгринд там не пропортирован.   -  person Nick Borodulin    schedule 29.02.2012


Ответы (4)


Вы предполагаете, что компилятор компилирует код позади new, но этот код обычно находится где-то в предварительно скомпилированном RT.

new также обычно не вызывает malloc напрямую (в некоторых системах, таких как Windows, он вообще не вызывает malloc), он имеет несколько собственных задач, которые выполняются до и после обработки распределения. для чего-то подобного вам, возможно, придется пойти по полузлому пути глобальной перегрузки new и delete, чтобы заставить его напрямую вызывать malloc и free из вашего кода.

person Necrolis    schedule 29.02.2012

Из документации slackware по адресу http://slackbuilds.org/repository/13.1/libraries/electric-fence/

In order to debug a program it needs to be linked with Electric Fence's
library or dynamic linking needs to be used; README.Debian explains that
in detail.


If you're using c++, and you and want to statically link your c++
programs, you shouldn't use g++ to link libefence.a, but rather:
gcc -o myprog myprog.o -lstdc++ -lg++ -lefence
(if you use g++, the order is different, and efence's malloc doesn't
get used)

Обязательно прочитайте справочную страницу libefence, в которой описывается, как устанавливать различные переменные среды, которые изменяют поведение lebefence.

person user740970    schedule 13.03.2014

Для людей, которые ищут быстрый способ «отладки» кода C++ с помощью электрического забора на armv5:

Нет необходимости статически компилировать и изменять команду компоновщика. Мне достаточно было установить электроизгородь и запустить:

LD_PRELOAD=libefence.so ./your-buggy-program

(из тех же документов, что указаны выше)

person ChristophK    schedule 14.03.2016

Только если ваш код содержит «mallocs», «-libefence» будет виден в двоичном файле сборки с командой «ldd». В противном случае, если нет «mallocs» и только «new», вы можете не увидеть библиотеку «-libefence» в списке связанных библиотек сборочного двоичного файла.

person parasrish    schedule 28.11.2015