usando cerca elétrica em um programa c++
-
14-11-2019 - |
Pergunta
Tenho experimentado o Electric Fence recentemente e não consigo descobrir como usá-lo com código c++.
Aqui está um exemplo:
// test.cpp
#include <cstdlib>
using namespace std;
int main()
{
int *a = new int(10);
delete a;
}
Eu compilei com
g++ ./test.cpp -o test -lefence -L/home/bor/efence_x86_64/lib -lpthread
E não vejo o banner Electric Fence no início e não consigo encontrar símbolos EF no executável (usando o comando nm).
Mas se eu modificar um programa assim:
// test.cpp
#include <cstdlib>
using namespace std;
int main()
{
char *p = (char*)malloc(20);
free(p);
int *a = new int(10);
delete a;
}
está tudo bem - aparece EF.Eu sei que meio que resolve o problema, eu sei :).Eu só quero entender por que não funcionou em primeiro lugar, porque new()
deveria ligar malloc()
, e delete()
chamadas free()
, não?
A razão pela qual entrei nisso é um grande projeto usando impulsionar bibliotecas e vários outros.E este programa nunca liga malloc()
ou free()
diretamente.E quando eu o construí com EF, não apenas vinculei o EF ao executável final, mas reconstruí todas as bibliotecas tentando vincular o EF a elas.E não consigo encontrar símbolos EF em nenhum deles.É a abordagem certa?Ou está errado e o EF só deveria estar vinculado ao executável no final, as libs deveriam ser deixadas intactas?Mas, novamente, não consigo encontrar símbolos EF no executável.
Solução
Você está assumindo que o compilador está compilando o código por trás new
, mas esse código geralmente reside em algum lugar de um RT pré-compilado.
new
também geralmente não liga malloc
diretamente (em alguns sistemas como o Windows, ele não chama malloc
de todo), tem algumas tarefas próprias que são executadas, antes e depois de tratar a alocação.para algo assim, você pode ter que seguir o caminho semi-maligno de sobrecarregar globalmente new
e delete
para forçá-lo a ligar diretamente malloc
e free
do seu código.
Outras dicas
Dos documentos do slackware em 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)
Não deixe de ler o libefence
Manpage que descreve como definir várias variáveis de ambiente que alteram o comportamento de Lebefence
Para pessoas que procuram uma maneira rápida de "depurar" código C++ com cerca elétrica no armv5:
Não é necessário compilar e alterar estaticamente o comando do vinculador.Para mim bastou instalar cerca elétrica e rodar:
LD_PRELOAD=libefence.so ./your-buggy-program
(dos mesmos documentos citados acima)
Somente se o seu código contiver "mallocs", o "-libefence" ficará visível no binário de construção com o comando "ldd".Caso contrário, se não houver "mallocs" e apenas "novo", você poderá não ver a biblioteca "-libefence" na lista de bibliotecas vinculadas do binário de construção.