Использование электрического забора в программе на С ++
В последнее время я экспериментировал с 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" в списке связанных библиотек двоичного файла сборки.