gpt4 book ai didi

c++ - 英特尔引脚 : how to detect realloc size

转载 作者:太空宇宙 更新时间:2023-11-04 01:44:13 24 4
gpt4 key购买 nike

我有一个以下的 pin 工具,例如 trace.cpp(与 pin 工具 manual 中的完全一样):

#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)
{
std::cout << name << "(" << size << ")" << endl;

}

VOID MallocAfter(ADDRINT ret)
{
std::cout << " 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;
}

(唯一的变化是它打印而不是将其存储在输出文件中)

我有以下 C 代码示例 - example.c:

#include <stdio.h>
#include <stdlib.h>

struct A {
int x[10];
int y[1];
};

int main()
{
struct A *ptr = calloc(1, sizeof(struct A));
ptr->x[10] = 4;
printf("%i\n", ptr->x[10]);
ptr = realloc(ptr, sizeof(int));
ptr->x[10] = 4;
printf("%i\n", ptr->x[10]);
free(ptr);
return 0;
}

当我使用 pin 工具运行它时,它会产生以下输出:

$ pin -t obj-intel64/trace.so -- ./example.o | tail
returns 139865991781744
malloc(272)
returns 139865991785984
malloc(44)
returns 33456736
malloc(4096)
returns 33456800
free(33456736)
4
4

注意两个 malloc 调用:

malloc(44)
malloc(4096)

它完美地检测到第一个(注意 c 代码中的 calloc 调用),但它检测到 4096 的 realloc(如果我在这里错了请纠正我)。但是,我相信它应该检测到 4 (sizeof int)。

我哪里错了?有什么方法可以检测到正确的尺寸(或者我可能在这里遗漏了什么)?

最佳答案

您正在使用跟踪工具来跟踪对 mallocfree 的实际调用。您似乎没有跟踪对 callocrealloc 的调用,大概是假设这些函数最终会调用 malloc

但这不一定是真的。例如,如果 realloc 检测到现有内存块已经足够大,可以满足请求,它可以只返回它的第一个参数而不做任何其他操作,因此您不会看到对 malloc 的任何调用。这显然是您的示例中发生的情况,因为您的 realloc 调用请求的内存比 calloc 分配的内存少,我们可以看到它在这里没有这样做,因为 free 调用时 ptr 的地址与 calloc 分配的 block 相同。

如果现有分配比请求大得多,realloc 可能会选择将 block 复制到更小的分配中,可能使用 malloc 获取。 .但即使 realloc 确实决定减少已分配内存的大小,也不能保证它需要新的分配。在某些实现中,可以拆分现有 block ,将不需要的部分添加到空闲列表中。这不会涉及对 freemalloc 的调用。

那么,如果 malloc(4096) 不是来自 realloc,那么它从何而来?最有可能的答案是 malloc 是从标准库中调用的。例如,printf 可能已经注意到它需要为 stdout 分配一个输出缓冲区,因此它会调用 malloc 来获取一些内存。

简而言之,您可能需要跟踪所有内存管理函数以清楚地了解正在发生的事情。

关于c++ - 英特尔引脚 : how to detect realloc size,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56830226/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com