You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Pintool插桩统计malloc调用时出现重复计数问题求助

Debugging Unexpected malloc Calls in Your PinTool

Let's break down why you're seeing extra malloc invocations and how to fix it:

Why the Extra Calls Happen

  1. Duplicate 4095-byte calls: You're likely instrumenting both the PLT (Procedure Linkage Table) entry for malloc and the actual __libc_malloc implementation in libc. When your test program calls malloc, it first jumps through the PLT entry, then to the real libc implementation—if both are instrumented, you'll count the same user call twice.
  2. 1024-byte call: This is an internal libc malloc, triggered during program initialization. Common causes include:
    • Stdio buffer allocation (since you included <stdio.h>)
    • Thread-local storage setup
    • Libc's internal memory management initialization

Fixes to Try

1. Target Only the Real malloc Implementation

Modify your image load callback to instrument only the actual __libc_malloc function in libc, not the PLT entry. This avoids duplicate counts from linkage jumps:

VOID ImageLoad(IMG img, VOID *v) {
    // Focus only on libc
    if (IMG_Name(img).find("libc.so") == string::npos) return;

    // Target the real libc malloc implementation
    RTN mallocRtn = RTN_FindByName(img, "__libc_malloc");
    if (!RTN_Valid(mallocRtn)) return;

    // Ensure the routine is safe for probed insertion
    if (!RTN_IsSafeForProbedInsertion(mallocRtn)) {
        fprintf(stderr, "Warning: malloc not safe for probed insertion\n");
        return;
    }

    // Insert your pre-call handler
    RTN_InsertCall(mallocRtn, IPOINT_BEFORE, (AFUNPTR)MallocBefore,
                   IARG_FUNCARG_ENTRYPOINT_VALUE, 0,  // malloc's size argument
                   IARG_THREAD_ID,
                   IARG_RETURN_IP,  // Address of the caller
                   IARG_END);
}

2. Filter Out Internal Libc Calls

Add logic to your MallocBefore handler to only count calls originating from your test program (not libc itself). Use the return IP to check which image the caller belongs to:

VOID MallocBefore(SIZE_T size, THREADID tid, ADDRINT callerAddr) {
    IMG callerImg = IMG_FindByAddress(callerAddr);
    if (callerImg == IMG_Invalid()) return;

    // Only count calls from your test program (adjust the path/name check as needed)
    string imgName = IMG_Name(callerImg);
    if (imgName.find("test") == string::npos) {
        return; // Skip libc-internal calls
    }

    // Get the caller's routine name for output
    RTN callerRtn = RTN_FindByAddress(callerAddr);
    string callerName = RTN_Valid(callerRtn) ? RTN_Name(callerRtn) : "unknown";

    printf("thread %d entered malloc(%zu) called from %s of img %s\n",
           tid, size, callerName.c_str(), imgName.c_str());
}

3. Verify Your Instrumentation Scope

Double-check that you're not accidentally instrumenting multiple versions of malloc. Some libcs expose both malloc (a wrapper macro/function) and __libc_malloc (the real implementation)—pick one to avoid duplication.

Final Notes

  • If you still see discrepancies, use Pin's backtrace functions (BACKTRACE_Get) to get a full call stack for each malloc. This will show exactly where the internal calls are coming from.
  • Make sure to test with a stripped-down test program (remove <stdio.h> temporarily) to confirm the 1024-byte call is indeed from stdio initialization.

内容的提问来源于stack exchange,提问作者abjoshi - Reinstate Monica

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:29:50