Я использовал инструмент закрепления, опубликованный в официальном руководстве Intel :
#include "pin.H"
#include <iostream>
#include <fstream>
/* ===================================================================== */
/* Names of malloc and free */
/* ===================================================================== */
#if defined(TARGET_MAC)
#define MALLOC "_malloc"
#define FREE "_free"
#else
#define MALLOC "malloc"
#define FREE "free"
#endif
/* ===================================================================== */
/* Global Variables */
/* ===================================================================== */
std::ofstream TraceFile;
/* ===================================================================== */
/* Commandline Switches */
/* ===================================================================== */
KNOB<string> KnobOutputFile(KNOB_MODE_WRITEONCE, "pintool",
"o", "malloctrace.out", "specify trace file name");
/* ===================================================================== */
/* ===================================================================== */
/* Analysis routines */
/* ===================================================================== */
VOID Arg1Before(CHAR * name, ADDRINT size)
{
TraceFile << name << "(" << size << ")" << endl;
}
VOID MallocAfter(ADDRINT ret)
{
TraceFile << " returns " << ret << endl;
}
/* ===================================================================== */
/* Instrumentation routines */
/* ===================================================================== */
VOID Image(IMG img, VOID *v)
{
// Instrument the malloc() and free() functions. Print the input argument
// of each malloc() or free(), and the return value of malloc().
//
// Find the malloc() function.
RTN mallocRtn = RTN_FindByName(img, MALLOC);
if (RTN_Valid(mallocRtn))
{
RTN_Open(mallocRtn);
// Instrument malloc() to print the input argument value and the return value.
RTN_InsertCall(mallocRtn, IPOINT_BEFORE, (AFUNPTR)Arg1Before,
IARG_ADDRINT, MALLOC,
IARG_FUNCARG_ENTRYPOINT_VALUE, 0,
IARG_END);
RTN_InsertCall(mallocRtn, IPOINT_AFTER, (AFUNPTR)MallocAfter,
IARG_FUNCRET_EXITPOINT_VALUE, IARG_END);
RTN_Close(mallocRtn);
}
// Find the free() function.
RTN freeRtn = RTN_FindByName(img, FREE);
if (RTN_Valid(freeRtn))
{
RTN_Open(freeRtn);
// Instrument free() to print the input argument value.
RTN_InsertCall(freeRtn, IPOINT_BEFORE, (AFUNPTR)Arg1Before,
IARG_ADDRINT, FREE,
IARG_FUNCARG_ENTRYPOINT_VALUE, 0,
IARG_END);
RTN_Close(freeRtn);
}
}
/* ===================================================================== */
VOID Fini(INT32 code, VOID *v)
{
TraceFile.close();
}
/* ===================================================================== */
/* Print Help Message */
/* ===================================================================== */
INT32 Usage()
{
cerr << "This tool produces a trace of calls to malloc." << endl;
cerr << endl << KNOB_BASE::StringKnobSummary() << endl;
return -1;
}
/* ===================================================================== */
/* Main */
/* ===================================================================== */
int main(int argc, char *argv[])
{
// Initialize pin & symbol manager
PIN_InitSymbols();
if( PIN_Init(argc,argv) )
{
return Usage();
}
// Write to a file since cout and cerr maybe closed by the application
TraceFile.open(KnobOutputFile.Value().c_str());
TraceFile << hex;
TraceFile.setf(ios::showbase);
// Register Image to be called to instrument functions.
IMG_AddInstrumentFunction(Image, 0);
PIN_AddFiniFunction(Fini, 0);
// Never returns
PIN_StartProgram();
return 0;
}
/* ===================================================================== */
/* eof */
/* ===================================================================== */
В приведенном выше примере печатается входной аргумент для malloc () и free (), а такжевозвращаемое значение из malloc ().
Я проверил его по своему коду:
#include <stdio.h>
#include <stdlib.h>
void foo()
{
int a = 2;
int val;
val = a;
printf("%i\n", val);
}
int main()
{
int i;
char *str = (char*)malloc(15);
char * xx = (char*)malloc(30);
for (i = 0; i < 10; ++i)
{
str[i] = rand()%23+'a';
}
for (i = 0; i < 10; ++i)
{
xx[i] = rand()%23+'a';
}
xx[i] = '\0';
str[i] = '\0';
printf("%s\n", str);
printf("%s\n", xx);
free(str);
foo();
return 0;
}
И получил следующий вывод:
$ tail malloctrace.out
malloc(0x110)
returns 0x7f258b149e00
malloc(0xf)
malloc(0xf)
returns 0x107a260
malloc(0x1e)
returns 0x107a280
malloc(0x400)
returns 0x107a2b0
free(0x107a260)
Теперь, вВ моем опубликованном коде есть пара malloc
вызовов:
char *str = (char*)malloc(15);
char * xx = (char*)malloc(30);
Но, как вы можете заметить в приведенном выше выводе, обнаруживается пара вызовов функции malloc:
malloc(0xf)
malloc(0xf)
Я считаю, что они соответствуют malloc(15)
(обратите внимание, то же самое не верно в случае malloc(30)
).Не могли бы вы сказать мне, почему это так, также мы можем обнаружить такой вызов только один раз.
Objdump:
Malloc:
0000000000400500 <malloc@plt>:
400500: ff 25 2a 0b 20 00 jmp QWORD PTR [rip+0x200b2a] # 601030 <malloc@GLIBC_2.2.5>
400506: 68 03 00 00 00 push 0x3
40050b: e9 b0 ff ff ff jmp 4004c0 <.plt>
Часть моей основной функции:
int i;
char *str = (char*)malloc(15);
40063a: bf 0f 00 00 00 mov edi,0xf
40063f: e8 bc fe ff ff call 400500 <malloc@plt>
400644: 48 89 45 f0 mov QWORD PTR [rbp-0x10],rax
char * xx = (char*)malloc(30);
400648: bf 1e 00 00 00 mov edi,0x1e
40064d: e8 ae fe ff ff call 400500 <malloc@plt>
400652: 48 89 45 e8 mov QWORD PTR [rbp-0x18],rax
Обратите внимание только на пару вызовов malloc.