使用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
- Duplicate 4095-byte calls: You're likely instrumenting both the PLT (Procedure Linkage Table) entry for
mallocand the actual__libc_mallocimplementation in libc. When your test program callsmalloc, 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. - 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
- Stdio buffer allocation (since you included
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
相关产品推荐
相关产品推荐

