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

В последнее время я экспериментировал с 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()нет?

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

4 ответа

Решение

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

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

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

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

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

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

Из документов 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 man-страница, которая описывает, как установить различные переменные окружения, которые изменяют поведение lebefence

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

Другие вопросы по тегам