Information Technology Reference
In-Depth Information
Box 8. continued
// Free the function prototype.
PROTO_Free( proto_sleep );
}
else {
cout << “Could not find routine in image\n”;
}
}
int main( INT32 argc, CHAR *argv[] ) {
// Initialize symbol processing
//
PIN_InitSymbols();
// Initialize pin
//
PIN_Init( argc, argv );
// Register ImageLoad to be called when an image is
loaded
//
IMG_AddInstrumentFunction( ImageLoad, 0 );
// Start the program in probe mode, never returns
//
PIN_StartProgramProbed();
return 0;
}
Summary of compiler-based
instrumentation techniques
Instrumenting program code with tracing func-
tionality is a powerful means of understanding
system behavior. Modifying source code provides
a straightforward means to collect trace informa-
tion that must relate to application-level program
functionality. It therefore enables the customiza-
tion of trace insertion according to the program
“features” of interest.
Alternatively, binary instrumentation is well
equipped to handle complex software where the
executed code cannot be identified until runtime.
Binary-level modifications and execution on vir-
tual machine architectures allow straightforward
inspection of machine-level registers and data,
such as the stack and caches. Conversely, because
binary modification operates at such a low level,
it is sometimes hard to specify what to instru-
ment when semantics cannot be easily linked to
program-level functions and basic blocks. Binary
instrumentation is primarily supportive of active
profiling, although the use of a virtual machine
to execute code also provides a means to profile
passively.
From the perspective of profiling multithreaded
programs specifically, binary-code instrumenta-
tion can provide an effective means to intercept
and instrument synchronization functions where
source code is not available or when there is a need
for very fine-grained information, such as access
to cache state. Binary-code instrumentation also
The target program is run until completion
through PIN _ StartProgramProbed() . Pin
also supports the ability to dynamically attach and
detach from a long-running process if transient
tracing is needed.
Dynamic compilation and virtual machine
execution incur overhead. With respect to Pin,
overhead primarily stems from performing
JIT-compilation, helped by the use of a code-
translation cache.
Figure 6 shows Pin performance data taken
from Luk et al. (2005). These results show that
the slowdown incurred by Pin is approximately
four times slower than the original code without
instrumentation. Even though this slowdown is
significant, the Pin approach is one of the fastest
JIT-based profiling solutions available today.
 
Search WWH ::




Custom Search