You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1270 lines
389 KiB

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Pin: Pin 3.15 User Guide</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">Pin
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
</script>
<div id="main-nav"></div>
</div><!-- top -->
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div class="header">
<div class="headertitle">
<div class="title">Pin 3.15 User Guide </div> </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p><br />
</p><hr/>
<h1><a class="anchor" id="INTRO"></a>
Introduction</h1>
<hr/>
<p>Pin is a tool for the instrumentation of programs. It supports the Linux*, macOS* and Windows* operating systems and executables for the IA-32, Intel(R) 64 and Intel(R) Many Integrated Core architectures.</p>
<p>Pin allows a tool to insert arbitrary code (written in C or C++) in arbitrary places in the executable. The code is added dynamically while the executable is running. This also makes it possible to attach Pin to an already running process.</p>
<p>Pin provides a rich API that abstracts away the underlying instruction set idiosyncracies and allows context information such as register contents to be passed to the injected code as parameters. Pin automatically saves and restores the registers that are overwritten by the injected code so the application continues to work. Limited access to symbol and debug information is available as well.</p>
<p>Pin includes the source code for a large number of example instrumentation tools like basic block profilers, cache simulators, instruction trace generators, etc. It is easy to derive new tools using the examples as a template.</p>
<p>Tutorial Sections</p><ul>
<li><a class="el" href="index.html#INSTRUMENTING">How to Instrument With Pin</a></li>
<li><a class="el" href="index.html#EXAMPLES">Examples</a></li>
<li><a class="el" href="index.html#CALLBACK">Callbacks</a></li>
<li><a class="el" href="index.html#MODIFYING">Modifying Application Instructions</a></li>
<li><a class="el" href="index.html#APPDEBUG">The Pin Advanced Debugging Extensions</a></li>
<li><a class="el" href="index.html#EX">Applying a Pintool to an Application</a></li>
<li><a class="el" href="index.html#DEBUGGING">Tips for Debugging a Pintool</a></li>
<li><a class="el" href="index.html#LOGGING">Logging Messages from a Pintool</a></li>
<li><a class="el" href="index.html#PERFORMANCE">Performance Considerations</a></li>
<li><a class="el" href="index.html#MEMORY">Memory management</a></li>
<li><a class="el" href="index.html#RESTRICTIONS">PinTools Information and Restrictions</a></li>
<li><a class="el" href="index.html#WINDOWS_TOOLS">Building Tools on windows</a></li>
<li><a class="el" href="index.html#WINLIBRARIES">Libraries for Windows</a></li>
<li><a class="el" href="index.html#LIBRARIES">Libraries for Linux</a></li>
<li><a class="el" href="index.html#INSTALLATION">Installation</a></li>
<li><a class="el" href="index.html#BUILDINGTOOLS">Building Your Own Tool</a></li>
<li><a class="el" href="index.html#MAKEFILES">Pin's makefile Infrastructure</a></li>
<li><a class="el" href="index.html#FEEDBACK">Feedback</a></li>
<li><a class="el" href="index.html#LEGAL">Disclaimer and Legal Information</a></li>
</ul>
<p>Reference Sections</p><ul>
<li><a class="el" href="group__API__REF.html">Pin API reference</a></li>
<li><a class="el" href="group__KNOBS.html">Pin Command Line Switches</a></li>
<li><a class="el" href="group__INSTLIB.html">Instrumentation Library</a></li>
</ul>
<p><br />
</p><hr/>
<h1><a class="anchor" id="INSTRUMENTING"></a>
How to Instrument with Pin</h1>
<hr/>
<p>Table of Contents</p><ul>
<li><a class="el" href="index.html#Pin">Pin</a></li>
<li><a class="el" href="index.html#Pintools">Pintools</a></li>
<li><a class="el" href="index.html#Observations">Observations</a></li>
<li><a class="el" href="index.html#GRAN">Instrumentation Granularity</a></li>
<li><a class="el" href="index.html#JIT_API">Managed platforms support</a></li>
<li><a class="el" href="index.html#SYMBOLS">Symbols</a></li>
<li><a class="el" href="index.html#FP">Floating Point Support in Analysis Routines</a></li>
<li><a class="el" href="index.html#MT">Instrumenting Multi-threaded Applications</a></li>
<li><a class="el" href="index.html#Deadlock">Avoiding Deadlocks in Multi-threaded Applications</a></li>
</ul>
<h2><a class="anchor" id="Pin"></a>
Pin</h2>
<p>The best way to think about Pin is as a "just in time" (JIT) compiler. The input to this compiler is not bytecode, however, but a regular executable. Pin intercepts the execution of the first instruction of the executable and generates ("compiles") new code for the straight line code sequence starting at this instruction. It then transfers control to the generated sequence. The generated code sequence is almost identical to the original one, but Pin ensures that it regains control when a branch exits the sequence. After regaining control, Pin generates more code for the branch target and continues execution. Pin makes this efficient by keeping all of the generated code in memory so it can be reused and directly branching from one sequence to another.</p>
<p>In JIT mode, the only code ever executed is the generated code. The original code is only used for reference. When generating code, Pin gives the user an opportunity to inject their own code (instrumentation).</p>
<p>Pin instruments all instructions that are actually excuted. It does not matter in what section they reside. Although there are some exceptions for conditional branches, generally speaking, if an instruction is never executed then it will not be instrumented.</p>
<h2><a class="anchor" id="Pintools"></a>
Pintools</h2>
<p>Conceptually, instrumentation consists of two components:</p>
<ul>
<li>A mechanism that decides where and what code is inserted</li>
<li>The code to execute at insertion points</li>
</ul>
<p>These two components are <em>instrumentation</em> and <em>analysis</em> code. Both components live in a single executable, a <em>Pintool</em>. Pintools can be thought of as plugins that can modify the code generation process inside Pin.</p>
<p>The Pintool registers instrumentation callback routines with Pin that are called from Pin whenever new code needs to be generated. This instrumentation callback routine represents the instrumentation component. It inspects the code to be generated, investigates its static properties, and decides if and where to inject calls to analysis functions.</p>
<p>The analysis function gathers data about the application. Pin makes sure that the integer and floating point register state is saved and restored as necessary and allow arguments to be passed to the functions.</p>
<p>The Pintool can also register notification callback routines for events such as thread creation or forking. These callbacks are generally used to gather data or tool initialization or clean up.</p>
<h2><a class="anchor" id="Observations"></a>
Observations</h2>
<p>Since a Pintool works like a plugin, it must run in the same address space as Pin and the executable to be instrumented. Hence the Pintool has access to all of the executable's data. It also shares file descriptors and other process information with the executable.</p>
<p>Pin and the Pintool control a program starting with the very first instruction. For executables compiled with shared libraries this implies that the execution of the dynamic loader and all shared libraries will be visible to the Pintool.</p>
<p>When writing tools, it is more important to tune the analysis code than the instrumentation code. This is because the instrumentation is executed once, but analysis code is called many times.</p>
<h2><a class="anchor" id="GRAN"></a>
Instrumentation Granularity</h2>
<p>As described above, Pin's instrumentation is "just in time" (JIT). Instrumentation occurs immediately before a code sequence is executed for the first time. We call this mode of operation <em> trace instrumentation </em>.</p>
<p>Trace instrumentation lets the Pintool inspect and instrument an executable one trace at a time. Traces usually begin at the target of a taken branch and end with an unconditional branch, including calls and returns. Pin guarantees that a trace is only entered at the top, but it may contain multiple exits. If a branch joins the middle of a trace, Pin constructs a new trace that begins with the branch target. Pin breaks the trace into basic blocks, <em>BBLs</em>. A BBL is a single entrance, single exit sequence of instructions. Branches to the middle of a bbl begin a new trace and hence a new BBL. It is often possible to insert a single analysis call for a BBL, instead of one analysis call for every instruction. Reducing the number of analysis calls makes instrumentation more efficient. Trace instrumentation utilizes the TRACE_AddInstrumentFunction API call.</p>
<p>Note, though, that since Pin is discovering the control flow of the program dynamically as it executes, Pin's BBL can be different from the classical definition of a BBL which you will find in a compiler textbook. For instance, consider the code generated for the body of a switch statement like this </p><div class="fragment"><div class="line"><span class="keywordflow">switch</span>(i)</div><div class="line">{</div><div class="line"> <span class="keywordflow">case</span> 4: total++;</div><div class="line"> <span class="keywordflow">case</span> 3: total++;</div><div class="line"> <span class="keywordflow">case</span> 2: total++;</div><div class="line"> <span class="keywordflow">case</span> 1: total++;</div><div class="line"> <span class="keywordflow">case</span> 0:</div><div class="line"> <span class="keywordflow">default</span>: <span class="keywordflow">break</span>;</div><div class="line">}</div></div><!-- fragment --><p>It will generate instructions something like this (for the IA-32 architecture) </p><div class="fragment"><div class="line">.L7:</div><div class="line"> addl $1, -4(%ebp)</div><div class="line">.L6:</div><div class="line"> addl $1, -4(%ebp)</div><div class="line">.L5:</div><div class="line"> addl $1, -4(%ebp)</div><div class="line">.L4:</div><div class="line"> addl $1, -4(%ebp)</div></div><!-- fragment --><p>In terms of classical basic blocks, each addl instruction is in a single instruction basic block. However as the different switch cases are executed, Pin will generate BBLs which contain all four instructions (when the .L7 case is entered), three instructions (when the .L6 case is entered), and so on. This means that counting Pin BBLs is unlikely to give the count you would expect if you thought that Pin BBLs were the same as the basic blocks in the text book. Here, for instance, if the code branches to .L7 you will count one Pin BBL, but there are four classical basic blocks executed.</p>
<p>Pin also breaks BBLs on some other instructions which may be unexpected, for instance cpuid, popf and REP prefixed instructions all end traces and therefore BBLs. Since REP prefixed instructions are treated as implicit loops, if a REP prefixed instruction iterates more than once, iterations after the first will cause a single instruction BBL to be generated, so in this case you would see more basic blocks executed than you might expect.</p>
<p>As a convenience for Pintool writers, Pin also offers an <em> instruction instrumentation </em> mode which lets the tool inspect and instrument an executable a single instruction at a time. This is essentially identical to trace instrumentation where the Pintool writer has been freed from the responsibilty of iterating over the instructions inside a trace. As decribed under trace instrumentation, certain BBLs and the instructions inside of them may be generated (and hence instrumented) multiple times. Instruction instrumentation utilizes the INS_AddInstrumentFunction API call.</p>
<p>Sometimes, however, it can be useful to look at different granularity than a trace. For this purpose Pin offers two additional modes: image and routine instrumentation. These modes are implemented by "caching" instrumentation requests and hence incur a space overhead, these modes are aslo referred to as ahead-of-time instrumentation.</p>
<p>Image instrumentation lets the Pintool inspect and instrument an entire image, IMG, when it is first loaded. A Pintool can walk the sections, SEC, of the image, the routines, RTN, of a section, and the instructions, INS of a routine. Instrumentation can be inserted so that it is executed before or after a routine is executed, or before or after an instruction is executed. Image instrumentation utilizes the IMG_AddInstrumentFunction API call. Image instrumentation depends on symbol information to determine routine boundaries hence PIN_InitSymbols must be called before PIN_Init.</p>
<p>Routine instrumentation lets the Pintool inspect and instrument an entire routine when the image it is contained in is first loaded. A Pintool can walk the instructions of a routine. There is not enough information available to break the instructions into BBLs. Instrumentation can be inserted so that it is executed before or after a routine is executed, or before or after an instruction is executed. Routine instrumentation is provided as a convenience for Pintool writers, as an alternative to walking the sections and routines of the image during the Image instrumentation, as described in the previous paragraph.</p>
<p>Routine instrumentation utilizes the RTN_AddInstrumentFunction API call. Instrumentation of routine exits does not work reliably in the presence of tail calls or when return instructions cannot reliably be detected.</p>
<p>Note that in both Image and Routine instrumentation, it is not possible to know whether or not a routine will actually be executed (since these instrumentations are done at image load time). It is possible to walk the instructions only of routines that are executed, in the Trace or Instruction instrumentation routines, by identifying instructions that are the start of routines. See the tool Tests/parse_executed_rtns.cpp.</p>
<h2><a class="anchor" id="JIT_API"></a>
Managed platforms support</h2>
<p>Pin supports all executables including the managed binaries. From Pin point of view managed binary is one more kind of a self-modifying program. There is a way to cause Pin to differentiate the just-in-time compiled code (Jitted code) from all other dynamically generated code and associate Jitted code with appropriate managed functions. To get this functionality, the just-in-time compiler (Jitter) of the running managed platform should support <a href="https://software.intel.com/en-us/node/544211">Jit Profiling API</a></p>
<p>The following capabilities are supported:</p><ul>
<li><a class="el" href="group__RTN__BASIC__API.html#ga260a065245b69511e0071b2b469f854b">RTN_IsDynamic()</a> API is used to indentify dynamically created code. A routine can be marked as dynamically created using Jit Profiling API only.</li>
<li>A Pintool can instrument Jitted routines using RTN_AddInstrumentFunction API See the examples <a class="el" href="index.html#JitApiTools">Managed platforms support</a> for more information.</li>
</ul>
<p>Following conditions must be satisfied to get the managed platforms support: </p><ul>
<li>
<p class="startli">Set LD_LIBRARY_PATH environment variables to include pinjitprofiling dynamic library and Pin CRT libraries location.</p>
<p class="endli"></p>
</li>
<li>
<p class="startli">Add the knob support_jit_api to the Pin command line as Pintool option:</p>
<div class="fragment"><div class="line">&lt;Pin executable&gt; &lt;Pin options&gt; -t &lt;Pintool&gt; -support_jit_api &lt;Other Pintool options&gt; -- &lt;Test application&gt; &lt;Test application options&gt;</div></div><!-- fragment --><p class="endli"></p>
</li>
</ul>
<h2><a class="anchor" id="SYMBOLS"></a>
Symbols</h2>
<p>Pin provides access to function names using the symbol object (SYM). Symbol objects only provide information about the function symbols in the application. Information about other types of symbols (e.g. data symbols), must be obtained independently by the tool.</p>
<p>On Windows, you can use dbghelp.dll for this. Note that using dbghelp.dll in an instrumented process is not safe and can cause dead-locks in some cases. A possible solution is to find symbols using a different non-instrumented process.</p>
<p>On Linux, libelf.so or libdwarf.so can be used to access symbol information.</p>
<p>PIN_InitSymbols must be called to access functions by name. See <a class="el" href="group__SYM__BASIC__API.html">SYM: Symbol Object</a> for more information.</p>
<h2><a class="anchor" id="FP"></a>
Floating Point Support in Analysis Routines</h2>
<p>Pin takes care of maintaining the application's floating point state accross analysis routines.</p>
<p>IARG_REG_VALUE cannot be used to pass floating point register values as arguments to analysis routines.</p>
<h2><a class="anchor" id="MT"></a>
Instrumenting Multi-threaded Applications</h2>
<p>Instrumenting a multi-threaded program requires that the tool be thread safe - access to global storage must be coordinated with other threads. Pin tries to provide a conventional C++ program environment for tools, but it is not possible to use the standard library interfaces to manage threads in a Pintool. For example, Linux tools cannot use the pthreads library and Windows tools should not use the Win32 API's to manage threads. Instead, Pin provides its own locking and thread management API's, which the Pintool should use. (See <a class="el" href="group__LOCK.html">LOCK: Locking Primitives</a> and <a class="el" href="group__PIN__THREAD__API.html">Pin Thread API</a>.)</p>
<p>Pintools do not need to add explicit locking to instrumentation routines because Pin calls these routines while holding an internal lock called the VM lock. However, Pin does execute analysis and replacement functions in parallel, so Pintools may need to add locking to these routines if they access global data.</p>
<p>Pintools on Linux also need to take care when calling standard C or C++ library routines from analysis or replacement functions because the C and C++ libraries linked into Pintools are <b>not</b> thread-safe. Some simple C / C++ routines are safe to call without locking, because their implementations are inherently thread-safe, however, Pin does not attempt to provide a list of safe routines. If you are in doubt, you should add locking around calls to library functions. In particular, the "errno" value is not multi-thread safe, so tools that use this should provide their own locking. Note that these restrictions only exist on the Unix platforms, as the library routines on Windows are thread safe.</p>
<p>Pin provides call-backs when each thread starts and ends (see PIN_AddThreadStartFunction and PIN_AddThreadFiniFunction). These provide a convenient place for a Pintool to allocate and manipulate thread local data and store it on a thread's local storage.</p>
<p>Pin also provides an analysis routine argument (IARG_THREAD_ID), which passes a Pin-specific thread ID for the calling thread. This ID is different from the O/S system thread ID, and is a small number starting at 0, which can be used as an index to an array of thread data or as the locking value to Pin user locks. See the example <a class="el" href="index.html#MallocMT">Instrumenting Threaded Applications</a> for more information.</p>
<p>In addition to the Pin thread ID, the Pin API provides an efficient thread local storage (TLS), with the option to allocate a new TLS key and associate it with a given data destruction function. Any thread of the process can store and retrieve values in its own slot, referenced by the allocated key. The initial value associated with the key in all threads is NULL. See the example <a class="el" href="index.html#InscountTLS">Using TLS</a> for more information.</p>
<p>False sharing occurs when multiple threads access different parts of the same cache line and at least one of them is a write. To maintain memory coherency, the computer must copy the memory from one CPU's cache to another, even though data is not truly shared. False sharing can usually be avoided by padding critical data structures to the size of a cache line, or by rearranging the data layout of structures. See the example <a class="el" href="index.html#InscountTLS">Using TLS</a> for more information.</p>
<h2><a class="anchor" id="Deadlock"></a>
Avoiding Deadlocks in Multi-threaded Applications</h2>
<p>Since Pin, the tool, and the application may each acquire and release locks, Pintool developers must take care to avoid deadlocks with either the application or Pin. Deadlocks generally occur when two threads acquire the same locks in a different order. For example, thread A acquires lock L1 and then acquires lock L2, while thread B acquires lock L2 and then acquires lock L1. This will lead to a deadlock if thread A holds lock L1 and waits for L2 while thread B holds lock L2 and waits for L1. To avoid such deadlocks, Pin imposes a hierarchy on the order in which locks must be acquired. Pin generally acquires its own internal locks before the tool acquires any lock (e.g. via <a class="el" href="group__LOCK.html#ga9569245cd781216f8f1a54d3a0962ddf">PIN_GetLock()</a>). Additionally, we assume that the application may acquire locks at the top of this hierarchy (i.e. before Pin acquires its internal locks). The following diagram illustrates the hierarchy: </p><pre class="fragment">Application locks -&gt; Pin internal locks -&gt; Tool locks
</pre><p> Pintool developers should design their Pintools such that they never break this lock hierarchy, and they can do so by following these basic guidelines:</p><ul>
<li>If the tool acquires any locks from within a Pin call-back, it must release those locks before returning from that call-back. Holding a lock across Pin call-backs violates the hierarchy with respect to the Pin internal locks.</li>
<li>If the tool acquires any locks from within an analysis routine, it must release those locks before returning from the analysis routine. Holding a lock across Pin analysis routines violates the hierarchy with respect to Pin internal locks and other locks used by the instrumented application itself.</li>
<li>If the tool calls a Pin API from within a Pin call-back or analysis routine, it should not hold any tool locks when calling the API. Some of the Pin APIs use the internal Pin locks so holding a tool lock before invoking these APIs violates the hierarchy with respect to the Pin internal locks.</li>
<li>If the tool calls a Pin API from within an analysis routine, it may need to acquire the Pin client lock first by calling <a class="el" href="group__PIN__CONTROL.html#gadf5abd51ee9b1d599c539a9e2784e9ef">PIN_LockClient()</a>. This depends on the API, so check the documentation for the specific API for more information. Note that the tool should not hold any other locks when calling <a class="el" href="group__PIN__CONTROL.html#gadf5abd51ee9b1d599c539a9e2784e9ef">PIN_LockClient()</a>, as described in the previous item.</li>
</ul>
<p>While these guidelines are sufficient in most cases, they may turn out to be too restrictive for certain use-cases. The next set of guidelines explains the conditions in which it is safe to relax the basic guidelines above:</p><ul>
<li>In JIT mode, the tool may acquire locks from within an analysis routine and not release them, providing it releases these locks before leaving the trace that contains the analysis routine. The tool must expect that the trace may exit "early" if an application instruction raises an exception. Any lock <code>L</code>, which the tool might hold when the application raises an exception, must obey the following sub-rules:<ul>
<li>The tool must establish a call-back that executes when the application raises an exception and this call-back must release lock <code>L</code> if it was acquired at the time the exception occurred. Tools can use <a class="el" href="group__PIN__CONTROL.html#ga786fd61c9be3c42a1a6deefc71dffadf">PIN_AddContextChangeFunction()</a> to establish this call-back.</li>
<li>The tool must not acquire lock <code>L</code> from within any Pin call-back, to avoid violating the hierarchy with respect to the Pin internal locks.</li>
</ul>
</li>
<li>If the tool calls a Pin API from an analysis routine, it may acquire and hold a lock <code>L</code> while calling the API providing that:<ul>
<li>Lock <code>L</code> is not being acquired from any Pin call-back. This avoids the hierarchy violation with respect to the Pin internal locks.</li>
<li>The Pin API being invoked does not cause application code to execute (e.g., <a class="el" href="group__PIN__CONTROL.html#ga5ae5853e6600a23f9c552cba784870cc">PIN_CallApplicationFunction()</a>). This avoids the hierarchy violation with respect to the locks used by the application itself.</li>
</ul>
</li>
</ul>
<p><br />
</p><hr/>
<h1><a class="anchor" id="EXAMPLES"></a>
Examples</h1>
<hr/>
<p>Table of Contents</p><ul>
<li><a class="el" href="index.html#BuildingExamples">Building the Example Tools</a></li>
<li><a class="el" href="index.html#WindowsNotes">Notes for Building Tools for Windows</a></li>
<li><a class="el" href="index.html#SimpleCount">Simple Instruction Count (Instruction Instrumentation)</a></li>
<li><a class="el" href="index.html#IAddressTrace">Instruction Address Trace (Instruction Instrumentation)</a></li>
<li><a class="el" href="index.html#MAddressTrace">Memory Reference Trace (Instruction Instrumentation)</a></li>
<li><a class="el" href="index.html#ImageLoad">Detecting the Loading and Unloading of Images (Image Instrumentation)</a></li>
<li><a class="el" href="index.html#inscount1">More Efficient Instruction Counting (Trace Instrumentation)</a></li>
<li><a class="el" href="index.html#ProcInstrCount">Procedure Instruction Count (Routine Instrumentation)</a></li>
<li><a class="el" href="index.html#SafeCopy">Using PIN_SafeCopy()</a></li>
<li><a class="el" href="index.html#Invocation">Order of Instrumentation</a></li>
<li><a class="el" href="index.html#FunctionArguments">Finding the Value of Function Arguments</a></li>
<li><a class="el" href="index.html#FindSymbol">Finding Functions By Name on Windows</a></li>
<li><a class="el" href="index.html#MallocMT">Instrumenting Threaded Applications</a></li>
<li><a class="el" href="index.html#InscountTLS">Using TLS</a></li>
<li><a class="el" href="index.html#Buffering">Using the Fast Buffering APIs</a></li>
<li><a class="el" href="index.html#StaticInstructionCounts">Finding the Static Properties of an Image</a></li>
<li><a class="el" href="index.html#DetachPin">Detaching Pin from the Application</a></li>
<li><a class="el" href="index.html#ReplaceSigProbed">Replacing a Routine in Probe Mode</a></li>
<li><a class="el" href="index.html#FollowChild">Instrumenting Child Processes</a></li>
<li><a class="el" href="index.html#ForkOnLinux">Instrumenting Before and After Forks</a></li>
<li><a class="el" href="index.html#JitApiTools">Managed platforms support</a></li>
</ul>
<p>To illustrate how to write Pintools, we present some simple examples. In the web based version of the manual, you can click on a function in the Pin API to see its documentation.</p>
<p>All the examples presented in the manual can be found in the source/tools/ManualExamples directory.</p>
<h2><a class="anchor" id="BuildingExamples"></a>
Building the Example Tools</h2>
<p>To build all examples in a directory for ia32 architecture: </p><pre class="fragment">$ cd source/tools/ManualExamples
$ make all TARGET=ia32
</pre><p>To build all examples in a directory for intel64 architecture: </p><pre class="fragment">$ cd source/tools/ManualExamples
$ make all TARGET=intel64
</pre><p>To build and run a specific example (e.g., inscount0): </p><pre class="fragment">$ cd source/tools/ManualExamples
$ make inscount0.test TARGET=intel64
</pre><p>To build a specific example without running it (e.g., inscount0): </p><pre class="fragment">$ cd source/tools/ManualExamples
$ make obj-intel64/inscount0.so TARGET=intel64
</pre><p>The above applies to the Intel(R) 64 architecture. For the IA-32 architecture, use TARGET=ia32 instead. </p><pre class="fragment">$ cd source/tools/ManualExamples
$ make obj-ia32/inscount0.so TARGET=ia32
</pre><h2><a class="anchor" id="WindowsNotes"></a>
Notes for Building Tools for Windows</h2>
<p>Since the tools are built using make, be sure to install cygwin make first.</p>
<p>Open the Visual Studio Command Prompt corresponding to your target architecture, i.e. x86 or x64, and follow the steps in the <a class="el" href="index.html#BuildingExamples">Building the Example Tools</a> section.</p>
<h2><a class="anchor" id="SimpleCount"></a>
Simple Instruction Count (Instruction Instrumentation)</h2>
<p>The example below instruments a program to count the total number of instructions executed. It inserts a call to <code>docount</code> before every instruction. When the program exits, it saves the count in the file <code>inscount.out</code>.</p>
<p>Here is how to run it and display its output (note that the file list is the <code>ls</code> output, so it may be different on your machine, similarly the instruction count will depend on the implementation of <code>ls</code>):</p>
<pre class="fragment">$ ../../../pin -t obj-intel64/inscount0.so -- /bin/ls
Makefile atrace.o imageload.out itrace proccount
Makefile.example imageload inscount0 itrace.o proccount.o
atrace imageload.o inscount0.o itrace.out
$ cat inscount.out
Count 422838
$
</pre><p>The KNOB exhibited in the example below overwrites the default name for the output file. To use this feature, add "-o &lt;file_name&gt;" to the command line. Tool command line options should be inserted between the tool name and the double dash ("--"). For more information on how to add command line options to your tool, please see <a class="el" href="group__KNOB__API.html">KNOB: Commandline Option Handling</a>.</p>
<pre class="fragment">$ ../../../pin -t obj-intel64/inscount0.so -o inscount0.log -- /bin/ls
</pre><p>The example can be found in source/tools/ManualExamples/inscount0.cpp</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;fstream&gt;</span></div><div class="line"><span class="preprocessor">#include &quot;pin.H&quot;</span></div><div class="line"><span class="keyword">using</span> std::cerr;</div><div class="line"><span class="keyword">using</span> std::ofstream;</div><div class="line"><span class="keyword">using</span> std::ios;</div><div class="line"><span class="keyword">using</span> std::string;</div><div class="line"><span class="keyword">using</span> std::endl;</div><div class="line"></div><div class="line">ofstream OutFile;</div><div class="line"></div><div class="line"><span class="comment">// The running count of instructions is kept here</span></div><div class="line"><span class="comment">// make it static to help the compiler optimize docount</span></div><div class="line"><span class="keyword">static</span> UINT64 icount = 0;</div><div class="line"></div><div class="line"><span class="comment">// This function is called before every instruction is executed</span></div><div class="line">VOID docount() { icount++; }</div><div class="line"> </div><div class="line"><span class="comment">// Pin calls this function every time a new instruction is encountered</span></div><div class="line">VOID Instruction(INS ins, VOID *v)</div><div class="line">{</div><div class="line"> <span class="comment">// Insert a call to docount before every instruction, no arguments are passed</span></div><div class="line"> <a class="code" href="group__INS__INST__API.html#ga74a956a0acde197043d04f4adcde4626">INS_InsertCall</a>(ins, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>, (AFUNPTR)docount, IARG_END);</div><div class="line">}</div><div class="line"></div><div class="line">KNOB&lt;string&gt; KnobOutputFile(<a class="code" href="group__KNOB__BASIC.html#ggad45510089e3b85a88df038e900e9f8baa576ddd3b58b1121ff4070df605951cf6">KNOB_MODE_WRITEONCE</a>, <span class="stringliteral">&quot;pintool&quot;</span>,</div><div class="line"> <span class="stringliteral">&quot;o&quot;</span>, <span class="stringliteral">&quot;inscount.out&quot;</span>, <span class="stringliteral">&quot;specify output file name&quot;</span>);</div><div class="line"></div><div class="line"><span class="comment">// This function is called when the application exits</span></div><div class="line">VOID Fini(INT32 code, VOID *v)</div><div class="line">{</div><div class="line"> <span class="comment">// Write to a file since cout and cerr maybe closed by the application</span></div><div class="line"> OutFile.setf(ios::showbase);</div><div class="line"> OutFile &lt;&lt; <span class="stringliteral">&quot;Count &quot;</span> &lt;&lt; icount &lt;&lt; endl;</div><div class="line"> OutFile.close();</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Print Help Message */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line">INT32 Usage()</div><div class="line">{</div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot;This tool counts the number of dynamic instructions executed&quot;</span> &lt;&lt; endl;</div><div class="line"> cerr &lt;&lt; endl &lt;&lt; KNOB_BASE::StringKnobSummary() &lt;&lt; endl;</div><div class="line"> <span class="keywordflow">return</span> -1;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Main */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* argc, argv are the entire command line: pin -t &lt;toolname&gt; -- ... */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> * argv[])</div><div class="line">{</div><div class="line"> <span class="comment">// Initialize pin</span></div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__PIN__CONTROL.html#ga783d3bd40c3fb2ca51b1f9af31a70c9c">PIN_Init</a>(argc, argv)) <span class="keywordflow">return</span> Usage();</div><div class="line"></div><div class="line"> OutFile.open(KnobOutputFile.Value().c_str());</div><div class="line"></div><div class="line"> <span class="comment">// Register Instruction to be called to instrument instructions</span></div><div class="line"> <a class="code" href="group__INS__INST__API.html#gaaff4a98e0ece27fc46c0050b4ae05c6d">INS_AddInstrumentFunction</a>(Instruction, 0);</div><div class="line"></div><div class="line"> <span class="comment">// Register Fini to be called when the application exits</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gac167b8d28d255e53a0ac1f6e9edcd3ec">PIN_AddFiniFunction</a>(Fini, 0);</div><div class="line"> </div><div class="line"> <span class="comment">// Start the program, never returns</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gaded401aeb030a76ee3396137b06ad808">PIN_StartProgram</a>();</div><div class="line"> </div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment --><h2><a class="anchor" id="IAddressTrace"></a>
Instruction Address Trace (Instruction Instrumentation)</h2>
<p>In the previous example, we did not pass any arguments to <code>docount</code>, the analysis procedure. In this example, we show how to pass arguments. When calling an analysis procedure, Pin allows you to pass the instruction pointer, current value of registers, effective address of memory operations, constants, etc. For a complete list, see <a class="el" href="group__INST__ARGS.html#ga089c27ca15e9ff139dd3a3f8a6f8451d">IARG_TYPE</a>.</p>
<p>With a small change, we can turn the instruction counting example into a Pintool that prints the address of every instruction that is executed. This tool is useful for understanding the control flow of a program for debugging, or in processor design when simulating an instruction cache.</p>
<p>We change the arguments to INS_InsertCall to pass the address of the instruction about to be executed. We replace <code>docount</code> with <code>printip</code>, which prints the instruction address. It writes its output to the file <code>itrace.out</code>.</p>
<p>This is how to run it and look at the output:</p>
<pre class="fragment">$ ../../../pin -t obj-intel64/itrace.so -- /bin/ls
Makefile atrace.o imageload.out itrace proccount
Makefile.example imageload inscount0 itrace.o proccount.o
atrace imageload.o inscount0.o itrace.out
$ head itrace.out
0x40001e90
0x40001e91
0x40001ee4
0x40001ee5
0x40001ee7
0x40001ee8
0x40001ee9
0x40001eea
0x40001ef0
0x40001ee0
$
</pre><p>The example can be found in source/tools/ManualExamples/itrace.cpp</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &lt;stdio.h&gt;</span></div><div class="line"><span class="preprocessor">#include &quot;pin.H&quot;</span></div><div class="line"></div><div class="line">FILE * trace;</div><div class="line"></div><div class="line"><span class="comment">// This function is called before every instruction is executed</span></div><div class="line"><span class="comment">// and prints the IP</span></div><div class="line">VOID printip(VOID *ip) { fprintf(trace, <span class="stringliteral">&quot;%p\n&quot;</span>, ip); }</div><div class="line"></div><div class="line"><span class="comment">// Pin calls this function every time a new instruction is encountered</span></div><div class="line">VOID Instruction(INS ins, VOID *v)</div><div class="line">{</div><div class="line"> <span class="comment">// Insert a call to printip before every instruction, and pass it the IP</span></div><div class="line"> <a class="code" href="group__INS__INST__API.html#ga74a956a0acde197043d04f4adcde4626">INS_InsertCall</a>(ins, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>, (AFUNPTR)printip, <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da623ad95758bce14fcb9427beef53736a">IARG_INST_PTR</a>, IARG_END);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// This function is called when the application exits</span></div><div class="line">VOID Fini(INT32 code, VOID *v)</div><div class="line">{</div><div class="line"> fprintf(trace, <span class="stringliteral">&quot;#eof\n&quot;</span>);</div><div class="line"> fclose(trace);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Print Help Message */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line">INT32 Usage()</div><div class="line">{</div><div class="line"> PIN_ERROR(<span class="stringliteral">&quot;This Pintool prints the IPs of every instruction executed\n&quot;</span> </div><div class="line"> + KNOB_BASE::StringKnobSummary() + <span class="stringliteral">&quot;\n&quot;</span>);</div><div class="line"> <span class="keywordflow">return</span> -1;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Main */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> * argv[])</div><div class="line">{</div><div class="line"> trace = fopen(<span class="stringliteral">&quot;itrace.out&quot;</span>, <span class="stringliteral">&quot;w&quot;</span>);</div><div class="line"> </div><div class="line"> <span class="comment">// Initialize pin</span></div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__PIN__CONTROL.html#ga783d3bd40c3fb2ca51b1f9af31a70c9c">PIN_Init</a>(argc, argv)) <span class="keywordflow">return</span> Usage();</div><div class="line"></div><div class="line"> <span class="comment">// Register Instruction to be called to instrument instructions</span></div><div class="line"> <a class="code" href="group__INS__INST__API.html#gaaff4a98e0ece27fc46c0050b4ae05c6d">INS_AddInstrumentFunction</a>(Instruction, 0);</div><div class="line"></div><div class="line"> <span class="comment">// Register Fini to be called when the application exits</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gac167b8d28d255e53a0ac1f6e9edcd3ec">PIN_AddFiniFunction</a>(Fini, 0);</div><div class="line"> </div><div class="line"> <span class="comment">// Start the program, never returns</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gaded401aeb030a76ee3396137b06ad808">PIN_StartProgram</a>();</div><div class="line"> </div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment --><h2><a class="anchor" id="MAddressTrace"></a>
Memory Reference Trace (Instruction Instrumentation)</h2>
<p>The previous example instruments all instructions. Sometimes a tool may only want to instrument a class of instructions, like memory operations or branch instructions. A tool can do this by using the Pin API which includes functions that classify and examine instructions. The basic API is common to all instruction sets and is described <a class="el" href="group__INS__BASIC__API.html">here.</a> In addition, there is an instruction set specific API for the <a class="el" href="group__INS__BASIC__API__IA32.html">IA-32 ISA.</a></p>
<p>In this example, we show how to do more selective instrumentation by examining the instructions. This tool generates a trace of all memory addresses referenced by a program. This is also useful for debugging and for simulating a data cache in a processor.</p>
<p>We only instrument instructions that read or write memory. We also use INS_InsertPredicatedCall instead of INS_InsertCall to avoid generating references to instructions that are predicated when the predicate is false. On IA-32 and Intel(R) 64 architectures CMOVcc, FCMOVcc and REP prefixed string operations are treated as being predicated. For CMOVcc and FCMOVcc the predicate is the condition test implied by "cc", for REP prefixed string ops it is that the count register is non-zero.</p>
<p>Since the instrumentation functions are only called once and the analysis functions are called every time an instruction is executed, it is much faster to instrument only the memory operations, as compared to the previous instruction trace example that instruments every instruction.</p>
<p>Here is how to run it and the sample output:</p>
<pre class="fragment">$ ../../../pin -t obj-intel64/pinatrace.so -- /bin/ls
Makefile atrace.o imageload.o inscount0.o itrace.out
Makefile.example atrace.out imageload.out itrace proccount
atrace imageload inscount0 itrace.o proccount.o
$ head pinatrace.out
0x40001ee0: R 0xbfffe798
0x40001efd: W 0xbfffe7d4
0x40001f09: W 0xbfffe7d8
0x40001f20: W 0xbfffe864
0x40001f20: W 0xbfffe868
0x40001f20: W 0xbfffe86c
0x40001f20: W 0xbfffe870
0x40001f20: W 0xbfffe874
0x40001f20: W 0xbfffe878
0x40001f20: W 0xbfffe87c
$
</pre><p>The example can be found in source/tools/ManualExamples/pinatrace.cpp</p>
<div class="fragment"><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"> * This file contains an ISA-portable PIN tool for tracing memory accesses.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"></div><div class="line"><span class="preprocessor">#include &lt;stdio.h&gt;</span></div><div class="line"><span class="preprocessor">#include &quot;pin.H&quot;</span></div><div class="line"></div><div class="line"></div><div class="line">FILE * trace;</div><div class="line"></div><div class="line"><span class="comment">// Print a memory read record</span></div><div class="line">VOID RecordMemRead(VOID * ip, VOID * addr)</div><div class="line">{</div><div class="line"> fprintf(trace,<span class="stringliteral">&quot;%p: R %p\n&quot;</span>, ip, addr);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// Print a memory write record</span></div><div class="line">VOID RecordMemWrite(VOID * ip, VOID * addr)</div><div class="line">{</div><div class="line"> fprintf(trace,<span class="stringliteral">&quot;%p: W %p\n&quot;</span>, ip, addr);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// Is called for every instruction and instruments reads and writes</span></div><div class="line">VOID Instruction(INS ins, VOID *v)</div><div class="line">{</div><div class="line"> <span class="comment">// Instruments memory accesses using a predicated call, i.e.</span></div><div class="line"> <span class="comment">// the instrumentation is called iff the instruction will actually be executed.</span></div><div class="line"> <span class="comment">//</span></div><div class="line"> <span class="comment">// On the IA-32 and Intel(R) 64 architectures conditional moves and REP </span></div><div class="line"> <span class="comment">// prefixed instructions appear as predicated instructions in Pin.</span></div><div class="line"> UINT32 memOperands = <a class="code" href="group__INS__BASIC__API__GEN__IA32.html#ga138b553c79c6e39fe5f3858a7a60c854">INS_MemoryOperandCount</a>(ins);</div><div class="line"></div><div class="line"> <span class="comment">// Iterate over each memory operand of the instruction.</span></div><div class="line"> <span class="keywordflow">for</span> (UINT32 memOp = 0; memOp &lt; memOperands; memOp++)</div><div class="line"> {</div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__INS__BASIC__API__GEN__IA32.html#ga3fdb434cd56a5b72be15dd0931a2b19c">INS_MemoryOperandIsRead</a>(ins, memOp))</div><div class="line"> {</div><div class="line"> <a class="code" href="group__INS__INST__API.html#ga26d02bff719bf8600421895956804252">INS_InsertPredicatedCall</a>(</div><div class="line"> ins, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>, (AFUNPTR)RecordMemRead,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da623ad95758bce14fcb9427beef53736a">IARG_INST_PTR</a>,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da985747a3c70e3a4283fc8a2f16399e63">IARG_MEMORYOP_EA</a>, memOp,</div><div class="line"> IARG_END);</div><div class="line"> }</div><div class="line"> <span class="comment">// Note that in some architectures a single memory operand can be </span></div><div class="line"> <span class="comment">// both read and written (for instance incl (%eax) on IA-32)</span></div><div class="line"> <span class="comment">// In that case we instrument it once for read and once for write.</span></div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__INS__BASIC__API__GEN__IA32.html#gacd65d0a0a6033d2d8115183705def544">INS_MemoryOperandIsWritten</a>(ins, memOp))</div><div class="line"> {</div><div class="line"> <a class="code" href="group__INS__INST__API.html#ga26d02bff719bf8600421895956804252">INS_InsertPredicatedCall</a>(</div><div class="line"> ins, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>, (AFUNPTR)RecordMemWrite,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da623ad95758bce14fcb9427beef53736a">IARG_INST_PTR</a>,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da985747a3c70e3a4283fc8a2f16399e63">IARG_MEMORYOP_EA</a>, memOp,</div><div class="line"> IARG_END);</div><div class="line"> }</div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line">VOID Fini(INT32 code, VOID *v)</div><div class="line">{</div><div class="line"> fprintf(trace, <span class="stringliteral">&quot;#eof\n&quot;</span>);</div><div class="line"> fclose(trace);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Print Help Message */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"> </div><div class="line">INT32 Usage()</div><div class="line">{</div><div class="line"> PIN_ERROR( <span class="stringliteral">&quot;This Pintool prints a trace of memory addresses\n&quot;</span> </div><div class="line"> + KNOB_BASE::StringKnobSummary() + <span class="stringliteral">&quot;\n&quot;</span>);</div><div class="line"> <span class="keywordflow">return</span> -1;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Main */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> *argv[])</div><div class="line">{</div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__PIN__CONTROL.html#ga783d3bd40c3fb2ca51b1f9af31a70c9c">PIN_Init</a>(argc, argv)) <span class="keywordflow">return</span> Usage();</div><div class="line"></div><div class="line"> trace = fopen(<span class="stringliteral">&quot;pinatrace.out&quot;</span>, <span class="stringliteral">&quot;w&quot;</span>);</div><div class="line"></div><div class="line"> <a class="code" href="group__INS__INST__API.html#gaaff4a98e0ece27fc46c0050b4ae05c6d">INS_AddInstrumentFunction</a>(Instruction, 0);</div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gac167b8d28d255e53a0ac1f6e9edcd3ec">PIN_AddFiniFunction</a>(Fini, 0);</div><div class="line"></div><div class="line"> <span class="comment">// Never returns</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gaded401aeb030a76ee3396137b06ad808">PIN_StartProgram</a>();</div><div class="line"> </div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment --><h2><a class="anchor" id="ImageLoad"></a>
Detecting the Loading and Unloading of Images (Image Instrumentation)</h2>
<p>The example below prints a message to a trace file every time and image is loaded or unloaded. It really abuses the image instrumentation mode as the Pintool neither inspects the image nor adds instrumentation code.</p>
<p>If you invoke it on ls, you would see this output:</p>
<pre class="fragment">$ ../../../pin -t obj-intel64/imageload.so -- /bin/ls
Makefile atrace.o imageload.o inscount0.o proccount
Makefile.example atrace.out imageload.out itrace proccount.o
atrace imageload inscount0 itrace.o trace.out
$ cat imageload.out
Loading /bin/ls
Loading /lib/ld-linux.so.2
Loading /lib/libtermcap.so.2
Loading /lib/i686/libc.so.6
Unloading /bin/ls
Unloading /lib/ld-linux.so.2
Unloading /lib/libtermcap.so.2
Unloading /lib/i686/libc.so.6
$
</pre><p>The example can be found in source/tools/ManualExamples/imageload.cpp</p>
<div class="fragment"><div class="line"><span class="comment">//</span></div><div class="line"><span class="comment">// This tool prints a trace of image load and unload events</span></div><div class="line"><span class="comment">//</span></div><div class="line"></div><div class="line"><span class="preprocessor">#include &quot;pin.H&quot;</span></div><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;fstream&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;stdlib.h&gt;</span></div><div class="line"><span class="keyword">using</span> std::ofstream;</div><div class="line"><span class="keyword">using</span> std::string;</div><div class="line"><span class="keyword">using</span> std::endl;</div><div class="line"></div><div class="line"></div><div class="line">KNOB&lt;string&gt; KnobOutputFile(<a class="code" href="group__KNOB__BASIC.html#ggad45510089e3b85a88df038e900e9f8baa576ddd3b58b1121ff4070df605951cf6">KNOB_MODE_WRITEONCE</a>, <span class="stringliteral">&quot;pintool&quot;</span>,</div><div class="line"> <span class="stringliteral">&quot;o&quot;</span>, <span class="stringliteral">&quot;imageload.out&quot;</span>, <span class="stringliteral">&quot;specify file name&quot;</span>);</div><div class="line"></div><div class="line">ofstream TraceFile;</div><div class="line"></div><div class="line"><span class="comment">// Pin calls this function every time a new img is loaded</span></div><div class="line"><span class="comment">// It can instrument the image, but this example does not</span></div><div class="line"><span class="comment">// Note that imgs (including shared libraries) are loaded lazily</span></div><div class="line"></div><div class="line">VOID ImageLoad(IMG img, VOID *v)</div><div class="line">{</div><div class="line"> TraceFile &lt;&lt; <span class="stringliteral">&quot;Loading &quot;</span> &lt;&lt; <a class="code" href="group__IMG__BASIC__API.html#ga22acd549352fc062c6c62c82e7a09354">IMG_Name</a>(img) &lt;&lt; <span class="stringliteral">&quot;, Image id = &quot;</span> &lt;&lt; <a class="code" href="group__IMG__BASIC__API.html#gae9802263d9ceb357e46f215d86294548">IMG_Id</a>(img) &lt;&lt; endl;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// Pin calls this function every time a new img is unloaded</span></div><div class="line"><span class="comment">// You can&#39;t instrument an image that is about to be unloaded</span></div><div class="line">VOID ImageUnload(IMG img, VOID *v)</div><div class="line">{</div><div class="line"> TraceFile &lt;&lt; <span class="stringliteral">&quot;Unloading &quot;</span> &lt;&lt; <a class="code" href="group__IMG__BASIC__API.html#ga22acd549352fc062c6c62c82e7a09354">IMG_Name</a>(img) &lt;&lt; endl;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// This function is called when the application exits</span></div><div class="line"><span class="comment">// It closes the output file.</span></div><div class="line">VOID Fini(INT32 code, VOID *v)</div><div class="line">{</div><div class="line"> <span class="keywordflow">if</span> (TraceFile.is_open()) { TraceFile.close(); }</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Print Help Message */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line">INT32 Usage()</div><div class="line">{</div><div class="line"> PIN_ERROR(<span class="stringliteral">&quot;This tool prints a log of image load and unload events\n&quot;</span></div><div class="line"> + KNOB_BASE::StringKnobSummary() + <span class="stringliteral">&quot;\n&quot;</span>);</div><div class="line"> <span class="keywordflow">return</span> -1;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Main */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> * argv[])</div><div class="line">{</div><div class="line"> <span class="comment">// Initialize symbol processing</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#ga8cf4aca0b0bdbc7fc0ae965883d8e3c2">PIN_InitSymbols</a>();</div><div class="line"> </div><div class="line"> <span class="comment">// Initialize pin</span></div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__PIN__CONTROL.html#ga783d3bd40c3fb2ca51b1f9af31a70c9c">PIN_Init</a>(argc, argv)) <span class="keywordflow">return</span> Usage();</div><div class="line"> </div><div class="line"> TraceFile.open(KnobOutputFile.Value().c_str());</div><div class="line"> </div><div class="line"> <span class="comment">// Register ImageLoad to be called when an image is loaded</span></div><div class="line"> <a class="code" href="group__IMG__BASIC__API.html#ga494869187b5d94d7dd346bc9ff49642f">IMG_AddInstrumentFunction</a>(ImageLoad, 0);</div><div class="line"></div><div class="line"> <span class="comment">// Register ImageUnload to be called when an image is unloaded</span></div><div class="line"> <a class="code" href="group__IMG__BASIC__API.html#gadd37dea66b2c1c46ef45d77023926a95">IMG_AddUnloadFunction</a>(ImageUnload, 0);</div><div class="line"></div><div class="line"> <span class="comment">// Register Fini to be called when the application exits</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gac167b8d28d255e53a0ac1f6e9edcd3ec">PIN_AddFiniFunction</a>(Fini, 0);</div><div class="line"> </div><div class="line"> <span class="comment">// Start the program, never returns</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gaded401aeb030a76ee3396137b06ad808">PIN_StartProgram</a>();</div><div class="line"> </div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment --><h2><a class="anchor" id="inscount1"></a>
More Efficient Instruction Counting (Trace Instrumentation)</h2>
<p>The example <a class="el" href="index.html#SimpleCount">Simple Instruction Count (Instruction Instrumentation)</a> computed the number of executed instructions by inserting a call before every instruction. In this example, we make it more efficient by counting the number of instructions in a BBL at instrumentation time, and incrementing the counter once per BBL, instead of once per instruction.</p>
<p>The example can be found in source/tools/ManualExamples/inscount1.cpp</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;fstream&gt;</span></div><div class="line"><span class="preprocessor">#include &quot;pin.H&quot;</span></div><div class="line"><span class="keyword">using</span> std::cerr;</div><div class="line"><span class="keyword">using</span> std::ofstream;</div><div class="line"><span class="keyword">using</span> std::ios;</div><div class="line"><span class="keyword">using</span> std::string;</div><div class="line"><span class="keyword">using</span> std::endl;</div><div class="line"></div><div class="line">ofstream OutFile;</div><div class="line"></div><div class="line"><span class="comment">// The running count of instructions is kept here</span></div><div class="line"><span class="comment">// make it static to help the compiler optimize docount</span></div><div class="line"><span class="keyword">static</span> UINT64 icount = 0;</div><div class="line"></div><div class="line"><span class="comment">// This function is called before every block</span></div><div class="line">VOID docount(UINT32 c) { icount += c; }</div><div class="line"> </div><div class="line"><span class="comment">// Pin calls this function every time a new basic block is encountered</span></div><div class="line"><span class="comment">// It inserts a call to docount</span></div><div class="line">VOID Trace(<a class="code" href="group__TRACE__BASIC__API.html#gaf9f3009a146688d5230a16f8d3e575be">TRACE</a> trace, VOID *v)</div><div class="line">{</div><div class="line"> <span class="comment">// Visit every basic block in the trace</span></div><div class="line"> <span class="keywordflow">for</span> (BBL bbl = <a class="code" href="group__TRACE__BASIC__API.html#ga008abc5ba1af8d9e9cd073ffe0aefa18">TRACE_BblHead</a>(trace); <a class="code" href="group__BBL__BASIC__API.html#ga58a8d019cd09ce46cfe431ec8f14a075">BBL_Valid</a>(bbl); bbl = <a class="code" href="group__BBL__BASIC__API.html#gadd7141abb47139b52922e04e0c4a10f3">BBL_Next</a>(bbl))</div><div class="line"> {</div><div class="line"> <span class="comment">// Insert a call to docount before every bbl, passing the number of instructions</span></div><div class="line"> <a class="code" href="group__BBL__BASIC__API.html#gaeee9d7a6253d49d226bbed3f35768169">BBL_InsertCall</a>(bbl, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>, (AFUNPTR)docount, <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dabd19b79248899659441e56e4738d5bfd">IARG_UINT32</a>, <a class="code" href="group__BBL__BASIC__API.html#ga76ceb2d9e0fb974d3c3769b2413ed634">BBL_NumIns</a>(bbl), IARG_END);</div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line">KNOB&lt;string&gt; KnobOutputFile(<a class="code" href="group__KNOB__BASIC.html#ggad45510089e3b85a88df038e900e9f8baa576ddd3b58b1121ff4070df605951cf6">KNOB_MODE_WRITEONCE</a>, <span class="stringliteral">&quot;pintool&quot;</span>,</div><div class="line"> <span class="stringliteral">&quot;o&quot;</span>, <span class="stringliteral">&quot;inscount.out&quot;</span>, <span class="stringliteral">&quot;specify output file name&quot;</span>);</div><div class="line"></div><div class="line"><span class="comment">// This function is called when the application exits</span></div><div class="line">VOID Fini(INT32 code, VOID *v)</div><div class="line">{</div><div class="line"> <span class="comment">// Write to a file since cout and cerr maybe closed by the application</span></div><div class="line"> OutFile.setf(ios::showbase);</div><div class="line"> OutFile &lt;&lt; <span class="stringliteral">&quot;Count &quot;</span> &lt;&lt; icount &lt;&lt; endl;</div><div class="line"> OutFile.close();</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Print Help Message */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line">INT32 Usage()</div><div class="line">{</div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot;This tool counts the number of dynamic instructions executed&quot;</span> &lt;&lt; endl;</div><div class="line"> cerr &lt;&lt; endl &lt;&lt; KNOB_BASE::StringKnobSummary() &lt;&lt; endl;</div><div class="line"> <span class="keywordflow">return</span> -1;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Main */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> * argv[])</div><div class="line">{</div><div class="line"> <span class="comment">// Initialize pin</span></div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__PIN__CONTROL.html#ga783d3bd40c3fb2ca51b1f9af31a70c9c">PIN_Init</a>(argc, argv)) <span class="keywordflow">return</span> Usage();</div><div class="line"></div><div class="line"> OutFile.open(KnobOutputFile.Value().c_str());</div><div class="line"></div><div class="line"> <span class="comment">// Register Instruction to be called to instrument instructions</span></div><div class="line"> <a class="code" href="group__TRACE__BASIC__API.html#ga41381de13d25c4bbd968cb64cb719d56">TRACE_AddInstrumentFunction</a>(Trace, 0);</div><div class="line"></div><div class="line"> <span class="comment">// Register Fini to be called when the application exits</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gac167b8d28d255e53a0ac1f6e9edcd3ec">PIN_AddFiniFunction</a>(Fini, 0);</div><div class="line"> </div><div class="line"> <span class="comment">// Start the program, never returns</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gaded401aeb030a76ee3396137b06ad808">PIN_StartProgram</a>();</div><div class="line"> </div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment --><h2><a class="anchor" id="ProcInstrCount"></a>
Procedure Instruction Count (Routine Instrumentation)</h2>
<p>The example below instruments a program to count the number of times a procedure is called, and the total number of instructions executed in each procedure. When it finishes, it prints a profile to proccount.out</p>
<p>Executing the tool and sample output:</p>
<pre class="fragment">$ ../../../pin -t obj-intel64/proccount.so -- /bin/grep proccount.cpp Makefile
proccount_SOURCES = proccount.cpp
$ head proccount.out
Procedure Image Address Calls Instructions
_fini libc.so.6 0x40144d00 1 21
__deregister_frame_info libc.so.6 0x40143f60 2 70
__register_frame_info libc.so.6 0x40143df0 2 62
fde_merge libc.so.6 0x40143870 0 8
__init_misc libc.so.6 0x40115824 1 85
__getclktck libc.so.6 0x401157f4 0 2
munmap libc.so.6 0x40112ca0 1 9
mmap libc.so.6 0x40112bb0 1 23
getpagesize libc.so.6 0x4010f934 2 26
$
</pre><p>The example can be found in source/tools/ManualExamples/proccount.cpp</p>
<div class="fragment"><div class="line"><span class="comment">//</span></div><div class="line"><span class="comment">// This tool counts the number of times a routine is executed and </span></div><div class="line"><span class="comment">// the number of instructions executed in a routine</span></div><div class="line"><span class="comment">//</span></div><div class="line"></div><div class="line"><span class="preprocessor">#include &lt;fstream&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;iomanip&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;string.h&gt;</span></div><div class="line"><span class="preprocessor">#include &quot;pin.H&quot;</span></div><div class="line"><span class="keyword">using</span> std::ofstream;</div><div class="line"><span class="keyword">using</span> std::string;</div><div class="line"><span class="keyword">using</span> std::hex;</div><div class="line"><span class="keyword">using</span> std::setw;</div><div class="line"><span class="keyword">using</span> std::cerr;</div><div class="line"><span class="keyword">using</span> std::dec;</div><div class="line"><span class="keyword">using</span> std::endl;</div><div class="line"></div><div class="line">ofstream outFile;</div><div class="line"></div><div class="line"><span class="comment">// Holds instruction count for a single procedure</span></div><div class="line"><span class="keyword">typedef</span> <span class="keyword">struct </span>RtnCount</div><div class="line">{</div><div class="line"> <span class="keywordtype">string</span> _name;</div><div class="line"> <span class="keywordtype">string</span> _image;</div><div class="line"> ADDRINT _address;</div><div class="line"> RTN _rtn;</div><div class="line"> UINT64 _rtnCount;</div><div class="line"> UINT64 _icount;</div><div class="line"> <span class="keyword">struct </span>RtnCount * _next;</div><div class="line">} RTN_COUNT;</div><div class="line"></div><div class="line"><span class="comment">// Linked list of instruction counts for each routine</span></div><div class="line">RTN_COUNT * RtnList = 0;</div><div class="line"></div><div class="line"><span class="comment">// This function is called before every instruction is executed</span></div><div class="line">VOID docount(UINT64 * counter)</div><div class="line">{</div><div class="line"> (*counter)++;</div><div class="line">}</div><div class="line"> </div><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span> * StripPath(<span class="keyword">const</span> <span class="keywordtype">char</span> * path)</div><div class="line">{</div><div class="line"> <span class="keyword">const</span> <span class="keywordtype">char</span> * file = strrchr(path,<span class="charliteral">&#39;/&#39;</span>);</div><div class="line"> <span class="keywordflow">if</span> (file)</div><div class="line"> <span class="keywordflow">return</span> file+1;</div><div class="line"> <span class="keywordflow">else</span></div><div class="line"> <span class="keywordflow">return</span> path;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// Pin calls this function every time a new rtn is executed</span></div><div class="line">VOID Routine(RTN rtn, VOID *v)</div><div class="line">{</div><div class="line"> </div><div class="line"> <span class="comment">// Allocate a counter for this routine</span></div><div class="line"> RTN_COUNT * rc = <span class="keyword">new</span> RTN_COUNT;</div><div class="line"></div><div class="line"> <span class="comment">// The RTN goes away when the image is unloaded, so save it now</span></div><div class="line"> <span class="comment">// because we need it in the fini</span></div><div class="line"> rc-&gt;_name = <a class="code" href="group__RTN__BASIC__API.html#gacac860956fa8cf004a51e823e81a2ac0">RTN_Name</a>(rtn);</div><div class="line"> rc-&gt;_image = StripPath(<a class="code" href="group__IMG__BASIC__API.html#ga22acd549352fc062c6c62c82e7a09354">IMG_Name</a>(<a class="code" href="group__SEC__BASIC__API.html#gac57c906aeabfa47c07300e6a70d70c05">SEC_Img</a>(<a class="code" href="group__RTN__BASIC__API.html#ga4883c839d424578a9f6983d05e6a9a12">RTN_Sec</a>(rtn))).c_str());</div><div class="line"> rc-&gt;_address = <a class="code" href="group__RTN__BASIC__API.html#ga83a81fae96c9faabe0f1c90a0d7e865f">RTN_Address</a>(rtn);</div><div class="line"> rc-&gt;_icount = 0;</div><div class="line"> rc-&gt;_rtnCount = 0;</div><div class="line"></div><div class="line"> <span class="comment">// Add to list of routines</span></div><div class="line"> rc-&gt;_next = RtnList;</div><div class="line"> RtnList = rc;</div><div class="line"> </div><div class="line"> <a class="code" href="group__RTN__BASIC__API.html#gaf8714086f8aebc9feacccc8cd02dc561">RTN_Open</a>(rtn);</div><div class="line"> </div><div class="line"> <span class="comment">// Insert a call at the entry point of a routine to increment the call count</span></div><div class="line"> <a class="code" href="group__RTN__BASIC__API.html#ga76bde295a78d1232fd6ff98a5ff011cf">RTN_InsertCall</a>(rtn, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>, (AFUNPTR)docount, <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da7a11763427dff3afb81caab97b02881b">IARG_PTR</a>, &amp;(rc-&gt;_rtnCount), IARG_END);</div><div class="line"> </div><div class="line"> <span class="comment">// For each instruction of the routine</span></div><div class="line"> <span class="keywordflow">for</span> (INS ins = <a class="code" href="group__RTN__BASIC__API.html#gab1bd91206939b88057664c46ef8eac86">RTN_InsHead</a>(rtn); <a class="code" href="group__INS__BASIC__API__GEN__IA32.html#ga3a8b61fffa9ae4ad9f899b21ce37397c">INS_Valid</a>(ins); ins = <a class="code" href="group__INS__BASIC__API__GEN__IA32.html#ga227ce58a739b1573125c11071ecb48de">INS_Next</a>(ins))</div><div class="line"> {</div><div class="line"> <span class="comment">// Insert a call to docount to increment the instruction counter for this rtn</span></div><div class="line"> <a class="code" href="group__INS__INST__API.html#ga74a956a0acde197043d04f4adcde4626">INS_InsertCall</a>(ins, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>, (AFUNPTR)docount, <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da7a11763427dff3afb81caab97b02881b">IARG_PTR</a>, &amp;(rc-&gt;_icount), IARG_END);</div><div class="line"> }</div><div class="line"></div><div class="line"> </div><div class="line"> <a class="code" href="group__RTN__BASIC__API.html#ga37272253377eb65c9eb5ff47ec4f1e6b">RTN_Close</a>(rtn);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// This function is called when the application exits</span></div><div class="line"><span class="comment">// It prints the name and count for each procedure</span></div><div class="line">VOID Fini(INT32 code, VOID *v)</div><div class="line">{</div><div class="line"> outFile &lt;&lt; setw(23) &lt;&lt; <span class="stringliteral">&quot;Procedure&quot;</span> &lt;&lt; <span class="stringliteral">&quot; &quot;</span></div><div class="line"> &lt;&lt; setw(15) &lt;&lt; <span class="stringliteral">&quot;Image&quot;</span> &lt;&lt; <span class="stringliteral">&quot; &quot;</span></div><div class="line"> &lt;&lt; setw(18) &lt;&lt; <span class="stringliteral">&quot;Address&quot;</span> &lt;&lt; <span class="stringliteral">&quot; &quot;</span></div><div class="line"> &lt;&lt; setw(12) &lt;&lt; <span class="stringliteral">&quot;Calls&quot;</span> &lt;&lt; <span class="stringliteral">&quot; &quot;</span></div><div class="line"> &lt;&lt; setw(12) &lt;&lt; <span class="stringliteral">&quot;Instructions&quot;</span> &lt;&lt; endl;</div><div class="line"></div><div class="line"> <span class="keywordflow">for</span> (RTN_COUNT * rc = RtnList; rc; rc = rc-&gt;_next)</div><div class="line"> {</div><div class="line"> <span class="keywordflow">if</span> (rc-&gt;_icount &gt; 0)</div><div class="line"> outFile &lt;&lt; setw(23) &lt;&lt; rc-&gt;_name &lt;&lt; <span class="stringliteral">&quot; &quot;</span></div><div class="line"> &lt;&lt; setw(15) &lt;&lt; rc-&gt;_image &lt;&lt; <span class="stringliteral">&quot; &quot;</span></div><div class="line"> &lt;&lt; setw(18) &lt;&lt; hex &lt;&lt; rc-&gt;_address &lt;&lt; dec &lt;&lt;<span class="stringliteral">&quot; &quot;</span></div><div class="line"> &lt;&lt; setw(12) &lt;&lt; rc-&gt;_rtnCount &lt;&lt; <span class="stringliteral">&quot; &quot;</span></div><div class="line"> &lt;&lt; setw(12) &lt;&lt; rc-&gt;_icount &lt;&lt; endl;</div><div class="line"> }</div><div class="line"></div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Print Help Message */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line">INT32 Usage()</div><div class="line">{</div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot;This Pintool counts the number of times a routine is executed&quot;</span> &lt;&lt; endl;</div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot;and the number of instructions executed in a routine&quot;</span> &lt;&lt; endl;</div><div class="line"> cerr &lt;&lt; endl &lt;&lt; KNOB_BASE::StringKnobSummary() &lt;&lt; endl;</div><div class="line"> <span class="keywordflow">return</span> -1;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Main */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> * argv[])</div><div class="line">{</div><div class="line"> <span class="comment">// Initialize symbol table code, needed for rtn instrumentation</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#ga8cf4aca0b0bdbc7fc0ae965883d8e3c2">PIN_InitSymbols</a>();</div><div class="line"></div><div class="line"> outFile.open(<span class="stringliteral">&quot;proccount.out&quot;</span>);</div><div class="line"></div><div class="line"> <span class="comment">// Initialize pin</span></div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__PIN__CONTROL.html#ga783d3bd40c3fb2ca51b1f9af31a70c9c">PIN_Init</a>(argc, argv)) <span class="keywordflow">return</span> Usage();</div><div class="line"></div><div class="line"> <span class="comment">// Register Routine to be called to instrument rtn</span></div><div class="line"> <a class="code" href="group__RTN__BASIC__API.html#gad10b9862dbe2f9bef8f7978492c35d01">RTN_AddInstrumentFunction</a>(Routine, 0);</div><div class="line"></div><div class="line"> <span class="comment">// Register Fini to be called when the application exits</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gac167b8d28d255e53a0ac1f6e9edcd3ec">PIN_AddFiniFunction</a>(Fini, 0);</div><div class="line"> </div><div class="line"> <span class="comment">// Start the program, never returns</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gaded401aeb030a76ee3396137b06ad808">PIN_StartProgram</a>();</div><div class="line"> </div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment --><h2><a class="anchor" id="SafeCopy"></a>
Using PIN_SafeCopy()</h2>
<p>PIN_SafeCopy is used to copy the specified number of bytes from a source memory region to a destination memory region. This function guarantees safe return to the caller even if the source or destination regions are inaccessible (entirely or partially).</p>
<p>Use of this function also guarantees that the tool reads or writes the values used by the application. For example, on Windows, Pin replaces certain TEB fields when running a tool's analysis code. If the tool accessed these fields directly, it would see the modified values rather than the original ones. Using <a class="el" href="group__PIN__CONTROL.html#ga98669d2f5629027689d60bd852ffa0eb">PIN_SafeCopy()</a> allows the tool to read or write the application's values for these fields.</p>
<p>We recommend using this API any time a tool reads or writes application memory.</p>
<pre class="fragment">$ ../../../pin -t obj-ia32/safecopy.so -- /bin/cp makefile obj-ia32/safecopy.so.makefile.copy
$ head safecopy.out
Emulate loading from addr 0xbff0057c to ebx
Emulate loading from addr 0x64ffd4 to eax
Emulate loading from addr 0xbff00598 to esi
Emulate loading from addr 0x6501c8 to edi
Emulate loading from addr 0x64ff14 to edx
Emulate loading from addr 0x64ff1c to edx
Emulate loading from addr 0x64ff24 to edx
Emulate loading from addr 0x64ff2c to edx
Emulate loading from addr 0x64ff34 to edx
Emulate loading from addr 0x64ff3c to edx
</pre><p>The example can be found in source/tools/ManualExamples/safecopy.cpp.</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &lt;stdio.h&gt;</span></div><div class="line"><span class="preprocessor">#include &quot;pin.H&quot;</span></div><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;fstream&gt;</span></div><div class="line"><span class="keyword">using</span> std::cerr;</div><div class="line"><span class="keyword">using</span> std::endl;</div><div class="line"></div><div class="line">std::ofstream* out = 0;</div><div class="line"></div><div class="line"><span class="comment">//=======================================================</span></div><div class="line"><span class="comment">// Analysis routines</span></div><div class="line"><span class="comment">//=======================================================</span></div><div class="line"></div><div class="line"><span class="comment">// Move from memory to register</span></div><div class="line">ADDRINT DoLoad(<a class="code" href="group__REG__CPU__IA32.html#ga0f57fb50e80d686a588694f73046f2aa">REG</a> reg, ADDRINT * addr)</div><div class="line">{</div><div class="line"> *out &lt;&lt; <span class="stringliteral">&quot;Emulate loading from addr &quot;</span> &lt;&lt; addr &lt;&lt; <span class="stringliteral">&quot; to &quot;</span> &lt;&lt; <a class="code" href="group__REG__CPU__GENERIC.html#ga44ff31760c2de7aae1d8b4bb0cc06729">REG_StringShort</a>(reg) &lt;&lt; endl;</div><div class="line"> ADDRINT value;</div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#ga98669d2f5629027689d60bd852ffa0eb">PIN_SafeCopy</a>(&amp;value, addr, <span class="keyword">sizeof</span>(ADDRINT));</div><div class="line"> <span class="keywordflow">return</span> value;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">//=======================================================</span></div><div class="line"><span class="comment">// Instrumentation routines</span></div><div class="line"><span class="comment">//=======================================================</span></div><div class="line"></div><div class="line">VOID EmulateLoad(INS ins, VOID* v)</div><div class="line">{</div><div class="line"> <span class="comment">// Find the instructions that move a value from memory to a register</span></div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__INS__BASIC__API__GEN__IA32.html#gac8414d9f7927f82817901f0fd209158a">INS_Opcode</a>(ins) == XED_ICLASS_MOV &amp;&amp;</div><div class="line"> <a class="code" href="group__INS__BASIC__API__GEN__IA32.html#ga53406fedba9cbde8633a8da58c262e31">INS_IsMemoryRead</a>(ins) &amp;&amp;</div><div class="line"> <a class="code" href="group__INS__BASIC__API__IA32.html#ga47e1a53b42fde8d1206482e17d7545ed">INS_OperandIsReg</a>(ins, 0) &amp;&amp;</div><div class="line"> <a class="code" href="group__INS__BASIC__API__IA32.html#gae3250a73461f2f78b3ce333ca3d1a7da">INS_OperandIsMemory</a>(ins, 1))</div><div class="line"> {</div><div class="line"> <span class="comment">// op0 &lt;- *op1</span></div><div class="line"> <a class="code" href="group__INS__INST__API.html#ga74a956a0acde197043d04f4adcde4626">INS_InsertCall</a>(ins,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>,</div><div class="line"> AFUNPTR(DoLoad),</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dabd19b79248899659441e56e4738d5bfd">IARG_UINT32</a>,</div><div class="line"> <a class="code" href="group__REG__CPU__IA32.html#ga0f57fb50e80d686a588694f73046f2aa">REG</a>(<a class="code" href="group__INS__BASIC__API__IA32.html#ga8392f6469bf5e04b59b390fa5b433918">INS_OperandReg</a>(ins, 0)),</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da2138787daf04a57e6684eb0b368e120e">IARG_MEMORYREAD_EA</a>,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da6c8569ef37241134ffc6e24593275981">IARG_RETURN_REGS</a>,</div><div class="line"> <a class="code" href="group__INS__BASIC__API__IA32.html#ga8392f6469bf5e04b59b390fa5b433918">INS_OperandReg</a>(ins, 0),</div><div class="line"> IARG_END);</div><div class="line"></div><div class="line"> <span class="comment">// Delete the instruction</span></div><div class="line"> <a class="code" href="group__INS__MOD__API__GEN__IA32.html#gad37791f157338a12e22f8d9c54f09fe4">INS_Delete</a>(ins);</div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Print Help Message */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line">INT32 Usage()</div><div class="line">{</div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot;This tool demonstrates the use of SafeCopy&quot;</span> &lt;&lt; endl;</div><div class="line"> cerr &lt;&lt; endl &lt;&lt; KNOB_BASE::StringKnobSummary() &lt;&lt; endl;</div><div class="line"> <span class="keywordflow">return</span> -1;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Main */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> * argv[])</div><div class="line">{</div><div class="line"> <span class="comment">// Write to a file since cout and cerr maybe closed by the application</span></div><div class="line"> out = <span class="keyword">new</span> std::ofstream(<span class="stringliteral">&quot;safecopy.out&quot;</span>);</div><div class="line"></div><div class="line"> <span class="comment">// Initialize pin &amp; symbol manager</span></div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__PIN__CONTROL.html#ga783d3bd40c3fb2ca51b1f9af31a70c9c">PIN_Init</a>(argc, argv)) <span class="keywordflow">return</span> Usage();</div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#ga8cf4aca0b0bdbc7fc0ae965883d8e3c2">PIN_InitSymbols</a>();</div><div class="line"></div><div class="line"> <span class="comment">// Register EmulateLoad to be called to instrument instructions</span></div><div class="line"> <a class="code" href="group__INS__INST__API.html#gaaff4a98e0ece27fc46c0050b4ae05c6d">INS_AddInstrumentFunction</a>(EmulateLoad, 0);</div><div class="line"></div><div class="line"> <span class="comment">// Never returns</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gaded401aeb030a76ee3396137b06ad808">PIN_StartProgram</a>();</div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment --><h2><a class="anchor" id="Invocation"></a>
Order of Instrumentation</h2>
<p>Pin provides tools with multiple ways to control the exection order of analysis calls. The exection order depends mainly on the insertion action (<a class="el" href="group__INST__ARGS.html#ga707ea08e31f44f4a81e2a7766123bad7">IPOINT</a>) and call order (<a class="el" href="group__INST__ARGS.html#ga3d1d5f6805cb16d00bce441290ca2212">CALL_ORDER</a>). The example below illustrates this behavior by instrumenting all return instructions in three different ways. Additional examples can be found in source/tools/InstrumentationOrderAndVersion.</p>
<pre class="fragment">$ ../../../pin -t obj-ia32/invocation.so -- obj-ia32/little_malloc
$ head invocation.out
After: IP = 0x64bc5e
Before: IP = 0x64bc5e
Taken: IP = 0x63a12e
After: IP = 0x64bc5e
Before: IP = 0x64bc5e
Taken: IP = 0x641c76
After: IP = 0x641ca6
After: IP = 0x64bc5e
Before: IP = 0x64bc5e
Taken: IP = 0x648b02
</pre><p>The example can be found in source/tools/ManualExamples/invocation.cpp.</p>
<div class="fragment"><div class="line"></div><div class="line"><span class="preprocessor">#include &quot;pin.H&quot;</span></div><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;fstream&gt;</span></div><div class="line"><span class="keyword">using</span> std::ofstream;</div><div class="line"><span class="keyword">using</span> std::string;</div><div class="line"><span class="keyword">using</span> std::ios;</div><div class="line"><span class="keyword">using</span> std::hex;</div><div class="line"><span class="keyword">using</span> std::cerr;</div><div class="line"><span class="keyword">using</span> std::dec;</div><div class="line"><span class="keyword">using</span> std::endl;</div><div class="line"></div><div class="line"></div><div class="line">KNOB&lt;string&gt; KnobOutputFile(<a class="code" href="group__KNOB__BASIC.html#ggad45510089e3b85a88df038e900e9f8baa576ddd3b58b1121ff4070df605951cf6">KNOB_MODE_WRITEONCE</a>, <span class="stringliteral">&quot;pintool&quot;</span>,</div><div class="line"> <span class="stringliteral">&quot;o&quot;</span>, <span class="stringliteral">&quot;invocation.out&quot;</span>, <span class="stringliteral">&quot;specify output file name&quot;</span>);</div><div class="line"></div><div class="line">ofstream OutFile;</div><div class="line"></div><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"> * Analysis routines</span></div><div class="line"><span class="comment"> */</span></div><div class="line">VOID Taken( <span class="keyword">const</span> <a class="code" href="group__CONTEXT__API.html#ga73f8f88949aaecf53a6d23f56399c676">CONTEXT</a> * ctxt)</div><div class="line">{</div><div class="line"> ADDRINT TakenIP = (ADDRINT)<a class="code" href="group__CONTEXT__API.html#gac1358a6179f0a63300fdf34ecf8b741d">PIN_GetContextReg</a>( ctxt, REG_INST_PTR );</div><div class="line"> OutFile &lt;&lt; <span class="stringliteral">&quot;Taken: IP = &quot;</span> &lt;&lt; hex &lt;&lt; TakenIP &lt;&lt; dec &lt;&lt; endl;</div><div class="line">}</div><div class="line"></div><div class="line">VOID Before(<a class="code" href="group__CONTEXT__API.html#ga73f8f88949aaecf53a6d23f56399c676">CONTEXT</a> * ctxt)</div><div class="line">{</div><div class="line"> ADDRINT BeforeIP = (ADDRINT)<a class="code" href="group__CONTEXT__API.html#gac1358a6179f0a63300fdf34ecf8b741d">PIN_GetContextReg</a>( ctxt, REG_INST_PTR);</div><div class="line"> OutFile &lt;&lt; <span class="stringliteral">&quot;Before: IP = &quot;</span> &lt;&lt; hex &lt;&lt; BeforeIP &lt;&lt; dec &lt;&lt; endl;</div><div class="line">}</div><div class="line"></div><div class="line"></div><div class="line">VOID After(<a class="code" href="group__CONTEXT__API.html#ga73f8f88949aaecf53a6d23f56399c676">CONTEXT</a> * ctxt)</div><div class="line">{</div><div class="line"> ADDRINT AfterIP = (ADDRINT)<a class="code" href="group__CONTEXT__API.html#gac1358a6179f0a63300fdf34ecf8b741d">PIN_GetContextReg</a>( ctxt, REG_INST_PTR);</div><div class="line"> OutFile &lt;&lt; <span class="stringliteral">&quot;After: IP = &quot;</span> &lt;&lt; hex &lt;&lt; AfterIP &lt;&lt; dec &lt;&lt; endl;</div><div class="line">}</div><div class="line"></div><div class="line"> </div><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"> * Instrumentation routines</span></div><div class="line"><span class="comment"> */</span></div><div class="line">VOID ImageLoad(IMG img, VOID *v)</div><div class="line">{</div><div class="line"> <span class="keywordflow">for</span> (SEC sec = <a class="code" href="group__IMG__BASIC__API.html#gaa9597e002a76d7a5e5e1b530bb263aad">IMG_SecHead</a>(img); <a class="code" href="group__SEC__BASIC__API.html#ga584ce38ee42410cf65bb5c7201760663">SEC_Valid</a>(sec); sec = <a class="code" href="group__SEC__BASIC__API.html#ga0f20232da7164c5a2bd7a484218cfa36">SEC_Next</a>(sec))</div><div class="line"> {</div><div class="line"> <span class="comment">// RTN_InsertCall() and INS_InsertCall() are executed in order of</span></div><div class="line"> <span class="comment">// appearance. In the code sequence below, the IPOINT_AFTER is</span></div><div class="line"> <span class="comment">// executed before the IPOINT_BEFORE.</span></div><div class="line"> <span class="keywordflow">for</span> (RTN rtn = <a class="code" href="group__SEC__BASIC__API.html#ga2b837186aae0819ca2389253438d22b9">SEC_RtnHead</a>(sec); <a class="code" href="group__RTN__BASIC__API.html#ga6ac855c9a19a3aab44347188e6695875">RTN_Valid</a>(rtn); rtn = <a class="code" href="group__RTN__BASIC__API.html#ga491bf55c9718f8751054ebe37b460d65">RTN_Next</a>(rtn))</div><div class="line"> {</div><div class="line"> <span class="comment">// Open the RTN.</span></div><div class="line"> <a class="code" href="group__RTN__BASIC__API.html#gaf8714086f8aebc9feacccc8cd02dc561">RTN_Open</a>( rtn );</div><div class="line"> </div><div class="line"> <span class="comment">// IPOINT_AFTER is implemented by instrumenting each return</span></div><div class="line"> <span class="comment">// instruction in a routine. Pin tries to find all return</span></div><div class="line"> <span class="comment">// instructions, but success is not guaranteed.</span></div><div class="line"> <a class="code" href="group__RTN__BASIC__API.html#ga76bde295a78d1232fd6ff98a5ff011cf">RTN_InsertCall</a>( rtn, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a42eff26179c6d87348abe492301c12ec">IPOINT_AFTER</a>, (AFUNPTR)After,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da25577a47a3c3945080ce1429959f3f1d">IARG_CONTEXT</a>, IARG_END);</div><div class="line"> </div><div class="line"> <span class="comment">// Examine each instruction in the routine.</span></div><div class="line"> <span class="keywordflow">for</span>( INS ins = <a class="code" href="group__RTN__BASIC__API.html#gab1bd91206939b88057664c46ef8eac86">RTN_InsHead</a>(rtn); <a class="code" href="group__INS__BASIC__API__GEN__IA32.html#ga3a8b61fffa9ae4ad9f899b21ce37397c">INS_Valid</a>(ins); ins = <a class="code" href="group__INS__BASIC__API__GEN__IA32.html#ga227ce58a739b1573125c11071ecb48de">INS_Next</a>(ins) )</div><div class="line"> {</div><div class="line"> <span class="keywordflow">if</span>( <a class="code" href="group__INS__BASIC__API__GEN__IA32.html#gaf35ab682222bdbf641cba586e50c898a">INS_IsRet</a>(ins) )</div><div class="line"> {</div><div class="line"> <span class="comment">// instrument each return instruction.</span></div><div class="line"> <span class="comment">// IPOINT_TAKEN_BRANCH always occurs last.</span></div><div class="line"> <a class="code" href="group__INS__INST__API.html#ga74a956a0acde197043d04f4adcde4626">INS_InsertCall</a>( ins, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>, (AFUNPTR)Before,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da25577a47a3c3945080ce1429959f3f1d">IARG_CONTEXT</a>, IARG_END);</div><div class="line"> <a class="code" href="group__INS__INST__API.html#ga74a956a0acde197043d04f4adcde4626">INS_InsertCall</a>( ins, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a5ef5b45901a8447e5173f50746ab029d">IPOINT_TAKEN_BRANCH</a>, (AFUNPTR)Taken,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da25577a47a3c3945080ce1429959f3f1d">IARG_CONTEXT</a>, IARG_END);</div><div class="line"> }</div><div class="line"> }</div><div class="line"> <span class="comment">// Close the RTN.</span></div><div class="line"> <a class="code" href="group__RTN__BASIC__API.html#ga37272253377eb65c9eb5ff47ec4f1e6b">RTN_Close</a>( rtn );</div><div class="line"> }</div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line">VOID Fini(INT32 code, VOID *v)</div><div class="line">{</div><div class="line"> OutFile.close();</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Print Help Message */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line">INT32 Usage()</div><div class="line">{</div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot;This is the invocation pintool&quot;</span> &lt;&lt; endl;</div><div class="line"> cerr &lt;&lt; endl &lt;&lt; KNOB_BASE::StringKnobSummary() &lt;&lt; endl;</div><div class="line"> <span class="keywordflow">return</span> -1;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Main */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> * argv[])</div><div class="line">{</div><div class="line"> <span class="comment">// Initialize pin &amp; symbol manager</span></div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__PIN__CONTROL.html#ga783d3bd40c3fb2ca51b1f9af31a70c9c">PIN_Init</a>(argc, argv)) <span class="keywordflow">return</span> Usage();</div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#ga8cf4aca0b0bdbc7fc0ae965883d8e3c2">PIN_InitSymbols</a>();</div><div class="line"></div><div class="line"> <span class="comment">// Register ImageLoad to be called to instrument instructions</span></div><div class="line"> <a class="code" href="group__IMG__BASIC__API.html#ga494869187b5d94d7dd346bc9ff49642f">IMG_AddInstrumentFunction</a>(ImageLoad, 0);</div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gac167b8d28d255e53a0ac1f6e9edcd3ec">PIN_AddFiniFunction</a>(Fini, 0);</div><div class="line"></div><div class="line"> <span class="comment">// Write to a file since cout and cerr maybe closed by the application</span></div><div class="line"> OutFile.open(KnobOutputFile.Value().c_str());</div><div class="line"> OutFile.setf(ios::showbase);</div><div class="line"> </div><div class="line"> <span class="comment">// Start the program, never returns</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gaded401aeb030a76ee3396137b06ad808">PIN_StartProgram</a>();</div><div class="line"> </div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line">}</div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"> </div></div><!-- fragment --><h2><a class="anchor" id="FunctionArguments"></a>
Finding the Value of Function Arguments</h2>
<p>Often one needs the know the value of the argument passed into a function, or the return value. You can use Pin to find this information. Using the <a class="el" href="group__RTN__BASIC__API.html#ga76bde295a78d1232fd6ff98a5ff011cf">RTN_InsertCall()</a> function, you can specify the arguments of interest.</p>
<p>The example below prints the input argument for malloc() and free(), and the return value from malloc().</p>
<pre class="fragment">$ ../../../pin -t obj-ia32/malloctrace.so -- /bin/cp makefile obj-ia32/malloctrace.so.makefile.copy
$ head malloctrace.out
malloc(0x24d)
returns 0x6504f8
malloc(0x57)
returns 0x650748
malloc(0xc)
returns 0x6507a0
malloc(0x3c0)
returns 0x6507b0
malloc(0xc)
returns 0x650b70
</pre><p>The example can be found in source/tools/ManualExamples/malloctrace.cpp.</p>
<div class="fragment"><div class="line"></div><div class="line"><span class="preprocessor">#include &quot;pin.H&quot;</span></div><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;fstream&gt;</span></div><div class="line"><span class="keyword">using</span> std::hex;</div><div class="line"><span class="keyword">using</span> std::cerr;</div><div class="line"><span class="keyword">using</span> std::string;</div><div class="line"><span class="keyword">using</span> std::ios;</div><div class="line"><span class="keyword">using</span> std::endl;</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Names of malloc and free */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="preprocessor">#if defined(TARGET_MAC)</span></div><div class="line"><span class="preprocessor">#define MALLOC &quot;_malloc&quot;</span></div><div class="line"><span class="preprocessor">#define FREE &quot;_free&quot;</span></div><div class="line"><span class="preprocessor">#else</span></div><div class="line"><span class="preprocessor">#define MALLOC &quot;malloc&quot;</span></div><div class="line"><span class="preprocessor">#define FREE &quot;free&quot;</span></div><div class="line"><span class="preprocessor">#endif</span></div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Global Variables */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line">std::ofstream TraceFile;</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Commandline Switches */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line">KNOB&lt;string&gt; KnobOutputFile(<a class="code" href="group__KNOB__BASIC.html#ggad45510089e3b85a88df038e900e9f8baa576ddd3b58b1121ff4070df605951cf6">KNOB_MODE_WRITEONCE</a>, <span class="stringliteral">&quot;pintool&quot;</span>,</div><div class="line"> <span class="stringliteral">&quot;o&quot;</span>, <span class="stringliteral">&quot;malloctrace.out&quot;</span>, <span class="stringliteral">&quot;specify trace file name&quot;</span>);</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Analysis routines */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"> </div><div class="line">VOID Arg1Before(CHAR * name, ADDRINT size)</div><div class="line">{</div><div class="line"> TraceFile &lt;&lt; name &lt;&lt; <span class="stringliteral">&quot;(&quot;</span> &lt;&lt; size &lt;&lt; <span class="stringliteral">&quot;)&quot;</span> &lt;&lt; endl;</div><div class="line">}</div><div class="line"></div><div class="line">VOID MallocAfter(ADDRINT ret)</div><div class="line">{</div><div class="line"> TraceFile &lt;&lt; <span class="stringliteral">&quot; returns &quot;</span> &lt;&lt; ret &lt;&lt; endl;</div><div class="line">}</div><div class="line"></div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Instrumentation routines */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"> </div><div class="line">VOID Image(IMG img, VOID *v)</div><div class="line">{</div><div class="line"> <span class="comment">// Instrument the malloc() and free() functions. Print the input argument</span></div><div class="line"> <span class="comment">// of each malloc() or free(), and the return value of malloc().</span></div><div class="line"> <span class="comment">//</span></div><div class="line"> <span class="comment">// Find the malloc() function.</span></div><div class="line"> RTN mallocRtn = <a class="code" href="group__RTN__BASIC__API.html#ga77a2ad03e0431b881d6c3019b45261eb">RTN_FindByName</a>(img, MALLOC);</div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__RTN__BASIC__API.html#ga6ac855c9a19a3aab44347188e6695875">RTN_Valid</a>(mallocRtn))</div><div class="line"> {</div><div class="line"> <a class="code" href="group__RTN__BASIC__API.html#gaf8714086f8aebc9feacccc8cd02dc561">RTN_Open</a>(mallocRtn);</div><div class="line"></div><div class="line"> <span class="comment">// Instrument malloc() to print the input argument value and the return value.</span></div><div class="line"> <a class="code" href="group__RTN__BASIC__API.html#ga76bde295a78d1232fd6ff98a5ff011cf">RTN_InsertCall</a>(mallocRtn, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>, (AFUNPTR)Arg1Before,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da34126f334d65afac69784351a03615ad">IARG_ADDRINT</a>, MALLOC,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dab418d242314ea7c67b1febf7667e93a1">IARG_FUNCARG_ENTRYPOINT_VALUE</a>, 0,</div><div class="line"> IARG_END);</div><div class="line"> <a class="code" href="group__RTN__BASIC__API.html#ga76bde295a78d1232fd6ff98a5ff011cf">RTN_InsertCall</a>(mallocRtn, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a42eff26179c6d87348abe492301c12ec">IPOINT_AFTER</a>, (AFUNPTR)MallocAfter,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da19dc8d3703330b7b1e1064336dd235cf">IARG_FUNCRET_EXITPOINT_VALUE</a>, IARG_END);</div><div class="line"></div><div class="line"> <a class="code" href="group__RTN__BASIC__API.html#ga37272253377eb65c9eb5ff47ec4f1e6b">RTN_Close</a>(mallocRtn);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// Find the free() function.</span></div><div class="line"> RTN freeRtn = <a class="code" href="group__RTN__BASIC__API.html#ga77a2ad03e0431b881d6c3019b45261eb">RTN_FindByName</a>(img, FREE);</div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__RTN__BASIC__API.html#ga6ac855c9a19a3aab44347188e6695875">RTN_Valid</a>(freeRtn))</div><div class="line"> {</div><div class="line"> <a class="code" href="group__RTN__BASIC__API.html#gaf8714086f8aebc9feacccc8cd02dc561">RTN_Open</a>(freeRtn);</div><div class="line"> <span class="comment">// Instrument free() to print the input argument value.</span></div><div class="line"> <a class="code" href="group__RTN__BASIC__API.html#ga76bde295a78d1232fd6ff98a5ff011cf">RTN_InsertCall</a>(freeRtn, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>, (AFUNPTR)Arg1Before,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da34126f334d65afac69784351a03615ad">IARG_ADDRINT</a>, FREE,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dab418d242314ea7c67b1febf7667e93a1">IARG_FUNCARG_ENTRYPOINT_VALUE</a>, 0,</div><div class="line"> IARG_END);</div><div class="line"> <a class="code" href="group__RTN__BASIC__API.html#ga37272253377eb65c9eb5ff47ec4f1e6b">RTN_Close</a>(freeRtn);</div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line">VOID Fini(INT32 code, VOID *v)</div><div class="line">{</div><div class="line"> TraceFile.close();</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Print Help Message */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"> </div><div class="line">INT32 Usage()</div><div class="line">{</div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot;This tool produces a trace of calls to malloc.&quot;</span> &lt;&lt; endl;</div><div class="line"> cerr &lt;&lt; endl &lt;&lt; KNOB_BASE::StringKnobSummary() &lt;&lt; endl;</div><div class="line"> <span class="keywordflow">return</span> -1;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Main */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> *argv[])</div><div class="line">{</div><div class="line"> <span class="comment">// Initialize pin &amp; symbol manager</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#ga8cf4aca0b0bdbc7fc0ae965883d8e3c2">PIN_InitSymbols</a>();</div><div class="line"> <span class="keywordflow">if</span>( <a class="code" href="group__PIN__CONTROL.html#ga783d3bd40c3fb2ca51b1f9af31a70c9c">PIN_Init</a>(argc,argv) )</div><div class="line"> {</div><div class="line"> <span class="keywordflow">return</span> Usage();</div><div class="line"> }</div><div class="line"> </div><div class="line"> <span class="comment">// Write to a file since cout and cerr maybe closed by the application</span></div><div class="line"> TraceFile.open(KnobOutputFile.Value().c_str());</div><div class="line"> TraceFile &lt;&lt; hex;</div><div class="line"> TraceFile.setf(ios::showbase);</div><div class="line"> </div><div class="line"> <span class="comment">// Register Image to be called to instrument functions.</span></div><div class="line"> <a class="code" href="group__IMG__BASIC__API.html#ga494869187b5d94d7dd346bc9ff49642f">IMG_AddInstrumentFunction</a>(Image, 0);</div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gac167b8d28d255e53a0ac1f6e9edcd3ec">PIN_AddFiniFunction</a>(Fini, 0);</div><div class="line"></div><div class="line"> <span class="comment">// Never returns</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gaded401aeb030a76ee3396137b06ad808">PIN_StartProgram</a>();</div><div class="line"> </div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* eof */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div></div><!-- fragment --><h2><a class="anchor" id="FindSymbol"></a>
Finding Functions By Name on Windows</h2>
<p>Finding functions by name on Windows requires a different methodology. Several symbols could resolve to the same function address. It is important to check all symbol names.</p>
<p>The following example finds the function name in the symbol table, and uses the symbol address to find the appropriate RTN.</p>
<pre class="fragment">$ ..\..\..\pin -t obj-ia32\w_malloctrace.dll -- ..\Tests\obj-ia32\cp-pin.exe makefile w_malloctrace.makefile.copy
$ head *.out
Before: RtlAllocateHeap(00150000, 0, 0x94)
After: RtlAllocateHeap returns 0x153440
After: RtlAllocateHeap returns 0x153440
Before: RtlAllocateHeap(00150000, 0, 0x20)
After: RtlAllocateHeap returns 0
After: RtlAllocateHeap returns 0x1567c0
Before: RtlAllocateHeap(019E0000, 0x8, 0x1800)
After: RtlAllocateHeap returns 0x19e0688
Before: RtlAllocateHeap(00150000, 0, 0x1a)thread begin 0
After: RtlAllocateHeap returns 0
</pre><p>The example can be found in source/tools/ManualExamples/w_malloctrace.cpp.</p>
<div class="fragment"><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* This example demonstrates finding a function by name on Windows. */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line"><span class="preprocessor">#include &quot;pin.H&quot;</span></div><div class="line"><span class="keyword">namespace </span>WINDOWS</div><div class="line">{</div><div class="line"><span class="preprocessor">#include&lt;Windows.h&gt;</span></div><div class="line">}</div><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;fstream&gt;</span></div><div class="line"><span class="keyword">using</span> std::cerr;</div><div class="line"><span class="keyword">using</span> std::endl;</div><div class="line"><span class="keyword">using</span> std::hex;</div><div class="line"><span class="keyword">using</span> std::dec;</div><div class="line"><span class="keyword">using</span> std::string;</div><div class="line"><span class="keyword">using</span> std::ios;</div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Global Variables */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line">std::ofstream TraceFile;</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Commandline Switches */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line">KNOB&lt;string&gt; KnobOutputFile(<a class="code" href="group__KNOB__BASIC.html#ggad45510089e3b85a88df038e900e9f8baa576ddd3b58b1121ff4070df605951cf6">KNOB_MODE_WRITEONCE</a>, <span class="stringliteral">&quot;pintool&quot;</span>,</div><div class="line"> <span class="stringliteral">&quot;o&quot;</span>, <span class="stringliteral">&quot;w_malloctrace.out&quot;</span>, <span class="stringliteral">&quot;specify trace file name&quot;</span>);</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Print Help Message */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line">INT32 Usage()</div><div class="line">{</div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot;This tool produces a trace of calls to RtlAllocateHeap.&quot;</span>;</div><div class="line"> cerr &lt;&lt; endl &lt;&lt; endl;</div><div class="line"> cerr &lt;&lt; KNOB_BASE::StringKnobSummary();</div><div class="line"> cerr &lt;&lt; endl;</div><div class="line"> <span class="keywordflow">return</span> -1;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Analysis routines */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"> </div><div class="line">VOID Before(CHAR * name, WINDOWS::HANDLE hHeap,</div><div class="line"> WINDOWS::DWORD dwFlags, WINDOWS::DWORD dwBytes) </div><div class="line">{</div><div class="line"> TraceFile &lt;&lt; <span class="stringliteral">&quot;Before: &quot;</span> &lt;&lt; name &lt;&lt; <span class="stringliteral">&quot;(&quot;</span> &lt;&lt; hex &lt;&lt; hHeap &lt;&lt; <span class="stringliteral">&quot;, &quot;</span></div><div class="line"> &lt;&lt; dwFlags &lt;&lt; <span class="stringliteral">&quot;, &quot;</span> &lt;&lt; dwBytes &lt;&lt; <span class="stringliteral">&quot;)&quot;</span> &lt;&lt; dec &lt;&lt; endl;</div><div class="line">}</div><div class="line"></div><div class="line">VOID After(CHAR * name, ADDRINT ret)</div><div class="line">{</div><div class="line"> TraceFile &lt;&lt; <span class="stringliteral">&quot;After: &quot;</span> &lt;&lt; name &lt;&lt; <span class="stringliteral">&quot; returns &quot;</span> &lt;&lt; hex</div><div class="line"> &lt;&lt; ret &lt;&lt; dec &lt;&lt; endl;</div><div class="line">}</div><div class="line"></div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Instrumentation routines */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"> </div><div class="line">VOID Image(IMG img, VOID *v)</div><div class="line">{</div><div class="line"> <span class="comment">// Walk through the symbols in the symbol table.</span></div><div class="line"> <span class="comment">//</span></div><div class="line"> <span class="keywordflow">for</span> (SYM sym = <a class="code" href="group__IMG__BASIC__API.html#ga5394fba999264f58cb4838b8061dd79f">IMG_RegsymHead</a>(img); <a class="code" href="group__SYM__BASIC__API.html#ga222198e876ee9b2a72deeea3ed5c4008">SYM_Valid</a>(sym); sym = <a class="code" href="group__SYM__BASIC__API.html#ga41641c7ae44bbd4985dbe53de9cadbcd">SYM_Next</a>(sym))</div><div class="line"> {</div><div class="line"> <span class="keywordtype">string</span> undFuncName = <a class="code" href="group__SYM__BASIC__API.html#ga5d19cc4556883eb96d4627775e466fc4">PIN_UndecorateSymbolName</a>(<a class="code" href="group__SYM__BASIC__API.html#gab91cb2cbcd8bff087351b43167594b9e">SYM_Name</a>(sym), <a class="code" href="group__SYM__BASIC__API.html#gga2b7e9b0b1d3e5d38135695bdb1b380fea22890064021b2aa1f9f2754d181b7073">UNDECORATION_NAME_ONLY</a>);</div><div class="line"></div><div class="line"> <span class="comment">// Find the RtlAllocHeap() function.</span></div><div class="line"> <span class="keywordflow">if</span> (undFuncName == <span class="stringliteral">&quot;RtlAllocateHeap&quot;</span>)</div><div class="line"> {</div><div class="line"> RTN allocRtn = <a class="code" href="group__RTN__BASIC__API.html#ga6f86e6509f4bddb238576cda772c15de">RTN_FindByAddress</a>(<a class="code" href="group__IMG__BASIC__API.html#ga287976c95e15d6f5655ce9a665723711">IMG_LowAddress</a>(img) + <a class="code" href="group__SYM__BASIC__API.html#ga8b72567bd2c6639c367519927913c6bd">SYM_Value</a>(sym));</div><div class="line"> </div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__RTN__BASIC__API.html#ga6ac855c9a19a3aab44347188e6695875">RTN_Valid</a>(allocRtn))</div><div class="line"> {</div><div class="line"> <span class="comment">// Instrument to print the input argument value and the return value.</span></div><div class="line"> <a class="code" href="group__RTN__BASIC__API.html#gaf8714086f8aebc9feacccc8cd02dc561">RTN_Open</a>(allocRtn);</div><div class="line"> </div><div class="line"> <a class="code" href="group__RTN__BASIC__API.html#ga76bde295a78d1232fd6ff98a5ff011cf">RTN_InsertCall</a>(allocRtn, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>, (AFUNPTR)Before,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da34126f334d65afac69784351a03615ad">IARG_ADDRINT</a>, <span class="stringliteral">&quot;RtlAllocateHeap&quot;</span>,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dab418d242314ea7c67b1febf7667e93a1">IARG_FUNCARG_ENTRYPOINT_VALUE</a>, 0,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dab418d242314ea7c67b1febf7667e93a1">IARG_FUNCARG_ENTRYPOINT_VALUE</a>, 1,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dab418d242314ea7c67b1febf7667e93a1">IARG_FUNCARG_ENTRYPOINT_VALUE</a>, 2,</div><div class="line"> IARG_END);</div><div class="line"> <a class="code" href="group__RTN__BASIC__API.html#ga76bde295a78d1232fd6ff98a5ff011cf">RTN_InsertCall</a>(allocRtn, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a42eff26179c6d87348abe492301c12ec">IPOINT_AFTER</a>, (AFUNPTR)After,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da34126f334d65afac69784351a03615ad">IARG_ADDRINT</a>, <span class="stringliteral">&quot;RtlAllocateHeap&quot;</span>,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da19dc8d3703330b7b1e1064336dd235cf">IARG_FUNCRET_EXITPOINT_VALUE</a>,</div><div class="line"> IARG_END);</div><div class="line"> </div><div class="line"> <a class="code" href="group__RTN__BASIC__API.html#ga37272253377eb65c9eb5ff47ec4f1e6b">RTN_Close</a>(allocRtn);</div><div class="line"> }</div><div class="line"> }</div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line">VOID Fini(INT32 code, VOID *v)</div><div class="line">{</div><div class="line"> TraceFile.close();</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Main */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> *argv[])</div><div class="line">{</div><div class="line"> <span class="comment">// Initialize pin &amp; symbol manager</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#ga8cf4aca0b0bdbc7fc0ae965883d8e3c2">PIN_InitSymbols</a>();</div><div class="line"> <span class="keywordflow">if</span>( <a class="code" href="group__PIN__CONTROL.html#ga783d3bd40c3fb2ca51b1f9af31a70c9c">PIN_Init</a>(argc,argv) )</div><div class="line"> {</div><div class="line"> <span class="keywordflow">return</span> Usage();</div><div class="line"> }</div><div class="line"> </div><div class="line"> <span class="comment">// Write to a file since cout and cerr maybe closed by the application</span></div><div class="line"> TraceFile.open(KnobOutputFile.Value().c_str());</div><div class="line"> TraceFile &lt;&lt; hex;</div><div class="line"> TraceFile.setf(ios::showbase);</div><div class="line"> </div><div class="line"> <span class="comment">// Register Image to be called to instrument functions.</span></div><div class="line"> <a class="code" href="group__IMG__BASIC__API.html#ga494869187b5d94d7dd346bc9ff49642f">IMG_AddInstrumentFunction</a>(Image, 0);</div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gac167b8d28d255e53a0ac1f6e9edcd3ec">PIN_AddFiniFunction</a>(Fini, 0);</div><div class="line"></div><div class="line"> <span class="comment">// Never returns</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gaded401aeb030a76ee3396137b06ad808">PIN_StartProgram</a>();</div><div class="line"> </div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* eof */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div></div><!-- fragment --><h2><a class="anchor" id="MallocMT"></a>
Instrumenting Threaded Applications</h2>
<p>The following example demonstrates using the ThreadStart() and ThreadFini() notification callbacks. Although ThreadStart() and ThreadFini() are executed under the VM and client locks, they could still contend with resources that are shared by other analysis routines. Using <a class="el" href="group__LOCK.html#ga9569245cd781216f8f1a54d3a0962ddf">PIN_GetLock()</a> prevents this.</p>
<p>Note that there is known isolation issue when using Pin on Windows. On Windows, a deadlock can occur if a tool opens a file in a callback when run on a multi-threaded application. To work around this problem, open one file in main, and tag the data with the thread ID. See source/tools/ManualExamples/buffer_windows.cpp as an example. This problem does not exist on Linux.</p>
<pre class="fragment">$ ../../../pin -t obj-ia32/malloc_mt.so -- obj-ia32/thread_lin
$ head malloc_mt.out
thread begin 0
thread 0 entered malloc(24d)
thread 0 entered malloc(57)
thread 0 entered malloc(c)
thread 0 entered malloc(3c0)
thread 0 entered malloc(c)
thread 0 entered malloc(58)
thread 0 entered malloc(56)
thread 0 entered malloc(19)
thread 0 entered malloc(25c)
</pre><p>The example can be found in source/tools/ManualExamples/malloc_mt.cpp</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &lt;stdio.h&gt;</span></div><div class="line"><span class="preprocessor">#include &quot;pin.H&quot;</span></div><div class="line"><span class="keyword">using</span> std::string;</div><div class="line"></div><div class="line">KNOB&lt;string&gt; KnobOutputFile(<a class="code" href="group__KNOB__BASIC.html#ggad45510089e3b85a88df038e900e9f8baa576ddd3b58b1121ff4070df605951cf6">KNOB_MODE_WRITEONCE</a>, <span class="stringliteral">&quot;pintool&quot;</span>,</div><div class="line"> <span class="stringliteral">&quot;o&quot;</span>, <span class="stringliteral">&quot;malloc_mt.out&quot;</span>, <span class="stringliteral">&quot;specify output file name&quot;</span>);</div><div class="line"></div><div class="line"><span class="comment">//==============================================================</span></div><div class="line"><span class="comment">// Analysis Routines</span></div><div class="line"><span class="comment">//==============================================================</span></div><div class="line"><span class="comment">// Note: threadid+1 is used as an argument to the PIN_GetLock()</span></div><div class="line"><span class="comment">// routine as a debugging aid. This is the value that</span></div><div class="line"><span class="comment">// the lock is set to, so it must be non-zero.</span></div><div class="line"></div><div class="line"><span class="comment">// lock serializes access to the output file.</span></div><div class="line">FILE * out;</div><div class="line">PIN_LOCK pinLock;</div><div class="line"></div><div class="line"><span class="comment">// Note that opening a file in a callback is only supported on Linux systems.</span></div><div class="line"><span class="comment">// See buffer-win.cpp for how to work around this issue on Windows.</span></div><div class="line"><span class="comment">//</span></div><div class="line"><span class="comment">// This routine is executed every time a thread is created.</span></div><div class="line">VOID ThreadStart(<a class="code" href="group__PIN__THREAD__API.html#ga645289be59039349ad77ad2fa7b0e2f3">THREADID</a> threadid, <a class="code" href="group__CONTEXT__API.html#ga73f8f88949aaecf53a6d23f56399c676">CONTEXT</a> *ctxt, INT32 flags, VOID *v)</div><div class="line">{</div><div class="line"> <a class="code" href="group__LOCK.html#ga9569245cd781216f8f1a54d3a0962ddf">PIN_GetLock</a>(&amp;pinLock, threadid+1);</div><div class="line"> fprintf(out, <span class="stringliteral">&quot;thread begin %d\n&quot;</span>,threadid);</div><div class="line"> fflush(out);</div><div class="line"> <a class="code" href="group__LOCK.html#ga00a837236be573c0c548191e0846df1d">PIN_ReleaseLock</a>(&amp;pinLock);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// This routine is executed every time a thread is destroyed.</span></div><div class="line">VOID ThreadFini(<a class="code" href="group__PIN__THREAD__API.html#ga645289be59039349ad77ad2fa7b0e2f3">THREADID</a> threadid, <span class="keyword">const</span> <a class="code" href="group__CONTEXT__API.html#ga73f8f88949aaecf53a6d23f56399c676">CONTEXT</a> *ctxt, INT32 code, VOID *v)</div><div class="line">{</div><div class="line"> <a class="code" href="group__LOCK.html#ga9569245cd781216f8f1a54d3a0962ddf">PIN_GetLock</a>(&amp;pinLock, threadid+1);</div><div class="line"> fprintf(out, <span class="stringliteral">&quot;thread end %d code %d\n&quot;</span>,threadid, code);</div><div class="line"> fflush(out);</div><div class="line"> <a class="code" href="group__LOCK.html#ga00a837236be573c0c548191e0846df1d">PIN_ReleaseLock</a>(&amp;pinLock);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// This routine is executed each time malloc is called.</span></div><div class="line">VOID BeforeMalloc( <span class="keywordtype">int</span> size, <a class="code" href="group__PIN__THREAD__API.html#ga645289be59039349ad77ad2fa7b0e2f3">THREADID</a> threadid )</div><div class="line">{</div><div class="line"> <a class="code" href="group__LOCK.html#ga9569245cd781216f8f1a54d3a0962ddf">PIN_GetLock</a>(&amp;pinLock, threadid+1);</div><div class="line"> fprintf(out, <span class="stringliteral">&quot;thread %d entered malloc(%d)\n&quot;</span>, threadid, size);</div><div class="line"> fflush(out);</div><div class="line"> <a class="code" href="group__LOCK.html#ga00a837236be573c0c548191e0846df1d">PIN_ReleaseLock</a>(&amp;pinLock);</div><div class="line">}</div><div class="line"></div><div class="line"></div><div class="line"><span class="comment">//====================================================================</span></div><div class="line"><span class="comment">// Instrumentation Routines</span></div><div class="line"><span class="comment">//====================================================================</span></div><div class="line"></div><div class="line"><span class="comment">// This routine is executed for each image.</span></div><div class="line">VOID ImageLoad(IMG img, VOID *)</div><div class="line">{</div><div class="line"> RTN rtn = <a class="code" href="group__RTN__BASIC__API.html#ga77a2ad03e0431b881d6c3019b45261eb">RTN_FindByName</a>(img, <span class="stringliteral">&quot;malloc&quot;</span>);</div><div class="line"> </div><div class="line"> <span class="keywordflow">if</span> ( <a class="code" href="group__RTN__BASIC__API.html#ga6ac855c9a19a3aab44347188e6695875">RTN_Valid</a>( rtn ))</div><div class="line"> {</div><div class="line"> <a class="code" href="group__RTN__BASIC__API.html#gaf8714086f8aebc9feacccc8cd02dc561">RTN_Open</a>(rtn);</div><div class="line"> </div><div class="line"> <a class="code" href="group__RTN__BASIC__API.html#ga76bde295a78d1232fd6ff98a5ff011cf">RTN_InsertCall</a>(rtn, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>, AFUNPTR(BeforeMalloc),</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dab418d242314ea7c67b1febf7667e93a1">IARG_FUNCARG_ENTRYPOINT_VALUE</a>, 0,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451daadb6e5681193cc8435b9e57d13acf5d4">IARG_THREAD_ID</a>, IARG_END);</div><div class="line"></div><div class="line"> <a class="code" href="group__RTN__BASIC__API.html#ga37272253377eb65c9eb5ff47ec4f1e6b">RTN_Close</a>(rtn);</div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// This routine is executed once at the end.</span></div><div class="line">VOID Fini(INT32 code, VOID *v)</div><div class="line">{</div><div class="line"> fclose(out);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Print Help Message */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line">INT32 Usage()</div><div class="line">{</div><div class="line"> PIN_ERROR(<span class="stringliteral">&quot;This Pintool prints a trace of malloc calls in the guest application\n&quot;</span></div><div class="line"> + KNOB_BASE::StringKnobSummary() + <span class="stringliteral">&quot;\n&quot;</span>);</div><div class="line"> <span class="keywordflow">return</span> -1;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Main */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main(INT32 argc, CHAR **argv)</div><div class="line">{</div><div class="line"> <span class="comment">// Initialize the pin lock</span></div><div class="line"> <a class="code" href="group__LOCK.html#gac9a323f8cf8f4ea4a12080f4b4099edc">PIN_InitLock</a>(&amp;pinLock);</div><div class="line"> </div><div class="line"> <span class="comment">// Initialize pin</span></div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__PIN__CONTROL.html#ga783d3bd40c3fb2ca51b1f9af31a70c9c">PIN_Init</a>(argc, argv)) <span class="keywordflow">return</span> Usage();</div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#ga8cf4aca0b0bdbc7fc0ae965883d8e3c2">PIN_InitSymbols</a>();</div><div class="line"> </div><div class="line"> out = fopen(KnobOutputFile.Value().c_str(), <span class="stringliteral">&quot;w&quot;</span>);</div><div class="line"></div><div class="line"> <span class="comment">// Register ImageLoad to be called when each image is loaded.</span></div><div class="line"> <a class="code" href="group__IMG__BASIC__API.html#ga494869187b5d94d7dd346bc9ff49642f">IMG_AddInstrumentFunction</a>(ImageLoad, 0);</div><div class="line"></div><div class="line"> <span class="comment">// Register Analysis routines to be called when a thread begins/ends</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#ga93431bb0680a22395327ac7d8bb0c14c">PIN_AddThreadStartFunction</a>(ThreadStart, 0);</div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gae79d468cc5e19b450603f07f3397203d">PIN_AddThreadFiniFunction</a>(ThreadFini, 0);</div><div class="line"></div><div class="line"> <span class="comment">// Register Fini to be called when the application exits</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gac167b8d28d255e53a0ac1f6e9edcd3ec">PIN_AddFiniFunction</a>(Fini, 0);</div><div class="line"> </div><div class="line"> <span class="comment">// Never returns</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gaded401aeb030a76ee3396137b06ad808">PIN_StartProgram</a>();</div><div class="line"> </div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment --><h2><a class="anchor" id="InscountTLS"></a>
Using TLS</h2>
<p>Pin provides efficient thread local storage (TLS) APIs. These APIs allow a tool to create thread-specific data. The example below demonstrates how to use these APIs.</p>
<pre class="fragment">$ ../../../pin -t obj-ia32/inscount_tls.so -- obj-ia32/thread_lin
$ head
Count[0]= 237993
Count[1]= 213296
Count[2]= 209223
Count[3]= 209223
Count[4]= 209223
Count[5]= 209223
Count[6]= 209223
Count[7]= 209223
Count[8]= 209223
Count[9]= 209223
</pre><p>The example can be found in source/tools/ManualExamples/inscount_tls.cpp</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;fstream&gt;</span></div><div class="line"><span class="preprocessor">#include &quot;pin.H&quot;</span></div><div class="line"><span class="keyword">using</span> std::ostream;</div><div class="line"><span class="keyword">using</span> std::cout;</div><div class="line"><span class="keyword">using</span> std::cerr;</div><div class="line"><span class="keyword">using</span> std::string;</div><div class="line"><span class="keyword">using</span> std::endl;</div><div class="line"></div><div class="line">KNOB&lt;string&gt; KnobOutputFile(<a class="code" href="group__KNOB__BASIC.html#ggad45510089e3b85a88df038e900e9f8baa576ddd3b58b1121ff4070df605951cf6">KNOB_MODE_WRITEONCE</a>, <span class="stringliteral">&quot;pintool&quot;</span>,</div><div class="line"> <span class="stringliteral">&quot;o&quot;</span>, <span class="stringliteral">&quot;&quot;</span>, <span class="stringliteral">&quot;specify output file name&quot;</span>);</div><div class="line"></div><div class="line">INT32 numThreads = 0;</div><div class="line">ostream* OutFile = NULL;</div><div class="line"></div><div class="line"><span class="comment">// Force each thread&#39;s data to be in its own data cache line so that</span></div><div class="line"><span class="comment">// multiple threads do not contend for the same data cache line.</span></div><div class="line"><span class="comment">// This avoids the false sharing problem.</span></div><div class="line"><span class="preprocessor">#define PADSIZE 56 // 64 byte line size: 64-8</span></div><div class="line"></div><div class="line"><span class="comment">// a running count of the instructions</span></div><div class="line"><span class="keyword">class </span>thread_data_t</div><div class="line">{</div><div class="line"> <span class="keyword">public</span>:</div><div class="line"> thread_data_t() : _count(0) {}</div><div class="line"> UINT64 _count;</div><div class="line"> UINT8 _pad[PADSIZE];</div><div class="line">};</div><div class="line"></div><div class="line"><span class="comment">// key for accessing TLS storage in the threads. initialized once in main()</span></div><div class="line"><span class="keyword">static</span> <a class="code" href="group__PIN__THREAD__API.html#gaf45100643b9edc94ae0f0264e5d14fc3">TLS_KEY</a> tls_key = <a class="code" href="group__PIN__THREAD__API.html#ga7a22817a78367ba432a8121df3d7b461">INVALID_TLS_KEY</a>;</div><div class="line"></div><div class="line"><span class="comment">// This function is called before every block</span></div><div class="line">VOID <a class="code" href="group__INST__ARGS.html#ga5d3025eb005b7ea4745799f0ee1b86a6">PIN_FAST_ANALYSIS_CALL</a> docount(UINT32 c, <a class="code" href="group__PIN__THREAD__API.html#ga645289be59039349ad77ad2fa7b0e2f3">THREADID</a> threadid)</div><div class="line">{</div><div class="line"> thread_data_t* tdata = <span class="keyword">static_cast&lt;</span>thread_data_t*<span class="keyword">&gt;</span>(<a class="code" href="group__DEPRECATED__PIN__API.html#gab82e344077340051545bcb16478fb4a2">PIN_GetThreadData</a>(tls_key, threadid));</div><div class="line"> tdata-&gt;_count += c;</div><div class="line">}</div><div class="line"></div><div class="line">VOID ThreadStart(<a class="code" href="group__PIN__THREAD__API.html#ga645289be59039349ad77ad2fa7b0e2f3">THREADID</a> threadid, <a class="code" href="group__CONTEXT__API.html#ga73f8f88949aaecf53a6d23f56399c676">CONTEXT</a> *ctxt, INT32 flags, VOID *v)</div><div class="line">{</div><div class="line"> numThreads++;</div><div class="line"> thread_data_t* tdata = <span class="keyword">new</span> thread_data_t;</div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__DEPRECATED__PIN__API.html#ga07e007644db1d47bb89f97aa5273bc36">PIN_SetThreadData</a>(tls_key, tdata, threadid) == FALSE)</div><div class="line"> {</div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot;PIN_SetThreadData failed&quot;</span> &lt;&lt; endl;</div><div class="line"> <a class="code" href="group__PIN__PROCESS__API.html#gacca02e5ee771570c8d255506692a63ae">PIN_ExitProcess</a>(1);</div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line"></div><div class="line"><span class="comment">// Pin calls this function every time a new basic block is encountered.</span></div><div class="line"><span class="comment">// It inserts a call to docount.</span></div><div class="line">VOID Trace(<a class="code" href="group__TRACE__BASIC__API.html#gaf9f3009a146688d5230a16f8d3e575be">TRACE</a> trace, VOID *v)</div><div class="line">{</div><div class="line"> <span class="comment">// Visit every basic block in the trace</span></div><div class="line"> <span class="keywordflow">for</span> (BBL bbl = <a class="code" href="group__TRACE__BASIC__API.html#ga008abc5ba1af8d9e9cd073ffe0aefa18">TRACE_BblHead</a>(trace); <a class="code" href="group__BBL__BASIC__API.html#ga58a8d019cd09ce46cfe431ec8f14a075">BBL_Valid</a>(bbl); bbl = <a class="code" href="group__BBL__BASIC__API.html#gadd7141abb47139b52922e04e0c4a10f3">BBL_Next</a>(bbl))</div><div class="line"> {</div><div class="line"> <span class="comment">// Insert a call to docount for every bbl, passing the number of instructions.</span></div><div class="line"></div><div class="line"> <a class="code" href="group__BBL__BASIC__API.html#gaeee9d7a6253d49d226bbed3f35768169">BBL_InsertCall</a>(bbl, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7acf7dee2063098dd79907d19f9c7df65d">IPOINT_ANYWHERE</a>, (AFUNPTR)docount, <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da892dbdf11883df94c327bb31fd0d5fcd">IARG_FAST_ANALYSIS_CALL</a>,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dabd19b79248899659441e56e4738d5bfd">IARG_UINT32</a>, <a class="code" href="group__BBL__BASIC__API.html#ga76ceb2d9e0fb974d3c3769b2413ed634">BBL_NumIns</a>(bbl), <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451daadb6e5681193cc8435b9e57d13acf5d4">IARG_THREAD_ID</a>, IARG_END);</div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// This function is called when the thread exits</span></div><div class="line">VOID ThreadFini(<a class="code" href="group__PIN__THREAD__API.html#ga645289be59039349ad77ad2fa7b0e2f3">THREADID</a> threadIndex, <span class="keyword">const</span> <a class="code" href="group__CONTEXT__API.html#ga73f8f88949aaecf53a6d23f56399c676">CONTEXT</a> *ctxt, INT32 code, VOID *v)</div><div class="line">{</div><div class="line"> thread_data_t* tdata = <span class="keyword">static_cast&lt;</span>thread_data_t*<span class="keyword">&gt;</span>(<a class="code" href="group__DEPRECATED__PIN__API.html#gab82e344077340051545bcb16478fb4a2">PIN_GetThreadData</a>(tls_key, threadIndex));</div><div class="line"> *OutFile &lt;&lt; <span class="stringliteral">&quot;Count[&quot;</span> &lt;&lt; <a class="code" href="group__MISC__PRINT.html#ga0a07c9fee11e18f9eb88ee3f18fa3948">decstr</a>(threadIndex) &lt;&lt; <span class="stringliteral">&quot;] = &quot;</span> &lt;&lt; tdata-&gt;_count &lt;&lt; endl;</div><div class="line"> <span class="keyword">delete</span> tdata;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// This function is called when the application exits</span></div><div class="line">VOID Fini(INT32 code, VOID *v)</div><div class="line">{</div><div class="line"> *OutFile &lt;&lt; <span class="stringliteral">&quot;Total number of threads = &quot;</span> &lt;&lt; numThreads &lt;&lt; endl;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Print Help Message */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line">INT32 Usage()</div><div class="line">{</div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot;This tool counts the number of dynamic instructions executed&quot;</span> &lt;&lt; endl;</div><div class="line"> cerr &lt;&lt; endl &lt;&lt; KNOB_BASE::StringKnobSummary() &lt;&lt; endl;</div><div class="line"> <span class="keywordflow">return</span> 1;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Main */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> * argv[])</div><div class="line">{</div><div class="line"> <span class="comment">// Initialize pin</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#ga8cf4aca0b0bdbc7fc0ae965883d8e3c2">PIN_InitSymbols</a>();</div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__PIN__CONTROL.html#ga783d3bd40c3fb2ca51b1f9af31a70c9c">PIN_Init</a>(argc, argv))</div><div class="line"> <span class="keywordflow">return</span> Usage();</div><div class="line"></div><div class="line"> OutFile = KnobOutputFile.Value().empty() ? &amp;cout : <span class="keyword">new</span> std::ofstream(KnobOutputFile.Value().c_str());</div><div class="line"></div><div class="line"> <span class="comment">// Obtain a key for TLS storage.</span></div><div class="line"> tls_key = <a class="code" href="group__PIN__THREAD__API.html#ga681b583239becd0b181f5b31e865931c">PIN_CreateThreadDataKey</a>(NULL);</div><div class="line"> <span class="keywordflow">if</span> (tls_key == <a class="code" href="group__PIN__THREAD__API.html#ga7a22817a78367ba432a8121df3d7b461">INVALID_TLS_KEY</a>)</div><div class="line"> {</div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot;number of already allocated keys reached the MAX_CLIENT_TLS_KEYS limit&quot;</span> &lt;&lt; endl;</div><div class="line"> <a class="code" href="group__PIN__PROCESS__API.html#gacca02e5ee771570c8d255506692a63ae">PIN_ExitProcess</a>(1);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// Register ThreadStart to be called when a thread starts.</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#ga93431bb0680a22395327ac7d8bb0c14c">PIN_AddThreadStartFunction</a>(ThreadStart, NULL);</div><div class="line"></div><div class="line"> <span class="comment">// Register Fini to be called when thread exits.</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gae79d468cc5e19b450603f07f3397203d">PIN_AddThreadFiniFunction</a>(ThreadFini, NULL);</div><div class="line"></div><div class="line"> <span class="comment">// Register Fini to be called when the application exits.</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gac167b8d28d255e53a0ac1f6e9edcd3ec">PIN_AddFiniFunction</a>(Fini, NULL);</div><div class="line"></div><div class="line"> <span class="comment">// Register Instruction to be called to instrument instructions.</span></div><div class="line"> <a class="code" href="group__TRACE__BASIC__API.html#ga41381de13d25c4bbd968cb64cb719d56">TRACE_AddInstrumentFunction</a>(Trace, NULL);</div><div class="line"></div><div class="line"> <span class="comment">// Start the program, never returns</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gaded401aeb030a76ee3396137b06ad808">PIN_StartProgram</a>();</div><div class="line"></div><div class="line"> <span class="keywordflow">return</span> 1;</div><div class="line">}</div></div><!-- fragment --><h2><a class="anchor" id="Buffering"></a>
Using the Fast Buffering APIs</h2>
<p>Pin provides support for buffering data for processing. If all that your analysis callback does is to store its arguments into a buffer, then you should be able to use the buffering API instead, with some performance benefit. <a class="el" href="group__BUFFER__API.html#ga008bd698d07658fc4f60fd9b61fb81bc">PIN_DefineTraceBuffer()</a> defines the buffer that will be used. The buffer is allocated by each thread when it starts up, and deallocated when the thread exits. <a class="el" href="group__INS__INST__API.html#gacf731514b88f79344068df5d8e60eacc">INS_InsertFillBuffer()</a> writes the requested data directly to the given buffer. The callback delineated in the <a class="el" href="group__BUFFER__API.html#ga008bd698d07658fc4f60fd9b61fb81bc">PIN_DefineTraceBuffer()</a> call is used to process the buffer when the buffer is nearly full, and when the thread exits. Pin does <b>not</b> serialize the calls to this callback, so it is the tool writers responsibilty to make sure this function is thread safe. This example records the PC of all instructions that access memory, and the effective address accessed by the instruction. Note that IARG_REG_REFERENCE, IARG_REG_CONST_REFERENCE, IARG_CONTEXT, IARG_CONST_CONTEXT and IARG_PARTIAL_CONTEXT can NOT be used in the Fast Buffering APIs</p>
<pre class="fragment">$ ../../../pin -t obj-ia32/buffer_linux.so -- obj-ia32/thread_lin
$ tail buffer.out.*.*
3263df 330108
3263df 330108
3263f1 a92f43fc
3263f7 a92f4d7d
326404 a92f43fc
32640a a92f4bf8
32640a a92f4bf8
32640f a92f4d94
32641b a92f43fc
326421 a92f4bf8
</pre><p>The example can be found in source/tools/ManualExamples/buffer_linux.cpp. This example is appropriate for Linux tools. If you are writing a tool for Windows, please see source/tools/ManualExamples/buffer_windows.cpp</p>
<div class="fragment"><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"> * Sample buffering tool</span></div><div class="line"><span class="comment"> *</span></div><div class="line"><span class="comment"> * This tool collects an address trace of instructions that access memory</span></div><div class="line"><span class="comment"> * by filling a buffer. When the buffer overflows,the callback writes all</span></div><div class="line"><span class="comment"> * of the collected records to a file.</span></div><div class="line"><span class="comment"> *</span></div><div class="line"><span class="comment"> */</span></div><div class="line"></div><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;fstream&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;cstdlib&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;cstddef&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;unistd.h&gt;</span></div><div class="line"><span class="preprocessor">#include &quot;pin.H&quot;</span></div><div class="line"><span class="keyword">using</span> std::hex;</div><div class="line"><span class="keyword">using</span> std::ofstream;</div><div class="line"><span class="keyword">using</span> std::cerr;</div><div class="line"><span class="keyword">using</span> std::string;</div><div class="line"><span class="keyword">using</span> std::endl;</div><div class="line"></div><div class="line"></div><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"> * Name of the output file</span></div><div class="line"><span class="comment"> */</span></div><div class="line">KNOB&lt;string&gt; KnobOutputFile(<a class="code" href="group__KNOB__BASIC.html#ggad45510089e3b85a88df038e900e9f8baa576ddd3b58b1121ff4070df605951cf6">KNOB_MODE_WRITEONCE</a>, <span class="stringliteral">&quot;pintool&quot;</span>, <span class="stringliteral">&quot;o&quot;</span>, <span class="stringliteral">&quot;buffer.out&quot;</span>, <span class="stringliteral">&quot;output file&quot;</span>);</div><div class="line"></div><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"> * The ID of the buffer</span></div><div class="line"><span class="comment"> */</span></div><div class="line">BUFFER_ID bufId;</div><div class="line"></div><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"> * Thread specific data</span></div><div class="line"><span class="comment"> */</span></div><div class="line"><a class="code" href="group__PIN__THREAD__API.html#gaf45100643b9edc94ae0f0264e5d14fc3">TLS_KEY</a> mlog_key;</div><div class="line"></div><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"> * Number of OS pages for the buffer</span></div><div class="line"><span class="comment"> */</span></div><div class="line"><span class="preprocessor">#define NUM_BUF_PAGES 1024</span></div><div class="line"></div><div class="line"></div><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"> * Record of memory references. Rather than having two separate</span></div><div class="line"><span class="comment"> * buffers for reads and writes, we just use one struct that includes a</span></div><div class="line"><span class="comment"> * flag for type.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"><span class="keyword">struct </span>MEMREF</div><div class="line">{</div><div class="line"> ADDRINT pc;</div><div class="line"> ADDRINT ea;</div><div class="line"> UINT32 size;</div><div class="line"> BOOL read;</div><div class="line">};</div><div class="line"></div><div class="line"></div><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"> * MLOG - thread specific data that is not handled by the buffering API.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"><span class="keyword">class </span>MLOG</div><div class="line">{</div><div class="line"> <span class="keyword">public</span>:</div><div class="line"> MLOG(<a class="code" href="group__PIN__THREAD__API.html#ga645289be59039349ad77ad2fa7b0e2f3">THREADID</a> tid);</div><div class="line"> ~MLOG();</div><div class="line"></div><div class="line"> VOID DumpBufferToFile( <span class="keyword">struct</span> MEMREF * reference, UINT64 numElements, <a class="code" href="group__PIN__THREAD__API.html#ga645289be59039349ad77ad2fa7b0e2f3">THREADID</a> tid );</div><div class="line"></div><div class="line"> <span class="keyword">private</span>:</div><div class="line"> ofstream _ofile;</div><div class="line">};</div><div class="line"></div><div class="line"></div><div class="line">MLOG::MLOG(<a class="code" href="group__PIN__THREAD__API.html#ga645289be59039349ad77ad2fa7b0e2f3">THREADID</a> tid)</div><div class="line">{</div><div class="line"> <span class="keyword">const</span> <span class="keywordtype">string</span> filename = KnobOutputFile.Value() + <span class="stringliteral">&quot;.&quot;</span> + <a class="code" href="group__MISC__PRINT.html#ga0a07c9fee11e18f9eb88ee3f18fa3948">decstr</a>(getpid()) + <span class="stringliteral">&quot;.&quot;</span> + <a class="code" href="group__MISC__PRINT.html#ga0a07c9fee11e18f9eb88ee3f18fa3948">decstr</a>(tid);</div><div class="line"></div><div class="line"> _ofile.open(filename.c_str());</div><div class="line"></div><div class="line"> <span class="keywordflow">if</span> ( ! _ofile )</div><div class="line"> {</div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot;Error: could not open output file.&quot;</span> &lt;&lt; endl;</div><div class="line"> exit(1);</div><div class="line"> }</div><div class="line"></div><div class="line"> _ofile &lt;&lt; hex;</div><div class="line">}</div><div class="line"></div><div class="line"></div><div class="line">MLOG::~MLOG()</div><div class="line">{</div><div class="line"> _ofile.close();</div><div class="line">}</div><div class="line"></div><div class="line"></div><div class="line">VOID MLOG::DumpBufferToFile( <span class="keyword">struct</span> MEMREF * reference, UINT64 numElements, <a class="code" href="group__PIN__THREAD__API.html#ga645289be59039349ad77ad2fa7b0e2f3">THREADID</a> tid )</div><div class="line">{</div><div class="line"> <span class="keywordflow">for</span>(UINT64 i=0; i&lt;numElements; i++, reference++)</div><div class="line"> {</div><div class="line"> <span class="keywordflow">if</span> (reference-&gt;ea != 0)</div><div class="line"> _ofile &lt;&lt; reference-&gt;pc &lt;&lt; <span class="stringliteral">&quot; &quot;</span> &lt;&lt; reference-&gt;ea &lt;&lt; endl;</div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"><span class="comment">/**************************************************************************</span></div><div class="line"><span class="comment"> *</span></div><div class="line"><span class="comment"> * Instrumentation routines</span></div><div class="line"><span class="comment"> *</span></div><div class="line"><span class="comment"> **************************************************************************/</span></div><div class="line"></div><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"> * Insert code to write data to a thread-specific buffer for instructions</span></div><div class="line"><span class="comment"> * that access memory.</span></div><div class="line"><span class="comment"> */</span></div><div class="line">VOID Trace(<a class="code" href="group__TRACE__BASIC__API.html#gaf9f3009a146688d5230a16f8d3e575be">TRACE</a> trace, VOID *v)</div><div class="line">{</div><div class="line"> <span class="keywordflow">for</span>(BBL bbl = <a class="code" href="group__TRACE__BASIC__API.html#ga008abc5ba1af8d9e9cd073ffe0aefa18">TRACE_BblHead</a>(trace); <a class="code" href="group__BBL__BASIC__API.html#ga58a8d019cd09ce46cfe431ec8f14a075">BBL_Valid</a>(bbl); bbl=<a class="code" href="group__BBL__BASIC__API.html#gadd7141abb47139b52922e04e0c4a10f3">BBL_Next</a>(bbl))</div><div class="line"> {</div><div class="line"> <span class="keywordflow">for</span>(INS ins = <a class="code" href="group__BBL__BASIC__API.html#ga7618bc7c80a25024227d3a24d59b936b">BBL_InsHead</a>(bbl); <a class="code" href="group__INS__BASIC__API__GEN__IA32.html#ga3a8b61fffa9ae4ad9f899b21ce37397c">INS_Valid</a>(ins); ins=<a class="code" href="group__INS__BASIC__API__GEN__IA32.html#ga227ce58a739b1573125c11071ecb48de">INS_Next</a>(ins))</div><div class="line"> {</div><div class="line"> <span class="keywordflow">if</span> (!<a class="code" href="group__INS__BASIC__API__IA32.html#ga2b685b5e8b997ba224e975eeb701eba9">INS_IsStandardMemop</a>(ins) &amp;&amp; !<a class="code" href="group__INS__BASIC__API__IA32.html#ga7fca105e9ec6a3014e5d0572533303a7">INS_HasMemoryVector</a>(ins))</div><div class="line"> {</div><div class="line"> <span class="comment">// We don&#39;t know how to treat these instructions</span></div><div class="line"> <span class="keywordflow">continue</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> UINT32 memoryOperands = <a class="code" href="group__INS__BASIC__API__GEN__IA32.html#ga138b553c79c6e39fe5f3858a7a60c854">INS_MemoryOperandCount</a>(ins);</div><div class="line"></div><div class="line"> <span class="keywordflow">for</span> (UINT32 memOp = 0; memOp &lt; memoryOperands; memOp++)</div><div class="line"> {</div><div class="line"> UINT32 refSize = <a class="code" href="group__INS__BASIC__API__GEN__IA32.html#ga94566988c11db3575963c2bd064898a3">INS_MemoryOperandSize</a>(ins, memOp);</div><div class="line"></div><div class="line"> <span class="comment">// Note that if the operand is both read and written we log it once</span></div><div class="line"> <span class="comment">// for each.</span></div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__INS__BASIC__API__GEN__IA32.html#ga3fdb434cd56a5b72be15dd0931a2b19c">INS_MemoryOperandIsRead</a>(ins, memOp))</div><div class="line"> {</div><div class="line"> <a class="code" href="group__INS__INST__API.html#gacf731514b88f79344068df5d8e60eacc">INS_InsertFillBuffer</a>(ins, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>, bufId,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da623ad95758bce14fcb9427beef53736a">IARG_INST_PTR</a>, offsetof(<span class="keyword">struct</span> MEMREF, pc),</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da985747a3c70e3a4283fc8a2f16399e63">IARG_MEMORYOP_EA</a>, memOp, offsetof(<span class="keyword">struct</span> MEMREF, ea),</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dabd19b79248899659441e56e4738d5bfd">IARG_UINT32</a>, refSize, offsetof(<span class="keyword">struct</span> MEMREF, size),</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dacac3cb99011b351eeb3f675bc8c62b83">IARG_BOOL</a>, TRUE, offsetof(<span class="keyword">struct</span> MEMREF, read),</div><div class="line"> IARG_END);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__INS__BASIC__API__GEN__IA32.html#gacd65d0a0a6033d2d8115183705def544">INS_MemoryOperandIsWritten</a>(ins, memOp))</div><div class="line"> {</div><div class="line"> <a class="code" href="group__INS__INST__API.html#gacf731514b88f79344068df5d8e60eacc">INS_InsertFillBuffer</a>(ins, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>, bufId,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da623ad95758bce14fcb9427beef53736a">IARG_INST_PTR</a>, offsetof(<span class="keyword">struct</span> MEMREF, pc),</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da985747a3c70e3a4283fc8a2f16399e63">IARG_MEMORYOP_EA</a>, memOp, offsetof(<span class="keyword">struct</span> MEMREF, ea),</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dabd19b79248899659441e56e4738d5bfd">IARG_UINT32</a>, refSize, offsetof(<span class="keyword">struct</span> MEMREF, size),</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dacac3cb99011b351eeb3f675bc8c62b83">IARG_BOOL</a>, FALSE, offsetof(<span class="keyword">struct</span> MEMREF, read),</div><div class="line"> IARG_END);</div><div class="line"> }</div><div class="line"> }</div><div class="line"> }</div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line"></div><div class="line"><span class="comment">/**************************************************************************</span></div><div class="line"><span class="comment"> *</span></div><div class="line"><span class="comment"> * Callback Routines</span></div><div class="line"><span class="comment"> *</span></div><div class="line"><span class="comment"> **************************************************************************/</span></div><div class="line"></div><div class="line">VOID * BufferFull(BUFFER_ID <span class="keywordtype">id</span>, <a class="code" href="group__PIN__THREAD__API.html#ga645289be59039349ad77ad2fa7b0e2f3">THREADID</a> tid, <span class="keyword">const</span> <a class="code" href="group__CONTEXT__API.html#ga73f8f88949aaecf53a6d23f56399c676">CONTEXT</a> *ctxt, VOID *buf,</div><div class="line"> UINT64 numElements, VOID *v)</div><div class="line">{</div><div class="line"> <span class="keyword">struct </span>MEMREF * reference=(<span class="keyword">struct </span>MEMREF*)buf;</div><div class="line"></div><div class="line"> MLOG * mlog = <span class="keyword">static_cast&lt;</span>MLOG*<span class="keyword">&gt;</span>( <a class="code" href="group__DEPRECATED__PIN__API.html#gab82e344077340051545bcb16478fb4a2">PIN_GetThreadData</a>( mlog_key, tid ) );</div><div class="line"></div><div class="line"> mlog-&gt;DumpBufferToFile( reference, numElements, tid );</div><div class="line"></div><div class="line"> <span class="keywordflow">return</span> buf;</div><div class="line">}</div><div class="line"></div><div class="line"></div><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"> * Note that opening a file in a callback is only supported on Linux systems.</span></div><div class="line"><span class="comment"> * See buffer-win.cpp for how to work around this issue on Windows.</span></div><div class="line"><span class="comment"> */</span></div><div class="line">VOID ThreadStart(<a class="code" href="group__PIN__THREAD__API.html#ga645289be59039349ad77ad2fa7b0e2f3">THREADID</a> tid, <a class="code" href="group__CONTEXT__API.html#ga73f8f88949aaecf53a6d23f56399c676">CONTEXT</a> *ctxt, INT32 flags, VOID *v)</div><div class="line">{</div><div class="line"> <span class="comment">// There is a new MLOG for every thread. Opens the output file.</span></div><div class="line"> MLOG * mlog = <span class="keyword">new</span> MLOG(tid);</div><div class="line"></div><div class="line"> <span class="comment">// A thread will need to look up its MLOG, so save pointer in TLS</span></div><div class="line"> <a class="code" href="group__DEPRECATED__PIN__API.html#ga07e007644db1d47bb89f97aa5273bc36">PIN_SetThreadData</a>(mlog_key, mlog, tid);</div><div class="line"></div><div class="line">}</div><div class="line"></div><div class="line"></div><div class="line">VOID ThreadFini(<a class="code" href="group__PIN__THREAD__API.html#ga645289be59039349ad77ad2fa7b0e2f3">THREADID</a> tid, <span class="keyword">const</span> <a class="code" href="group__CONTEXT__API.html#ga73f8f88949aaecf53a6d23f56399c676">CONTEXT</a> *ctxt, INT32 code, VOID *v)</div><div class="line">{</div><div class="line"> MLOG * mlog = <span class="keyword">static_cast&lt;</span>MLOG*<span class="keyword">&gt;</span>(<a class="code" href="group__DEPRECATED__PIN__API.html#gab82e344077340051545bcb16478fb4a2">PIN_GetThreadData</a>(mlog_key, tid));</div><div class="line"></div><div class="line"> <span class="keyword">delete</span> mlog;</div><div class="line"></div><div class="line"> <a class="code" href="group__DEPRECATED__PIN__API.html#ga07e007644db1d47bb89f97aa5273bc36">PIN_SetThreadData</a>(mlog_key, 0, tid);</div><div class="line">}</div><div class="line"></div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Print Help Message */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line">INT32 Usage()</div><div class="line">{</div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot;This tool demonstrates the basic use of the buffering API.&quot;</span> &lt;&lt; endl;</div><div class="line"> cerr &lt;&lt; endl &lt;&lt; KNOB_BASE::StringKnobSummary() &lt;&lt; endl;</div><div class="line"> <span class="keywordflow">return</span> -1;</div><div class="line">}</div><div class="line"></div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Main */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> *argv[])</div><div class="line">{</div><div class="line"> <span class="comment">// Initialize PIN library. Print help message if -h(elp) is specified</span></div><div class="line"> <span class="comment">// in the command line or the command line is invalid</span></div><div class="line"> <span class="keywordflow">if</span>( <a class="code" href="group__PIN__CONTROL.html#ga783d3bd40c3fb2ca51b1f9af31a70c9c">PIN_Init</a>(argc,argv) )</div><div class="line"> {</div><div class="line"> <span class="keywordflow">return</span> Usage();</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// Initialize the memory reference buffer;</span></div><div class="line"> <span class="comment">// set up the callback to process the buffer.</span></div><div class="line"> <span class="comment">//</span></div><div class="line"> bufId = <a class="code" href="group__BUFFER__API.html#ga008bd698d07658fc4f60fd9b61fb81bc">PIN_DefineTraceBuffer</a>(<span class="keyword">sizeof</span>(<span class="keyword">struct</span> MEMREF), NUM_BUF_PAGES,</div><div class="line"> BufferFull, 0);</div><div class="line"></div><div class="line"> <span class="keywordflow">if</span>(bufId == BUFFER_ID_INVALID)</div><div class="line"> {</div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot;Error: could not allocate initial buffer&quot;</span> &lt;&lt; endl;</div><div class="line"> <span class="keywordflow">return</span> 1;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// Initialize thread-specific data not handled by buffering api.</span></div><div class="line"> mlog_key = <a class="code" href="group__PIN__THREAD__API.html#ga681b583239becd0b181f5b31e865931c">PIN_CreateThreadDataKey</a>(0);</div><div class="line"></div><div class="line"> <span class="comment">// add an instrumentation function</span></div><div class="line"> <a class="code" href="group__TRACE__BASIC__API.html#ga41381de13d25c4bbd968cb64cb719d56">TRACE_AddInstrumentFunction</a>(Trace, 0);</div><div class="line"></div><div class="line"> <span class="comment">// add callbacks</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#ga93431bb0680a22395327ac7d8bb0c14c">PIN_AddThreadStartFunction</a>(ThreadStart, 0);</div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gae79d468cc5e19b450603f07f3397203d">PIN_AddThreadFiniFunction</a>(ThreadFini, 0);</div><div class="line"></div><div class="line"> <span class="comment">// Start the program, never returns</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gaded401aeb030a76ee3396137b06ad808">PIN_StartProgram</a>();</div><div class="line"></div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line">}</div><div class="line"></div><div class="line"></div></div><!-- fragment --><h2><a class="anchor" id="StaticInstructionCounts"></a>
Finding the Static Properties of an Image</h2>
<p>It is also possible to use Pin to examine binaries without instrumenting them. This is useful when you need to know static properties of an image. The sample tool below counts the number of instructions in an image, but does not insert any instrumentation.</p>
<p>The example can be found in source/tools/ManualExamples/staticcount.cpp</p>
<div class="fragment"><div class="line"><span class="comment">//</span></div><div class="line"><span class="comment">// This tool prints a trace of image load and unload events</span></div><div class="line"><span class="comment">//</span></div><div class="line"></div><div class="line"><span class="preprocessor">#include &lt;stdio.h&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"><span class="preprocessor">#include &quot;pin.H&quot;</span></div><div class="line"><span class="keyword">using</span> std::cerr;</div><div class="line"><span class="keyword">using</span> std::endl;</div><div class="line"></div><div class="line"></div><div class="line"><span class="comment">// Pin calls this function every time a new img is loaded</span></div><div class="line"><span class="comment">// It can instrument the image, but this example merely</span></div><div class="line"><span class="comment">// counts the number of static instructions in the image</span></div><div class="line"></div><div class="line">VOID ImageLoad(IMG img, VOID *v)</div><div class="line">{</div><div class="line"> UINT32 count = 0;</div><div class="line"> </div><div class="line"> <span class="keywordflow">for</span> (SEC sec = <a class="code" href="group__IMG__BASIC__API.html#gaa9597e002a76d7a5e5e1b530bb263aad">IMG_SecHead</a>(img); <a class="code" href="group__SEC__BASIC__API.html#ga584ce38ee42410cf65bb5c7201760663">SEC_Valid</a>(sec); sec = <a class="code" href="group__SEC__BASIC__API.html#ga0f20232da7164c5a2bd7a484218cfa36">SEC_Next</a>(sec))</div><div class="line"> { </div><div class="line"> <span class="keywordflow">for</span> (RTN rtn = <a class="code" href="group__SEC__BASIC__API.html#ga2b837186aae0819ca2389253438d22b9">SEC_RtnHead</a>(sec); <a class="code" href="group__RTN__BASIC__API.html#ga6ac855c9a19a3aab44347188e6695875">RTN_Valid</a>(rtn); rtn = <a class="code" href="group__RTN__BASIC__API.html#ga491bf55c9718f8751054ebe37b460d65">RTN_Next</a>(rtn))</div><div class="line"> {</div><div class="line"> <span class="comment">// Prepare for processing of RTN, an RTN is not broken up into BBLs,</span></div><div class="line"> <span class="comment">// it is merely a sequence of INSs </span></div><div class="line"> <a class="code" href="group__RTN__BASIC__API.html#gaf8714086f8aebc9feacccc8cd02dc561">RTN_Open</a>(rtn);</div><div class="line"> </div><div class="line"> <span class="keywordflow">for</span> (INS ins = <a class="code" href="group__RTN__BASIC__API.html#gab1bd91206939b88057664c46ef8eac86">RTN_InsHead</a>(rtn); <a class="code" href="group__INS__BASIC__API__GEN__IA32.html#ga3a8b61fffa9ae4ad9f899b21ce37397c">INS_Valid</a>(ins); ins = <a class="code" href="group__INS__BASIC__API__GEN__IA32.html#ga227ce58a739b1573125c11071ecb48de">INS_Next</a>(ins))</div><div class="line"> {</div><div class="line"> count++;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// to preserve space, release data associated with RTN after we have processed it</span></div><div class="line"> <a class="code" href="group__RTN__BASIC__API.html#ga37272253377eb65c9eb5ff47ec4f1e6b">RTN_Close</a>(rtn);</div><div class="line"> }</div><div class="line"> }</div><div class="line"> fprintf(stderr, <span class="stringliteral">&quot;Image %s has %d instructions\n&quot;</span>, <a class="code" href="group__IMG__BASIC__API.html#ga22acd549352fc062c6c62c82e7a09354">IMG_Name</a>(img).c_str(), count);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Print Help Message */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line">INT32 Usage()</div><div class="line">{</div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot;This tool prints a log of image load and unload events&quot;</span> &lt;&lt; endl;</div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot; along with static instruction counts for each image.&quot;</span> &lt;&lt; endl;</div><div class="line"> cerr &lt;&lt; endl &lt;&lt; KNOB_BASE::StringKnobSummary() &lt;&lt; endl;</div><div class="line"> <span class="keywordflow">return</span> -1;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Main */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> * argv[])</div><div class="line">{</div><div class="line"> <span class="comment">// prepare for image instrumentation mode</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#ga8cf4aca0b0bdbc7fc0ae965883d8e3c2">PIN_InitSymbols</a>();</div><div class="line"></div><div class="line"> <span class="comment">// Initialize pin</span></div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__PIN__CONTROL.html#ga783d3bd40c3fb2ca51b1f9af31a70c9c">PIN_Init</a>(argc, argv)) <span class="keywordflow">return</span> Usage();</div><div class="line"></div><div class="line"> <span class="comment">// Register ImageLoad to be called when an image is loaded</span></div><div class="line"> <a class="code" href="group__IMG__BASIC__API.html#ga494869187b5d94d7dd346bc9ff49642f">IMG_AddInstrumentFunction</a>(ImageLoad, 0);</div><div class="line"></div><div class="line"> <span class="comment">// Start the program, never returns</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gaded401aeb030a76ee3396137b06ad808">PIN_StartProgram</a>();</div><div class="line"> </div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment --><h2><a class="anchor" id="DetachPin"></a>
Detaching Pin from the Application</h2>
<p>Pin can relinquish control of application any time when invoked via PIN_Detach. Control is returned to the original uninstrumented code and the application runs at native speed. Thereafter no instrumented code is ever executed.</p>
<p>The example can be found in source/tools/ManualExamples/detach.cpp</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &lt;stdio.h&gt;</span></div><div class="line"><span class="preprocessor">#include &quot;pin.H&quot;</span></div><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"><span class="keyword">using</span> std::cerr;</div><div class="line"><span class="keyword">using</span> std::endl;</div><div class="line"></div><div class="line"><span class="comment">// This tool shows how to detach Pin from an </span></div><div class="line"><span class="comment">// application that is under Pin&#39;s control.</span></div><div class="line"></div><div class="line">UINT64 icount = 0;</div><div class="line"></div><div class="line"><span class="preprocessor">#define N 10000</span></div><div class="line">VOID docount() </div><div class="line">{</div><div class="line"> icount++;</div><div class="line"></div><div class="line"> <span class="comment">// Release control of application if 10000 </span></div><div class="line"> <span class="comment">// instructions have been executed</span></div><div class="line"> <span class="keywordflow">if</span> ((icount % N) == 0) </div><div class="line"> {</div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#ga6277d16bf33ede39685a26a92fc3cbef">PIN_Detach</a>();</div><div class="line"> }</div><div class="line">}</div><div class="line"> </div><div class="line">VOID Instruction(INS ins, VOID *v)</div><div class="line">{</div><div class="line"> <a class="code" href="group__INS__INST__API.html#ga74a956a0acde197043d04f4adcde4626">INS_InsertCall</a>(ins, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>, (AFUNPTR)docount, IARG_END);</div><div class="line">}</div><div class="line"></div><div class="line">VOID ByeWorld(VOID *v)</div><div class="line">{</div><div class="line"> std::cerr &lt;&lt; endl &lt;&lt; <span class="stringliteral">&quot;Detached at icount = &quot;</span> &lt;&lt; N &lt;&lt; endl;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Print Help Message */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line">INT32 Usage()</div><div class="line">{</div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot;This tool demonstrates how to detach Pin from an &quot;</span> &lt;&lt; endl;</div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot;application that is under Pin&#39;s control&quot;</span> &lt;&lt; endl;</div><div class="line"> cerr &lt;&lt; endl &lt;&lt; KNOB_BASE::StringKnobSummary() &lt;&lt; endl;</div><div class="line"> <span class="keywordflow">return</span> -1;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Main */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> * argv[])</div><div class="line">{</div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__PIN__CONTROL.html#ga783d3bd40c3fb2ca51b1f9af31a70c9c">PIN_Init</a>(argc, argv)) <span class="keywordflow">return</span> Usage();</div><div class="line"></div><div class="line"> <span class="comment">// Callback function to invoke for every </span></div><div class="line"> <span class="comment">// execution of an instruction</span></div><div class="line"> <a class="code" href="group__INS__INST__API.html#gaaff4a98e0ece27fc46c0050b4ae05c6d">INS_AddInstrumentFunction</a>(Instruction, 0);</div><div class="line"> </div><div class="line"> <span class="comment">// Callback functions to invoke before</span></div><div class="line"> <span class="comment">// Pin releases control of the application</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gafc04e55a26e3b74cdebb8c6a1bf5503b">PIN_AddDetachFunction</a>(ByeWorld, 0);</div><div class="line"> </div><div class="line"> <span class="comment">// Never returns</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gaded401aeb030a76ee3396137b06ad808">PIN_StartProgram</a>();</div><div class="line"> </div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment --><h2><a class="anchor" id="ReplaceSigProbed"></a>
Replacing a Routine in Probe Mode</h2>
<p>Probe mode is a method of using Pin to insert probes at the start of specified routines. A probe is a jump instruction that is placed at the start of the specified routine. The probe redirects the flow of control to the replacement function. Before the probe is inserted, the first few instructions of the specified routine are relocated. It is not uncommon for the replacement function to call the replaced routine. Pin provides the relocated address to facilitate this. See the example below.</p>
<p>In probe mode, the application and the replacement routine are run natively. This improves performance, but it puts more responsibility on the tool writer. Probes can only be placed on RTN boundaries.</p>
<p>Many of the PIN APIs that are available in JIT mode are not applicable in Probe mode. In particular, the Pin thread APIs are not supported in Probe mode, because Pin has no information about the threads when the application is run natively. For more information, check the RTN API documentation.</p>
<p>The tool writer must guarantee that there is no jump target where the probe is placed. A probe may be up to 14 bytes long.</p>
<p>Also, it is the tool writer's responsibility to ensure that no thread is currently executing the code where a probe is inserted. Tool writers are encouraged to insert probes when an image is loaded to avoid this problem. Pin will automatically remove the probes when an image is unloaded.</p>
<p>When using probes, Pin must be started with the <a class="el" href="group__PIN__CONTROL.html#ga01a31bf221500b0ca0b97fb64cc62247">PIN_StartProgramProbed()</a> API.</p>
<p>The example can be found in source/tools/ManualExamples/replacesigprobed.cpp. To build this test, execute: </p><pre class="fragment">$ make replacesigprobed.test
</pre><div class="fragment"><div class="line"><span class="comment">// Replace an original function with a custom function defined in the tool using</span></div><div class="line"><span class="comment">// probes. The replacement function has a different signature from that of the </span></div><div class="line"><span class="comment">// original replaced function.</span></div><div class="line"></div><div class="line"><span class="preprocessor">#include &quot;pin.H&quot;</span></div><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"><span class="keyword">using</span> std::cout;</div><div class="line"><span class="keyword">using</span> std::hex;</div><div class="line"><span class="keyword">using</span> std::cerr;</div><div class="line"><span class="keyword">using</span> std::flush;</div><div class="line"><span class="keyword">using</span> std::dec;</div><div class="line"><span class="keyword">using</span> std::endl;</div><div class="line"></div><div class="line"><span class="keyword">typedef</span> VOID * ( *FP_MALLOC )( size_t );</div><div class="line"></div><div class="line"><span class="comment">// This is the replacement routine.</span></div><div class="line"><span class="comment">//</span></div><div class="line">VOID * NewMalloc( FP_MALLOC orgFuncptr, UINT32 arg0, ADDRINT returnIp )</div><div class="line">{</div><div class="line"> <span class="comment">// Normally one would do something more interesting with this data.</span></div><div class="line"> <span class="comment">//</span></div><div class="line"> cout &lt;&lt; <span class="stringliteral">&quot;NewMalloc (&quot;</span></div><div class="line"> &lt;&lt; hex &lt;&lt; ADDRINT ( orgFuncptr ) &lt;&lt; <span class="stringliteral">&quot;, &quot;</span> </div><div class="line"> &lt;&lt; dec &lt;&lt; arg0 &lt;&lt; <span class="stringliteral">&quot;, &quot;</span> </div><div class="line"> &lt;&lt; hex &lt;&lt; returnIp &lt;&lt; <span class="stringliteral">&quot;)&quot;</span></div><div class="line"> &lt;&lt; endl &lt;&lt; flush;</div><div class="line"></div><div class="line"> <span class="comment">// Call the relocated entry point of the original (replaced) routine.</span></div><div class="line"> <span class="comment">//</span></div><div class="line"> VOID * v = orgFuncptr( arg0 );</div><div class="line"></div><div class="line"> <span class="keywordflow">return</span> v;</div><div class="line">}</div><div class="line"></div><div class="line"></div><div class="line"><span class="comment">// Pin calls this function every time a new img is loaded.</span></div><div class="line"><span class="comment">// It is best to do probe replacement when the image is loaded,</span></div><div class="line"><span class="comment">// because only one thread knows about the image at this time.</span></div><div class="line"><span class="comment">//</span></div><div class="line">VOID ImageLoad( IMG img, VOID *v )</div><div class="line">{</div><div class="line"> <span class="comment">// See if malloc() is present in the image. If so, replace it.</span></div><div class="line"> <span class="comment">//</span></div><div class="line"> RTN rtn = <a class="code" href="group__RTN__BASIC__API.html#ga77a2ad03e0431b881d6c3019b45261eb">RTN_FindByName</a>( img, <span class="stringliteral">&quot;malloc&quot;</span> );</div><div class="line"> </div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__RTN__BASIC__API.html#ga6ac855c9a19a3aab44347188e6695875">RTN_Valid</a>(rtn))</div><div class="line"> {</div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__RTN__BASIC__API.html#ga7e153406e2ff0031186ea67d9da1e2d7">RTN_IsSafeForProbedReplacement</a>(rtn))</div><div class="line"> {</div><div class="line"> cout &lt;&lt; <span class="stringliteral">&quot;Replacing malloc in &quot;</span> &lt;&lt; <a class="code" href="group__IMG__BASIC__API.html#ga22acd549352fc062c6c62c82e7a09354">IMG_Name</a>(img) &lt;&lt; endl;</div><div class="line"></div><div class="line"> <span class="comment">// Define a function prototype that describes the application routine</span></div><div class="line"> <span class="comment">// that will be replaced.</span></div><div class="line"> <span class="comment">//</span></div><div class="line"> <a class="code" href="group__PROTO__API.html#ga554ff954c3ea33bb537f30e3b500ef1c">PROTO</a> proto_malloc = <a class="code" href="group__PROTO__API.html#ga83166e4f44766add35b740312e346054">PROTO_Allocate</a>(<a class="code" href="group__PROTO__API.html#gacb4faa1f3649fce55756313c6259519f">PIN_PARG</a>(<span class="keywordtype">void</span> *), CALLINGSTD_DEFAULT,</div><div class="line"> <span class="stringliteral">&quot;malloc&quot;</span>, <a class="code" href="group__PROTO__API.html#gacb4faa1f3649fce55756313c6259519f">PIN_PARG</a>(<span class="keywordtype">int</span>), <a class="code" href="group__PROTO__API.html#gaeebb4a42707b704ebf214a06a6bf4e62">PIN_PARG_END</a>());</div><div class="line"></div><div class="line"> <span class="comment">// Replace the application routine with the replacement function.</span></div><div class="line"> <span class="comment">// Additional arguments have been added to the replacement routine.</span></div><div class="line"> <span class="comment">//</span></div><div class="line"> <a class="code" href="group__RTN__BASIC__API.html#gaec56561cab520a5493a599800319447b">RTN_ReplaceSignatureProbed</a>(rtn, AFUNPTR(NewMalloc),</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dad12677dad18848be51b49ea0f48e07cb">IARG_PROTOTYPE</a>, proto_malloc,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da0425900c8991df5d840dd6d9f9b03295">IARG_ORIG_FUNCPTR</a>,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dab418d242314ea7c67b1febf7667e93a1">IARG_FUNCARG_ENTRYPOINT_VALUE</a>, 0,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da2c4a6ff4e8a076e0f39d24ab73ec7092">IARG_RETURN_IP</a>,</div><div class="line"> IARG_END);</div><div class="line"></div><div class="line"> <span class="comment">// Free the function prototype.</span></div><div class="line"> <span class="comment">//</span></div><div class="line"> <a class="code" href="group__PROTO__API.html#ga164ba9eb7fbd418343184b0e2c8a3ae6">PROTO_Free</a>(proto_malloc);</div><div class="line"> }</div><div class="line"> <span class="keywordflow">else</span></div><div class="line"> {</div><div class="line"> cout &lt;&lt; <span class="stringliteral">&quot;Skip replacing malloc in &quot;</span> &lt;&lt; <a class="code" href="group__IMG__BASIC__API.html#ga22acd549352fc062c6c62c82e7a09354">IMG_Name</a>(img) &lt;&lt; <span class="stringliteral">&quot; since it is not safe.&quot;</span> &lt;&lt; endl;</div><div class="line"> }</div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Print Help Message */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line">INT32 Usage()</div><div class="line">{</div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot;This tool demonstrates how to replace an original&quot;</span> &lt;&lt; endl;</div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot; function with a custom function defined in the tool &quot;</span> &lt;&lt; endl;</div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot; using probes. The replacement function has a different &quot;</span> &lt;&lt; endl;</div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot; signature from that of the original replaced function.&quot;</span> &lt;&lt; endl;</div><div class="line"> cerr &lt;&lt; endl &lt;&lt; KNOB_BASE::StringKnobSummary() &lt;&lt; endl;</div><div class="line"> <span class="keywordflow">return</span> -1;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Main: Initialize and start Pin in Probe mode. */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main( INT32 argc, CHAR *argv[] )</div><div class="line">{</div><div class="line"> <span class="comment">// Initialize symbol processing</span></div><div class="line"> <span class="comment">//</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#ga8cf4aca0b0bdbc7fc0ae965883d8e3c2">PIN_InitSymbols</a>();</div><div class="line"> </div><div class="line"> <span class="comment">// Initialize pin</span></div><div class="line"> <span class="comment">//</span></div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__PIN__CONTROL.html#ga783d3bd40c3fb2ca51b1f9af31a70c9c">PIN_Init</a>(argc, argv)) <span class="keywordflow">return</span> Usage();</div><div class="line"> </div><div class="line"> <span class="comment">// Register ImageLoad to be called when an image is loaded</span></div><div class="line"> <span class="comment">//</span></div><div class="line"> <a class="code" href="group__IMG__BASIC__API.html#ga494869187b5d94d7dd346bc9ff49642f">IMG_AddInstrumentFunction</a>( ImageLoad, 0 );</div><div class="line"> </div><div class="line"> <span class="comment">// Start the program in probe mode, never returns</span></div><div class="line"> <span class="comment">//</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#ga01a31bf221500b0ca0b97fb64cc62247">PIN_StartProgramProbed</a>();</div><div class="line"> </div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line">}</div><div class="line"></div></div><!-- fragment --><h2><a class="anchor" id="FollowChild"></a>
Instrumenting Child Processes</h2>
<p>The <a class="el" href="group__PIN__CONTROL.html#ga5f4e19c43f3de21d382c3c4e2442d961">PIN_AddFollowChildProcessFunction()</a> allows you to define the function you will like to execute before an execv'd process starts. Use the -follow_execv option on the command line to instrument the child processes, like this:</p>
<pre class="fragment">$ ../../../pin -follow_execv -t obj-intel64/follow_child_tool.so -- obj-intel64/follow_child_app1 obj-intel64/follow_child_app2
</pre><p>The example can be found in source/tools/ManualExamples/follow_child_tool.cpp. To build this test, execute: </p><pre class="fragment">$ make follow_child_tool.test
</pre><div class="fragment"><div class="line"><span class="preprocessor">#include &quot;pin.H&quot;</span></div><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;stdio.h&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;unistd.h&gt;</span></div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Command line Switches */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line"></div><div class="line">BOOL FollowChild(<a class="code" href="group__CHILD__PROCESS__API.html#ga17aa0357dbaaec79a971207a6d4ec281">CHILD_PROCESS</a> childProcess, VOID * userData)</div><div class="line">{</div><div class="line"> fprintf(stdout, <span class="stringliteral">&quot;before child:%u\n&quot;</span>, getpid());</div><div class="line"> <span class="keywordflow">return</span> TRUE;</div><div class="line">} </div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main(INT32 argc, CHAR **argv)</div><div class="line">{</div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#ga783d3bd40c3fb2ca51b1f9af31a70c9c">PIN_Init</a>(argc, argv);</div><div class="line"></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#ga5f4e19c43f3de21d382c3c4e2442d961">PIN_AddFollowChildProcessFunction</a>(FollowChild, 0);</div><div class="line"></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gaded401aeb030a76ee3396137b06ad808">PIN_StartProgram</a>();</div><div class="line"></div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line">}</div><div class="line"></div></div><!-- fragment --><h2><a class="anchor" id="ForkOnLinux"></a>
Instrumenting Before and After Forks</h2>
<p>Pin allows Pintools to register for notification callbacks around forks. The <a class="el" href="group__PIN__CONTROL.html#ga7282900fb6160031936d8b63fecc4e21">PIN_AddForkFunction()</a> and <a class="el" href="group__PIN__CONTROL.html#gac25229eab5d0cd015f9d52046771a81f">PIN_AddForkFunctionProbed()</a> callbacks allow you to define the function you want to execute at one of these FPOINTs: </p><pre class="fragment"> FPOINT_BEFORE Call-back in parent, just before fork.
FPOINT_AFTER_IN_PARENT Call-back in parent, immediately after fork.
FPOINT_AFTER_IN_CHILD Call-back in child, immediately after fork.
</pre><p>Note that <a class="el" href="group__PIN__CONTROL.html#ga7282900fb6160031936d8b63fecc4e21">PIN_AddForkFunction()</a> is used for JIT mode and <a class="el" href="group__PIN__CONTROL.html#gac25229eab5d0cd015f9d52046771a81f">PIN_AddForkFunctionProbed()</a> is used for Probed mode. If the fork() fails, the FPOINT_AFTER_IN_PARENT callback, if it is defined, will execute anyway.</p>
<p>The example can be found in source/tools/ManualExamples/fork_jit_tool.cpp. To build this test, execute: </p><pre class="fragment">$ make fork_jit_tool.test
</pre><div class="fragment"><div class="line"></div><div class="line"><span class="preprocessor">#include &lt;stdio.h&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;sys/types.h&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;unistd.h&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;stdlib.h&gt;</span></div><div class="line"></div><div class="line"><span class="preprocessor">#include &quot;pin.H&quot;</span></div><div class="line"></div><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;fstream&gt;</span></div><div class="line"><span class="keyword">using</span> std::cerr;</div><div class="line"><span class="keyword">using</span> std::endl;</div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line">INT32 Usage()</div><div class="line">{</div><div class="line"> cerr &lt;&lt;</div><div class="line"> <span class="stringliteral">&quot;This pin tool registers callbacks around fork().\n&quot;</span></div><div class="line"> <span class="stringliteral">&quot;\n&quot;</span>;</div><div class="line"> cerr &lt;&lt; KNOB_BASE::StringKnobSummary();</div><div class="line"> cerr &lt;&lt; endl;</div><div class="line"> <span class="keywordflow">return</span> -1;</div><div class="line">}</div><div class="line"></div><div class="line"></div><div class="line">pid_t parent_pid;</div><div class="line">PIN_LOCK pinLock;</div><div class="line"></div><div class="line">VOID BeforeFork(<a class="code" href="group__PIN__THREAD__API.html#ga645289be59039349ad77ad2fa7b0e2f3">THREADID</a> threadid, <span class="keyword">const</span> <a class="code" href="group__CONTEXT__API.html#ga73f8f88949aaecf53a6d23f56399c676">CONTEXT</a>* ctxt, VOID * arg)</div><div class="line">{</div><div class="line"> <a class="code" href="group__LOCK.html#ga9569245cd781216f8f1a54d3a0962ddf">PIN_GetLock</a>(&amp;pinLock, threadid+1);</div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot;TOOL: Before fork.&quot;</span> &lt;&lt; endl;</div><div class="line"> <a class="code" href="group__LOCK.html#ga00a837236be573c0c548191e0846df1d">PIN_ReleaseLock</a>(&amp;pinLock);</div><div class="line"> parent_pid = <a class="code" href="group__PIN__PROCESS__API.html#ga4bf5a4a357a5829228abf26faa03604b">PIN_GetPid</a>();</div><div class="line">}</div><div class="line"></div><div class="line">VOID AfterForkInParent(<a class="code" href="group__PIN__THREAD__API.html#ga645289be59039349ad77ad2fa7b0e2f3">THREADID</a> threadid, <span class="keyword">const</span> <a class="code" href="group__CONTEXT__API.html#ga73f8f88949aaecf53a6d23f56399c676">CONTEXT</a>* ctxt, VOID * arg)</div><div class="line">{</div><div class="line"> <a class="code" href="group__LOCK.html#ga9569245cd781216f8f1a54d3a0962ddf">PIN_GetLock</a>(&amp;pinLock, threadid+1);</div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot;TOOL: After fork in parent.&quot;</span> &lt;&lt; endl;</div><div class="line"> <a class="code" href="group__LOCK.html#ga00a837236be573c0c548191e0846df1d">PIN_ReleaseLock</a>(&amp;pinLock);</div><div class="line"></div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__PIN__PROCESS__API.html#ga4bf5a4a357a5829228abf26faa03604b">PIN_GetPid</a>() != parent_pid)</div><div class="line"> {</div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot;PIN_GetPid() fails in parent process&quot;</span> &lt;&lt; endl;</div><div class="line"> exit(-1);</div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line">VOID AfterForkInChild(<a class="code" href="group__PIN__THREAD__API.html#ga645289be59039349ad77ad2fa7b0e2f3">THREADID</a> threadid, <span class="keyword">const</span> <a class="code" href="group__CONTEXT__API.html#ga73f8f88949aaecf53a6d23f56399c676">CONTEXT</a>* ctxt, VOID * arg)</div><div class="line">{</div><div class="line"> <a class="code" href="group__LOCK.html#ga9569245cd781216f8f1a54d3a0962ddf">PIN_GetLock</a>(&amp;pinLock, threadid+1);</div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot;TOOL: After fork in child.&quot;</span> &lt;&lt; endl;</div><div class="line"> <a class="code" href="group__LOCK.html#ga00a837236be573c0c548191e0846df1d">PIN_ReleaseLock</a>(&amp;pinLock);</div><div class="line"> </div><div class="line"> <span class="keywordflow">if</span> ((<a class="code" href="group__PIN__PROCESS__API.html#ga4bf5a4a357a5829228abf26faa03604b">PIN_GetPid</a>() == parent_pid) || (getppid() != parent_pid))</div><div class="line"> {</div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot;PIN_GetPid() fails in child process&quot;</span> &lt;&lt; endl;</div><div class="line"> exit(-1);</div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main(INT32 argc, CHAR **argv)</div><div class="line">{</div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#ga8cf4aca0b0bdbc7fc0ae965883d8e3c2">PIN_InitSymbols</a>();</div><div class="line"> <span class="keywordflow">if</span>( <a class="code" href="group__PIN__CONTROL.html#ga783d3bd40c3fb2ca51b1f9af31a70c9c">PIN_Init</a>(argc,argv) )</div><div class="line"> {</div><div class="line"> <span class="keywordflow">return</span> Usage();</div><div class="line"> }</div><div class="line"> </div><div class="line"> <span class="comment">// Initialize the pin lock</span></div><div class="line"> <a class="code" href="group__LOCK.html#gac9a323f8cf8f4ea4a12080f4b4099edc">PIN_InitLock</a>(&amp;pinLock);</div><div class="line"> </div><div class="line"> <span class="comment">// Register a notification handler that is called when the application</span></div><div class="line"> <span class="comment">// forks a new process.</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#ga7282900fb6160031936d8b63fecc4e21">PIN_AddForkFunction</a>(<a class="code" href="group__PIN__CONTROL.html#ggab459bf0034704bf1aa7fa7e192b7dc08ad25e85d29c19e7e0c5a9a768191bbcd7">FPOINT_BEFORE</a>, BeforeFork, 0); </div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#ga7282900fb6160031936d8b63fecc4e21">PIN_AddForkFunction</a>(<a class="code" href="group__PIN__CONTROL.html#ggab459bf0034704bf1aa7fa7e192b7dc08ae95eedd3db4447dda41b3fe76c7013c6">FPOINT_AFTER_IN_PARENT</a>, AfterForkInParent, 0);</div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#ga7282900fb6160031936d8b63fecc4e21">PIN_AddForkFunction</a>(<a class="code" href="group__PIN__CONTROL.html#ggab459bf0034704bf1aa7fa7e192b7dc08ab97d0822ccc4bd553feab25fc85412fc">FPOINT_AFTER_IN_CHILD</a>, AfterForkInChild, 0);</div><div class="line"> </div><div class="line"> <span class="comment">// Never returns</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gaded401aeb030a76ee3396137b06ad808">PIN_StartProgram</a>();</div><div class="line"> </div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment --><h2><a class="anchor" id="JitApiTools"></a>
Managed platforms support</h2>
<p>Pin allows Pintools to indentify dynamically created code using <a class="el" href="group__RTN__BASIC__API.html#ga260a065245b69511e0071b2b469f854b">RTN_IsDynamic()</a> API (only code of functions which are reported by <a href="http://software.intel.com/sites/products/documentation/doclib/iss/2013/amplifier/lin/ug_docs/GUID-17D7238B-DD19-45DB-B5E0-D9B344D1BE96.htm">Jit Profiling API</a>). The following example demonstrates use of <a class="el" href="group__RTN__BASIC__API.html#ga260a065245b69511e0071b2b469f854b">RTN_IsDynamic()</a> API. This example instruments a program to count the total number of instructions discovered and executed. The instructions are divided to three categories: native instructions, dynamic instructions and instructions without any known routine.</p>
<p>Here is how to run it and display its output with a 32 bit OpenCL sample on Windows:</p>
<pre class="fragment">$ set CL_CONFIG_USE_VTUNE=True
$ set INTEL_JIT_PROFILER32=ia32\bin\pinjitprofiling.dll
$ ia32\bin\pin.exe -t source\tools\JitProfilingApiTests\obj-ia32\DynamicInsCount.dll -support_jit_api -o DynamicInsCount.out -- ..\OpenCL\Win32\Debug\BitonicSort.exe
No command line arguments specified, using default values.
Initializing OpenCL runtime...
Trying to run on a CPU
OpenCL data alignment is 128 bytes.
Reading file 'BitonicSort.cl' (size 3435 bytes)
Sort order is ascending
Input size is 1048576 items
Executing OpenCL kernel...
Executing reference...
Performing verification...
Verification succeeded.
NDRange perf. counter time 12994.272962 ms.
Releasing resources...
$ type JitInsCount.out
===============================================
Number of executed native instructions: 7631596649
Number of executed jitted instructions: 438983207
Number of executed instructions without any known routine: 12246
===============================================
Number of discovered native instructions: 870531
Number of discovered jitted instructions: 223
Number of discovered instructions without any known routine: 36
===============================================
$
</pre><p>The example can be found in source\tools\JitProfilingApiTests\DynamicInsCount.cpp</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;pin.H&quot;</span></div><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;fstream&gt;</span></div><div class="line"></div><div class="line"><span class="comment">// ==================================================================</span></div><div class="line"><span class="comment">// Global variables</span></div><div class="line"><span class="comment">// ==================================================================</span></div><div class="line"></div><div class="line">UINT64 insNativeDiscoveredCount = 0; <span class="comment">//number of discovered native instructions</span></div><div class="line">UINT64 insDynamicDiscoveredCount = 0; <span class="comment">//number of discovered dynamic instructions</span></div><div class="line">UINT64 insNoRtnDiscoveredCount = 0; <span class="comment">//number of discovered instructions without any known routine</span></div><div class="line"></div><div class="line">UINT64 insNativeExecutedCount = 0; <span class="comment">//number of executed native instructions</span></div><div class="line">UINT64 insDynamicExecutedCount = 0; <span class="comment">//number of executed dynamic instructions</span></div><div class="line">UINT64 insNoRtnExecutedCount = 0; <span class="comment">//number of executed instructions without any known routine</span></div><div class="line"></div><div class="line">std::ostream * out = &amp;cerr;</div><div class="line"></div><div class="line"><span class="comment">// =====================================================================</span></div><div class="line"><span class="comment">// Command line switches</span></div><div class="line"><span class="comment">// =====================================================================</span></div><div class="line"></div><div class="line">KNOB&lt;string&gt; KnobOutputFile(<a class="code" href="group__KNOB__BASIC.html#ggad45510089e3b85a88df038e900e9f8baa576ddd3b58b1121ff4070df605951cf6">KNOB_MODE_WRITEONCE</a>, <span class="stringliteral">&quot;pintool&quot;</span>, <span class="stringliteral">&quot;o&quot;</span>, <span class="stringliteral">&quot;&quot;</span>, <span class="stringliteral">&quot;specify file name for output&quot;</span>);</div><div class="line"></div><div class="line"><span class="comment">// =====================================================================</span></div><div class="line"><span class="comment">// Utilities</span></div><div class="line"><span class="comment">// =====================================================================</span></div><div class="line"></div><div class="line"><span class="comment">// Print out help message.</span></div><div class="line">INT32 Usage()</div><div class="line">{</div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot;This tool prints out the number of native and dynamic instructions&quot;</span> &lt;&lt; endl;</div><div class="line"> cerr &lt;&lt; KNOB_BASE::StringKnobSummary() &lt;&lt; endl;</div><div class="line"> <span class="keywordflow">return</span> -1;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// =====================================================================</span></div><div class="line"><span class="comment">// Analysis routines</span></div><div class="line"><span class="comment">// =====================================================================</span></div><div class="line"></div><div class="line"><span class="comment">// This function is called before every native instruction is executed</span></div><div class="line">VOID InsNativeCount()</div><div class="line">{</div><div class="line"> ++insNativeExecutedCount;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// This function is called before every dynamic instruction is executed</span></div><div class="line">VOID InsDynamicCount()</div><div class="line">{</div><div class="line"> ++insDynamicExecutedCount;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// This function is called before every instruction without any known routine is executed</span></div><div class="line">VOID InsNoRtnCount()</div><div class="line">{</div><div class="line"> ++insNoRtnExecutedCount;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// =====================================================================</span></div><div class="line"><span class="comment">// Instrumentation callbacks</span></div><div class="line"><span class="comment">// =====================================================================</span></div><div class="line"></div><div class="line"><span class="comment">// Pin calls this function every time a new instruction is encountered</span></div><div class="line">VOID Instruction(INS ins, VOID *v)</div><div class="line">{</div><div class="line"> RTN rtn = <a class="code" href="group__INS__BASIC__API__GEN__IA32.html#ga45207e8a66dd24f7e1718679edbd2cd4">INS_Rtn</a>(ins);</div><div class="line"> <span class="keywordflow">if</span> (!<a class="code" href="group__RTN__BASIC__API.html#ga6ac855c9a19a3aab44347188e6695875">RTN_Valid</a>(rtn))</div><div class="line"> {</div><div class="line"> ++insNoRtnDiscoveredCount;</div><div class="line"> <a class="code" href="group__INS__INST__API.html#ga74a956a0acde197043d04f4adcde4626">INS_InsertCall</a>(ins, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>, (AFUNPTR)InsNoRtnCount, IARG_END);</div><div class="line"> }</div><div class="line"> <span class="keywordflow">else</span> <span class="keywordflow">if</span> (<a class="code" href="group__RTN__BASIC__API.html#ga260a065245b69511e0071b2b469f854b">RTN_IsDynamic</a>(rtn))</div><div class="line"> {</div><div class="line"> ++insDynamicDiscoveredCount;</div><div class="line"> <a class="code" href="group__INS__INST__API.html#ga74a956a0acde197043d04f4adcde4626">INS_InsertCall</a>(ins, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>, (AFUNPTR)InsDynamicCount, IARG_END);</div><div class="line"> }</div><div class="line"> <span class="keywordflow">else</span></div><div class="line"> {</div><div class="line"> ++insNativeDiscoveredCount;</div><div class="line"> <a class="code" href="group__INS__INST__API.html#ga74a956a0acde197043d04f4adcde4626">INS_InsertCall</a>(ins, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>, (AFUNPTR)InsNativeCount, IARG_END);</div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// Print out analysis results.</span></div><div class="line"><span class="comment">// This function is called when the application exits.</span></div><div class="line"><span class="comment">// @param[in] code exit code of the application</span></div><div class="line"><span class="comment">// @param[in] v value specified by the tool in the</span></div><div class="line"><span class="comment">// PIN_AddFiniFunction function call</span></div><div class="line">VOID Fini(INT32 code, VOID *v)</div><div class="line">{</div><div class="line"> *out &lt;&lt; <span class="stringliteral">&quot;===============================================&quot;</span> &lt;&lt; endl;</div><div class="line"> *out &lt;&lt; <span class="stringliteral">&quot;Number of executed native instructions: &quot;</span> &lt;&lt; insNativeExecutedCount &lt;&lt; endl;</div><div class="line"> *out &lt;&lt; <span class="stringliteral">&quot;Number of executed dynamic instructions: &quot;</span> &lt;&lt; insDynamicExecutedCount &lt;&lt; endl;</div><div class="line"> *out &lt;&lt; <span class="stringliteral">&quot;Number of executed instructions without any known routine: &quot;</span> &lt;&lt; insNoRtnExecutedCount &lt;&lt; endl;</div><div class="line"> *out &lt;&lt; <span class="stringliteral">&quot;===============================================&quot;</span> &lt;&lt; endl;</div><div class="line"> *out &lt;&lt; <span class="stringliteral">&quot;Number of discovered native instructions: &quot;</span> &lt;&lt; insNativeDiscoveredCount &lt;&lt; endl;</div><div class="line"> *out &lt;&lt; <span class="stringliteral">&quot;Number of discovered dynamic instructions: &quot;</span> &lt;&lt; insDynamicDiscoveredCount &lt;&lt; endl;</div><div class="line"> *out &lt;&lt; <span class="stringliteral">&quot;Number of discovered instructions without any known routine: &quot;</span> &lt;&lt; insNoRtnDiscoveredCount &lt;&lt; endl;</div><div class="line"> *out &lt;&lt; <span class="stringliteral">&quot;===============================================&quot;</span> &lt;&lt; endl;</div><div class="line"></div><div class="line"> <span class="keywordtype">string</span> fileName = KnobOutputFile.Value();</div><div class="line"> <span class="keywordflow">if</span> (!fileName.empty())</div><div class="line"> {</div><div class="line"> <span class="keyword">delete</span> out;</div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// The main procedure of the tool.</span></div><div class="line"><span class="comment">// This function is called when the application image is loaded but not yet started.</span></div><div class="line"><span class="comment">// @param[in] argc total number of elements in the argv array</span></div><div class="line"><span class="comment">// @param[in] argv array of command line arguments,</span></div><div class="line"><span class="comment">// including pin -t &lt;toolname&gt; -- ...</span></div><div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> *argv[])</div><div class="line">{</div><div class="line"> <span class="comment">// Initialize symbol processing</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#ga8cf4aca0b0bdbc7fc0ae965883d8e3c2">PIN_InitSymbols</a>();</div><div class="line"></div><div class="line"> <span class="comment">// Initialize PIN library. Print help message if -h(elp) is specified</span></div><div class="line"> <span class="comment">// in the command line or the command line is invalid</span></div><div class="line"> <span class="keywordflow">if</span>(<a class="code" href="group__PIN__CONTROL.html#ga783d3bd40c3fb2ca51b1f9af31a70c9c">PIN_Init</a>(argc,argv))</div><div class="line"> {</div><div class="line"> <span class="keywordflow">return</span> Usage();</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keywordtype">string</span> fileName = KnobOutputFile.Value();</div><div class="line"></div><div class="line"> <span class="keywordflow">if</span> (!fileName.empty())</div><div class="line"> {</div><div class="line"> out = <span class="keyword">new</span> std::ofstream(fileName.c_str());</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// Register Instruction to be called to instrument instructions</span></div><div class="line"> <a class="code" href="group__INS__INST__API.html#gaaff4a98e0ece27fc46c0050b4ae05c6d">INS_AddInstrumentFunction</a>(Instruction, NULL);</div><div class="line"></div><div class="line"> <span class="comment">// Register function to be called when the application exits</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gac167b8d28d255e53a0ac1f6e9edcd3ec">PIN_AddFiniFunction</a>(Fini, NULL);</div><div class="line"></div><div class="line"> <span class="comment">// Start the program, never returns</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gaded401aeb030a76ee3396137b06ad808">PIN_StartProgram</a>();</div><div class="line"></div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment --><p>Pin allows Pintools to instrument just compiled functions using RTN_AddInstrumentFunction API. Following example instruments a program to log Jitting and running of dynamic functions which are reported by <a href="http://software.intel.com/sites/products/documentation/doclib/iss/2013/amplifier/lin/ug_docs/GUID-17D7238B-DD19-45DB-B5E0-D9B344D1BE96.htm">Jit Profiling API</a>.</p>
<p>Here is how to run it with a 64 bit OpenCL sample on Linux:</p>
<pre class="fragment">$ setenv CL_CONFIG_USE_VTUNE True
$ setenv INTEL_JIT_PROFILER64 intel64/lib/libpinjitprofiling.so
$ ./pin -t source/tools/JitProfilingApiTests/obj-intel64/DynamicFuncInstrument.so -support_jit_api -o DynamicFuncInstrument.out -- ..\OpenCL\Win32\Debug\BitonicSort.exe
No command line arguments specified, using default values.
Initializing OpenCL runtime...
Trying to run on a CPU
OpenCL data alignment is 128 bytes.
Reading file 'BitonicSort.cl' (size 3435 bytes)
Sort order is ascending
Input size is 1048576 items
Executing OpenCL kernel...
Executing reference...
Performing verification...
Verification succeeded.
NDRange perf. counter time 12994.272962 ms.
Releasing resources...
$
</pre><p>The example can be found in source\tools\JitProfilingApiTests\DynamicFuncInstrument.cpp</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;pin.H&quot;</span></div><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;fstream&gt;</span></div><div class="line"></div><div class="line"><span class="comment">// =====================================================================</span></div><div class="line"><span class="comment">// Global variables</span></div><div class="line"><span class="comment">// =====================================================================</span></div><div class="line"></div><div class="line">std::ostream * out = &amp;cerr;</div><div class="line"></div><div class="line"><span class="comment">// =====================================================================</span></div><div class="line"><span class="comment">// Command line switches</span></div><div class="line"><span class="comment">// =====================================================================</span></div><div class="line"></div><div class="line">KNOB&lt;string&gt; KnobOutputFile(<a class="code" href="group__KNOB__BASIC.html#ggad45510089e3b85a88df038e900e9f8baa576ddd3b58b1121ff4070df605951cf6">KNOB_MODE_WRITEONCE</a>, <span class="stringliteral">&quot;pintool&quot;</span>, <span class="stringliteral">&quot;o&quot;</span>, <span class="stringliteral">&quot;&quot;</span>, <span class="stringliteral">&quot;specify file name for output&quot;</span>);</div><div class="line"></div><div class="line"><span class="comment">// =====================================================================</span></div><div class="line"><span class="comment">// Utilities</span></div><div class="line"><span class="comment">// =====================================================================</span></div><div class="line"></div><div class="line"><span class="comment">// Print out help message.</span></div><div class="line">INT32 Usage()</div><div class="line">{</div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot;This tool prints out the stack filtered by the dynamicaly created functions only&quot;</span> &lt;&lt; endl;</div><div class="line"> cerr &lt;&lt; KNOB_BASE::StringKnobSummary() &lt;&lt; endl;</div><div class="line"> <span class="keywordflow">return</span> -1;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// =====================================================================</span></div><div class="line"><span class="comment">// Analysis routines</span></div><div class="line"><span class="comment">// =====================================================================</span></div><div class="line"></div><div class="line">VOID RtnCallPrint(CHAR * rtnName)</div><div class="line">{</div><div class="line"> *out &lt;&lt; <span class="stringliteral">&quot;Before run &quot;</span> &lt;&lt; rtnName &lt;&lt; endl;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// =====================================================================</span></div><div class="line"><span class="comment">// Instrumentation callbacks</span></div><div class="line"><span class="comment">// =====================================================================</span></div><div class="line"></div><div class="line"><span class="comment">// Pin calls this function every time a new rtn is executed</span></div><div class="line">VOID Routine(RTN rtn, VOID *v)</div><div class="line">{</div><div class="line"> <span class="keywordflow">if</span> (!<a class="code" href="group__RTN__BASIC__API.html#ga260a065245b69511e0071b2b469f854b">RTN_IsDynamic</a>(rtn))</div><div class="line"> {</div><div class="line"> <span class="keywordflow">return</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> *out &lt;&lt; <span class="stringliteral">&quot;Just discovered &quot;</span> &lt;&lt; <a class="code" href="group__RTN__BASIC__API.html#gacac860956fa8cf004a51e823e81a2ac0">RTN_Name</a>(rtn) &lt;&lt; endl;</div><div class="line"></div><div class="line"> <a class="code" href="group__RTN__BASIC__API.html#gaf8714086f8aebc9feacccc8cd02dc561">RTN_Open</a>(rtn);</div><div class="line"></div><div class="line"> <span class="comment">// Insert a call at the entry point of a routine to increment the call count</span></div><div class="line"> <a class="code" href="group__RTN__BASIC__API.html#ga76bde295a78d1232fd6ff98a5ff011cf">RTN_InsertCall</a>(rtn, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>, (AFUNPTR)RtnCallPrint, <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da34126f334d65afac69784351a03615ad">IARG_ADDRINT</a>, <a class="code" href="group__RTN__BASIC__API.html#gacac860956fa8cf004a51e823e81a2ac0">RTN_Name</a>(rtn).c_str(), IARG_END);</div><div class="line"></div><div class="line"> <a class="code" href="group__RTN__BASIC__API.html#ga37272253377eb65c9eb5ff47ec4f1e6b">RTN_Close</a>(rtn);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// Print out analysis results.</span></div><div class="line"><span class="comment">// This function is called when the application exits.</span></div><div class="line"><span class="comment">// @param[in] code exit code of the application</span></div><div class="line"><span class="comment">// @param[in] v value specified by the tool in the</span></div><div class="line"><span class="comment">// PIN_AddFiniFunction function call</span></div><div class="line">VOID Fini(INT32 code, VOID *v)</div><div class="line">{</div><div class="line"> <span class="keyword">const</span> <span class="keywordtype">string</span> fileName = KnobOutputFile.Value();</div><div class="line"> <span class="keywordflow">if</span> (!fileName.empty())</div><div class="line"> {</div><div class="line"> <span class="keyword">delete</span> out;</div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// The main procedure of the tool.</span></div><div class="line"><span class="comment">// This function is called when the application image is loaded but not yet started.</span></div><div class="line"><span class="comment">// @param[in] argc total number of elements in the argv array</span></div><div class="line"><span class="comment">// @param[in] argv array of command line arguments,</span></div><div class="line"><span class="comment">// including pin -t &lt;toolname&gt; -- ...</span></div><div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> *argv[])</div><div class="line">{</div><div class="line"> <span class="comment">// Initialize symbol processing</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#ga8cf4aca0b0bdbc7fc0ae965883d8e3c2">PIN_InitSymbols</a>();</div><div class="line"></div><div class="line"> <span class="comment">// Initialize PIN library. Print help message if -h(elp) is specified</span></div><div class="line"> <span class="comment">// in the command line or the command line is invalid</span></div><div class="line"> <span class="keywordflow">if</span>(<a class="code" href="group__PIN__CONTROL.html#ga783d3bd40c3fb2ca51b1f9af31a70c9c">PIN_Init</a>(argc,argv))</div><div class="line"> {</div><div class="line"> <span class="keywordflow">return</span> Usage();</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">const</span> <span class="keywordtype">string</span> fileName = KnobOutputFile.Value();</div><div class="line"></div><div class="line"> <span class="keywordflow">if</span> (!fileName.empty())</div><div class="line"> {</div><div class="line"> out = <span class="keyword">new</span> std::ofstream(fileName.c_str());</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// Register Routine to be called to instrument rtn</span></div><div class="line"> <a class="code" href="group__RTN__BASIC__API.html#gad10b9862dbe2f9bef8f7978492c35d01">RTN_AddInstrumentFunction</a>(Routine, 0);</div><div class="line"></div><div class="line"> <span class="comment">// Register function to be called when the application exits</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gac167b8d28d255e53a0ac1f6e9edcd3ec">PIN_AddFiniFunction</a>(Fini, NULL);</div><div class="line"></div><div class="line"> <span class="comment">// Start the program, never returns</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gaded401aeb030a76ee3396137b06ad808">PIN_StartProgram</a>();</div><div class="line"></div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment --><p><br />
</p><hr/>
<h1><a class="anchor" id="CALLBACK"></a>
Callbacks</h1>
<hr/>
<p>The examples in the previous section have introduced a number of ways to register callback functions via the Pin API, such as:</p>
<ul>
<li>INS_AddInstrumentFunction (INSCALLBACK fun, VOID *val)</li>
<li>TRACE_AddInstrumentFunction (TRACECALLBACK fun, VOID *val)</li>
<li>RTN_AddInstrumentFunction (RTNCALLBACK fun, VOID *val)</li>
<li>IMG_AddInstrumentFunction (IMGCALLBACK fun, VOID *val)</li>
<li>PIN_AddFiniFunction (FINICALLBACK fun, VOID *val)</li>
<li>PIN_AddDetachFunction (DETACHCALLBACK fun, VOID *val)</li>
</ul>
<p>The extra parameter <code>val</code> (shared by all the registration functions) will be passed to <code>fun</code> as its second argument whenever it is "called back". This is a standard mechanism used in GUI programming with callbacks.</p>
<p>If this feature is not needed, it is safe to pass 0 for <code>val</code> when registering a callback. The expected use of <code>val</code> is to pass a pointer to an instance of a class. Since <code>val</code> is a generic pointer, <code>fun</code> must cast it back to an object before dereferencing the pointer.</p>
<p>Note that all callback registration functions return a PIN_CALLBACK object which can later be used to manipulate the properties of the registered callback (for example change the order in which PIN executes callback functions of the same type). This can be done by calling API functions that manipulates the PIN_CALLBACK object (see <a class="el" href="group__PIN__CALLBACKS.html">PIN callbacks</a>)</p>
<p><br />
</p><hr/>
<h1><a class="anchor" id="MODIFYING"></a>
Modifying Application Instructions</h1>
<hr/>
<p>Although Pin is most commonly used for instrumenting applications, it is also possible to change the application's instructions. The simplest way to do this is to insert an analysis routine to emulate an instruction, and then use <a class="el" href="group__INS__MOD__API__GEN__IA32.html#gad37791f157338a12e22f8d9c54f09fe4">INS_Delete()</a> to remove the original instruction. It is also possible to insert direct or indirect branches (using INS_InsertDirectJump and INS_InsertIndirectJump), which makes it easier to emulate instructions that change the control flow.</p>
<p>The memory addresses accessed by an instruction can be modified to refer to a value calculated by an analysis routine using INS_RewriteMemoryOperand.</p>
<p>Note that in all of the cases where an instruction is modified, the modification is only made after all of the instrumentation routines have been executed. Therefore all of the instrumentation routines see the original, un-modified instruction.</p>
<p><br />
</p><hr/>
<h1><a class="anchor" id="APPDEBUG"></a>
The Pin Advanced Debugging Extensions</h1>
<hr/>
<p>Pin's advanced debugging extensions allow you to debug an application, even while it runs under Pin in JIT mode. Moreover, your Pintool can add support for new debugger commands, without making any changes to GDB, LLDB or Visual Studio. This allows you to interactively control your Pintool from within a live debugger session. Finally, Pintools can add powerful new debugger features that are enabled via instrumentation. For example, a Pintool can use instrumentation to look for an interesting condition (like a memory buffer overwrite) and then stop at a live debugger session when that condition occurs.</p>
<p>This section illustrates these three concepts:</p>
<ul>
<li>Enabling all the traditional debugger features even while running an application under Pin in JIT mode.</li>
<li>Recognizing new debugger commands in your Pintool to allow interactive control of the tool from a live debugger session.</li>
<li>Adding support for new debugger features by writing a Pintool.</li>
</ul>
<p>These features are available on Linux (using GDB), macOS (using LLDB) and Windows (using Visual Studio). The Pin APIs are the same in all cases, but their usage from within the debugger may differ because each debugger has a different UI. The following tutorial is divided into two sections: one that is Linux and macOS centric and another that is Windows centric. They both describe the same example, so you can continue by reading either section.</p>
<ul>
<li><a class="el" href="index.html#APPDEBUG_UNIX">Tutorial for Linux and macOS</a></li>
<li><a class="el" href="index.html#APPDEBUG_WINDOWS">Tutorial for Windows</a></li>
</ul>
<p>Finally, note that these advanced debugging extensions are not at all related to debugging your Pintool. If you have a bug in your tool and need to debug it, see the section <a class="el" href="index.html#DEBUGGING">Tips for Debugging a Pintool</a> instead.</p>
<h2><a class="anchor" id="APPDEBUG_UNIX"></a>
Advanced Debugging Extensions on Linux and macOS</h2>
<p>Pin's debugging extensions on Linux work with nearly all modern versions of GDB/LLDB, so you can probably use whatever version of GDB/LLDB is already installed on your system. Pin uses GDB's remote debugger features, so it should work with any version of GDB/LLDB that supports that feature (Yes, LLDB support GDB's remote debugger features).</p>
<p>Throughout this section, we demonstrate the debugging extensions in Pin with the example tool "stack-debugger.cpp", which is available in the directory "source/tools/ManualExamples". You may want to compile that tool and follow along:</p>
<pre class="fragment">$ cd source/tools/ManualExamples
$ make DEBUG=1 stack-debugger.test
</pre><p>The tool and its associated test application, "fibonacci", are built in a directory named "obj-ia32", "obj-intel64", etc., depending on your machine type.</p>
<p>To enable the debugging extensions, run Pin with the <a class="el" href="group__KNOBS.html#SWITCH_APPDEBUG">-appdebug</a> command line switch. This causes Pin to start the application and stop immediately before the first instruction. Pin then prints a message telling you to start debugger.</p>
<p><b>Linux:</b> </p><pre class="fragment">$ ../../../pin -appdebug -t obj-intel64/stack-debugger.so -- obj-intel64/fibonacci.exe 1000
Application stopped until continued from debugger.
Start GDB, then issue this command at the prompt:
target remote :33030
</pre><p><b>macOS:</b> </p><pre class="fragment">$ ../../../pin -appdebug -t obj-intel64/stack-debugger.dylib -- obj-intel64/fibonacci.exe 1000
Application stopped until continued from debugger.
Start LLDB, then issue this command at the (lldb) prompt:
gdb-remote 33030
</pre><p>In another window, start the debugger and enter the command that Pin printed:</p>
<p><b>Linux:</b> </p><pre class="fragment">$ gdb fibonacci
(gdb) target remote :33030
</pre><p><b>macOS:</b> </p><pre class="fragment">$ lldb fibonacci
(lldb) gdb-remote 33030
</pre><p>At this point, the debugger is attached to the application that is running under Pin. You can set breakpoints, continue execution, print out variables, disassemble code, etc.</p>
<p><b>Linux:</b> </p><pre class="fragment">(gdb) break main
Breakpoint 1 at 0x401194: file fibonacci.cpp, line 12.
(gdb) cont
Continuing.
Breakpoint 1, main (argc=2, argv=0x7fbffff3c8) at fibonacci.cpp:12
12 if (argc &gt; 2)
(gdb) print argc
$1 = 2
(gdb) x/4i $pc
0x401194 &lt;main+27&gt;: cmpl $0x2,0xfffffffffffffe5c(%rbp)
0x40119b &lt;main+34&gt;: je 0x4011c8 &lt;main+79&gt;
0x40119d &lt;main+36&gt;: mov $0x402080,%esi
0x4011a2 &lt;main+41&gt;: mov $0x603300,%edi
</pre><p><b>macOS:</b> </p><pre class="fragment">Breakpoint 1: where = fibonacci.exe`main + 34 at fibonacci.cpp:12, address = 0x0000000100000db2
(lldb) c
Process 267 resuming
Process 267 stopped
* thread #1: tid = 0x010b, 0x0000000100000db2 fibonacci.exe`main(argc=2, argv=0x00007fff5fbff880) + 34 at fibonacci.cpp:12, stop reason = breakpoint 1.1
frame #0: 0x0000000100000db2 fibonacci.exe`main(argc=2, argv=0x00007fff5fbff880) + 34 at fibonacci.cpp:12
9
10 int main(int argc, char **argv)
11 {
-&gt; 12 if (argc &gt; 2)
13 {
14 std::cerr &lt;&lt; "Usage: fibonacci [num]" &lt;&lt; std::endl;
15 return 1;
(lldb) print argc
(int) $0 = 2
(lldb) x/4i $rip
-&gt; 0x100000db2: 83 bd 10 fe ff ff 02 cmpl $0x2, -0x1f0(%rbp)
0x100000db9: 0f 8e 4b 00 00 00 jle 0x100000e0a ; &lt;+122&gt; at fibonacci.cpp:18
0x100000dbf: 48 8b 3d 4a 42 00 00 movq 0x424a(%rip), %rdi ; (void *)0x00007fff74b59398: std::__1::cerr
0x100000dc6: 48 8d 35 fb 3f 00 00 leaq 0x3ffb(%rip), %rsi ; "Usage: fibonacci [num]"
</pre><p>Of course, any information you observe in the debugger shows the application's "pure" state. The details of Pin and the tool's instrumentation are hidden. For example, the disassembly you see above shows only the application's instructions, not any of the instructions inserted by the tool. However, when you use commands like "cont" or "step" to advance execution of the application, your tool's instrumentation runs as it normally would under Pin.</p>
<dl class="section note"><dt>Note</dt><dd>After connecting the debugger, you should NOT use the "run" command. The application is already running and stopped at the first instruction. Instead, use the "cont" command to continue execution.</dd></dl>
<h3><a class="anchor" id="APPDEBUG_UNIX_COMMANDS"></a>
Adding New Debugger Commands</h3>
<p>The previous section illustrated how you can enable the normal debugger features while running an application under Pin. Now, let's see how your Pintool can add new custom debugger commands, even without changing the debugger itself. Custom debugger commands are useful because they allow you to control your Pintool interactively from within a live debugger session. For example, you can ask your Pintool to print out information that it has collected, or you can interactively enable instrumentation only for certain phases of the application.</p>
<p>To illustrate, see the call to <a class="el" href="group__APPDEBUG__API.html#ga57d86fbcd855d998c28e27a8dfa56643">PIN_AddDebugInterpreter()</a> in the stack-debugger tool. That API sets up the following call-back function:</p>
<div class="fragment"><div class="line"><span class="keyword">static</span> BOOL DebugInterpreter(<a class="code" href="group__PIN__THREAD__API.html#ga645289be59039349ad77ad2fa7b0e2f3">THREADID</a> tid, <a class="code" href="group__CONTEXT__API.html#ga73f8f88949aaecf53a6d23f56399c676">CONTEXT</a> *ctxt, <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;cmd, <span class="keywordtype">string</span> *result, VOID *)</div><div class="line">{</div><div class="line"> TINFO_MAP::iterator it = ThreadInfos.find(tid);</div><div class="line"> <span class="keywordflow">if</span> (it == ThreadInfos.end())</div><div class="line"> <span class="keywordflow">return</span> FALSE;</div><div class="line"> TINFO *tinfo = it-&gt;second;</div><div class="line"></div><div class="line"> std::string line = TrimWhitespace(cmd);</div><div class="line"> *result = <span class="stringliteral">&quot;&quot;</span>;</div><div class="line"></div><div class="line"> <span class="comment">// [...]</span></div><div class="line"></div><div class="line"> <span class="keywordflow">if</span> (line == <span class="stringliteral">&quot;stats&quot;</span>)</div><div class="line"> {</div><div class="line"> ADDRINT sp = <a class="code" href="group__CONTEXT__API.html#gac1358a6179f0a63300fdf34ecf8b741d">PIN_GetContextReg</a>(ctxt, <a class="code" href="group__REG__CPU__IA32.html#gga0f57fb50e80d686a588694f73046f2aaa2a6956c6a8b5a16cd95bf2f33586e10a">REG_STACK_PTR</a>);</div><div class="line"> tinfo-&gt;_os.str(<span class="stringliteral">&quot;&quot;</span>);</div><div class="line"> <span class="keywordflow">if</span> (sp &lt;= tinfo-&gt;_stackBase)</div><div class="line"> tinfo-&gt;_os &lt;&lt; <span class="stringliteral">&quot;Current stack usage: &quot;</span> &lt;&lt; std::dec &lt;&lt; (tinfo-&gt;_stackBase - sp) &lt;&lt; <span class="stringliteral">&quot; bytes.\n&quot;</span>;</div><div class="line"> <span class="keywordflow">else</span></div><div class="line"> tinfo-&gt;_os &lt;&lt; <span class="stringliteral">&quot;Current stack usage: -&quot;</span> &lt;&lt; std::dec &lt;&lt; (sp - tinfo-&gt;_stackBase) &lt;&lt; <span class="stringliteral">&quot; bytes.\n&quot;</span>;</div><div class="line"> tinfo-&gt;_os &lt;&lt; <span class="stringliteral">&quot;Maximum stack usage: &quot;</span> &lt;&lt; tinfo-&gt;_max &lt;&lt; <span class="stringliteral">&quot; bytes.\n&quot;</span>;</div><div class="line"> *result = tinfo-&gt;_os.str();</div><div class="line"> <span class="keywordflow">return</span> TRUE;</div><div class="line"> }</div><div class="line"> <span class="keywordflow">else</span> <span class="keywordflow">if</span> (line == <span class="stringliteral">&quot;stacktrace on&quot;</span>)</div><div class="line"> {</div><div class="line"> <span class="keywordflow">if</span> (!EnableInstrumentation)</div><div class="line"> {</div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#ga7f5784c3b9431086f3b5b750912ca0c2">PIN_RemoveInstrumentation</a>();</div><div class="line"> EnableInstrumentation = <span class="keyword">true</span>;</div><div class="line"> *result = <span class="stringliteral">&quot;Stack tracing enabled.\n&quot;</span>;</div><div class="line"> }</div><div class="line"> <span class="keywordflow">return</span> TRUE;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// [...]</span></div><div class="line"></div><div class="line"> <span class="keywordflow">return</span> FALSE; <span class="comment">// Unknown command</span></div><div class="line"></div><div class="line">}</div></div><!-- fragment --><p>The <a class="el" href="group__APPDEBUG__API.html#ga57d86fbcd855d998c28e27a8dfa56643">PIN_AddDebugInterpreter()</a> API allows a Pintool to establish a handler for extended debugger commands. For example, the code snippet above implements the new commands "stats" and "stacktrace on". You can execute these commands in the debugger by using the "monitor" command:</p>
<p><b>Linux:</b> </p><pre class="fragment">(gdb) monitor stats
Current stack usage: 688 bytes.
Maximum stack usage: 0 bytes.
</pre><p><b>macOS:</b> (note the 'command script import' command) </p><pre class="fragment">(lldb) command script import ../../../extras/lldb/monitor.py
The "monitor" command has been set.
(lldb) monitor stats
Current stack usage: 1040 bytes.
Maximum stack usage: 0 bytes.
</pre><dl class="section note"><dt>Note</dt><dd>In macOS, as mentioned above, in order to use a 'monitor' GDB alike command you need to execute 'command script import ../../../extras/lldb/monitor.py' from inside the LLDB console. <br />
LLDB already support this GDB remote protocol using 'process plugin packet monitor', however the responses from such commands are returned as bytes code (instead of textual). <br />
This monitor python module implements a user-defined 'monitor' lldb command that send the Pintool command to PinADX and print back the response in human readable output. <br />
monitor.py is delivered as part of the Pinkit in the specified path.</dd></dl>
<p>A Pintool can do various things when the user types an extended debugger command. For example, the "stats" command prints out some information that the tool has collected. Any text that the tool writes to the "result" parameter is printed to the debugger console. Note that the CONTEXT parameter has the register state for the debugger's "focus" thread, so the tool can easily display information about this focus thread.</p>
<p>You can also use an extended debugger command to interactively enable or disable instrumentation in your Pintool, as demonstrated by the "stacktrace on" command. For example, if you wanted to quickly run your Pintool over the application's initial start-up phase, you could run with your Pintool's instrumentation disabled until a breakpoint is triggered. Then, you could use an extended command to enable instrumentation only during the interesting part of the application. In the stack-debugger example above, the call to <a class="el" href="group__PIN__CONTROL.html#ga7f5784c3b9431086f3b5b750912ca0c2">PIN_RemoveInstrumentation()</a> causes Pin to discard any previous instrumentation, so the tool re-instruments the code when the debugger continues execution of the application. As we will see later, the tool's global variable "EnableInstrumentation" adjusts the instrumentation that it inserts.</p>
<h3><a class="anchor" id="APPDEBUG_UNIX_BREAK"></a>
Semantic Breakpoints</h3>
<p>The last major feature of the advanced debugging extensions is the ability to stop execution at a breakpoint by calling an API from your tool's analysis code. This may sound simple, but it is very powerful. Your Pintool can use instrumentation to look for a complex condition and then stop at a breakpoint when that condition occurs.</p>
<p>The "stack-debugger" tool illustrates this by using instrumentation to observe all the instructions that allocate stack space, and then it stops at a breakpoint whenever the application's stack usage reaches some threshold. In effect, this adds a new feature to the debugger that could not be practically implemented using traditional debugger technology because a traditional debugger can not reasonably find all the instructions that allocate stack space. A Pintool, however, can do this quite easily via instrumentation.</p>
<p>The example code below from the "stack-debugger" tool uses Pin instrumentation to identify all the instructions that allocate stack space.</p>
<div class="fragment"><div class="line"><span class="keyword">static</span> VOID Instruction(INS ins, VOID *)</div><div class="line">{</div><div class="line"> <span class="keywordflow">if</span> (!EnableInstrumentation)</div><div class="line"> <span class="keywordflow">return</span>;</div><div class="line"></div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__INS__BASIC__API__GEN__IA32.html#gace8d6ad76944f2916071fc1519be39a2">INS_RegWContain</a>(ins, <a class="code" href="group__REG__CPU__IA32.html#gga0f57fb50e80d686a588694f73046f2aaa2a6956c6a8b5a16cd95bf2f33586e10a">REG_STACK_PTR</a>))</div><div class="line"> {</div><div class="line"> <a class="code" href="group__INST__ARGS.html#ga707ea08e31f44f4a81e2a7766123bad7">IPOINT</a> where = <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a42eff26179c6d87348abe492301c12ec">IPOINT_AFTER</a>;</div><div class="line"> <span class="keywordflow">if</span> (!<a class="code" href="group__INS__BASIC__API__GEN__IA32.html#gaabdbfe129a59dca362c8cb2e22ade56b">INS_IsValidForIpointAfter</a>(ins))</div><div class="line"> where = <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a5ef5b45901a8447e5173f50746ab029d">IPOINT_TAKEN_BRANCH</a>;</div><div class="line"></div><div class="line"> <a class="code" href="group__INS__INST__API.html#ga7907ad8ebd991b9e24df3b3b9cec4cac">INS_InsertIfCall</a>(ins, where, (AFUNPTR)OnStackChangeIf, <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dabe70796bf61230dac3ea1deaf4983c46">IARG_REG_VALUE</a>, <a class="code" href="group__REG__CPU__IA32.html#gga0f57fb50e80d686a588694f73046f2aaa2a6956c6a8b5a16cd95bf2f33586e10a">REG_STACK_PTR</a>,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dabe70796bf61230dac3ea1deaf4983c46">IARG_REG_VALUE</a>, RegTinfo, IARG_END);</div><div class="line"> <a class="code" href="group__INS__INST__API.html#ga952b2b061d3fa8f1cc4d5d59fef53a69">INS_InsertThenCall</a>(ins, where, (AFUNPTR)DoBreakpoint, <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dad3e65d643a63acb09d12b8538434ca45">IARG_CONST_CONTEXT</a>, <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451daadb6e5681193cc8435b9e57d13acf5d4">IARG_THREAD_ID</a>, IARG_END);</div><div class="line"> }</div><div class="line">}</div></div><!-- fragment --><p>The call to <a class="el" href="group__INS__BASIC__API__GEN__IA32.html#gace8d6ad76944f2916071fc1519be39a2">INS_RegWContain()</a> tests whether an instruction modifies the stack pointer. If it does, we insert an analysis call immediately after the instruction, which checks to see if the application's stack usage exceeds a threshold.</p>
<p>Also notice that all the instrumentation is gated by the global flag "EnableInstrumentation", which we saw earlier in the "stacktrace on" command. Thus, the user can disable instrumentation (with "stacktrace off") in order to execute quickly through uninteresting parts of the application, and then re-enable it (with "stacktrace on") for the interesting parts.</p>
<p>The analysis routine OnStackChangeIf() returns TRUE if the application's stack usage has exceeded the threshold. When this happens, the tool calls the DoBreakpoint() analysis routine, which will stop at the debugger breakpoint. Notice that we use if / then instrumentation here because the call to DoBreakpoint() requires a "CONTEXT *" parameter, which can be slow.</p>
<div class="fragment"><div class="line"><span class="keyword">static</span> ADDRINT OnStackChangeIf(ADDRINT sp, ADDRINT addrInfo)</div><div class="line">{</div><div class="line"> TINFO *tinfo = <span class="keyword">reinterpret_cast&lt;</span>TINFO *<span class="keyword">&gt;</span>(addrInfo);</div><div class="line"></div><div class="line"> <span class="comment">// The stack pointer may go above the base slightly. (For example, the application&#39;s dynamic</span></div><div class="line"> <span class="comment">// loader does this briefly during start-up.)</span></div><div class="line"> <span class="comment">//</span></div><div class="line"> <span class="keywordflow">if</span> (sp &gt; tinfo-&gt;_stackBase)</div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line"></div><div class="line"> <span class="comment">// Keep track of the maximum stack usage.</span></div><div class="line"> <span class="comment">//</span></div><div class="line"> <span class="keywordtype">size_t</span> size = tinfo-&gt;_stackBase - sp;</div><div class="line"> <span class="keywordflow">if</span> (size &gt; tinfo-&gt;_max)</div><div class="line"> tinfo-&gt;_max = size;</div><div class="line"></div><div class="line"> <span class="comment">// See if we need to trigger a breakpoint.</span></div><div class="line"> <span class="comment">//</span></div><div class="line"> <span class="keywordflow">if</span> (BreakOnNewMax &amp;&amp; size &gt; tinfo-&gt;_maxReported)</div><div class="line"> <span class="keywordflow">return</span> 1;</div><div class="line"> <span class="keywordflow">if</span> (BreakOnSize &amp;&amp; size &gt;= BreakOnSize)</div><div class="line"> <span class="keywordflow">return</span> 1;</div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keyword">static</span> VOID DoBreakpoint(<span class="keyword">const</span> <a class="code" href="group__CONTEXT__API.html#ga73f8f88949aaecf53a6d23f56399c676">CONTEXT</a> *ctxt, <a class="code" href="group__PIN__THREAD__API.html#ga645289be59039349ad77ad2fa7b0e2f3">THREADID</a> tid)</div><div class="line">{</div><div class="line"> TINFO *tinfo = <span class="keyword">reinterpret_cast&lt;</span>TINFO *<span class="keyword">&gt;</span>(<a class="code" href="group__CONTEXT__API.html#gac1358a6179f0a63300fdf34ecf8b741d">PIN_GetContextReg</a>(ctxt, RegTinfo));</div><div class="line"></div><div class="line"> <span class="comment">// Keep track of the maximum reported stack usage for &quot;stackbreak newmax&quot;.</span></div><div class="line"> <span class="comment">//</span></div><div class="line"> <span class="keywordtype">size_t</span> size = tinfo-&gt;_stackBase - <a class="code" href="group__CONTEXT__API.html#gac1358a6179f0a63300fdf34ecf8b741d">PIN_GetContextReg</a>(ctxt, <a class="code" href="group__REG__CPU__IA32.html#gga0f57fb50e80d686a588694f73046f2aaa2a6956c6a8b5a16cd95bf2f33586e10a">REG_STACK_PTR</a>);</div><div class="line"> <span class="keywordflow">if</span> (size &gt; tinfo-&gt;_maxReported)</div><div class="line"> tinfo-&gt;_maxReported = size;</div><div class="line"></div><div class="line"> ConnectDebugger(); <span class="comment">// Ask the user to connect a debugger, if it is not already connected.</span></div><div class="line"></div><div class="line"> <span class="comment">// Construct a string that the debugger will print when it stops. If a debugger is</span></div><div class="line"> <span class="comment">// not connected, no breakpoint is triggered and execution resumes immediately.</span></div><div class="line"> <span class="comment">//</span></div><div class="line"> tinfo-&gt;_os.str(<span class="stringliteral">&quot;&quot;</span>);</div><div class="line"> tinfo-&gt;_os &lt;&lt; <span class="stringliteral">&quot;Thread &quot;</span> &lt;&lt; std::dec &lt;&lt; tid &lt;&lt; <span class="stringliteral">&quot; uses &quot;</span> &lt;&lt; size &lt;&lt; <span class="stringliteral">&quot; bytes of stack.&quot;</span>;</div><div class="line"> <a class="code" href="group__APPDEBUG__API.html#gad46f50d48ebcf2414e766c2978111c4b">PIN_ApplicationBreakpoint</a>(ctxt, tid, FALSE, tinfo-&gt;_os.str());</div><div class="line">}</div></div><!-- fragment --><p>The analysis routine OnStackChangeIf() keeps track of some metrics on stack usage and tests whether the threshold has been reached. If the threshold is crossed, it returns non-zero, and Pin executes the DoBreakpoint() analysis routine.</p>
<p>The interesting part of DoBreakpoint() is at the very end, where it calls <a class="el" href="group__APPDEBUG__API.html#gad46f50d48ebcf2414e766c2978111c4b">PIN_ApplicationBreakpoint()</a>. This API causes Pin to stop the execution of all threads and triggers a breakpoint in the debugger. There is also a string parameter to <a class="el" href="group__APPDEBUG__API.html#gad46f50d48ebcf2414e766c2978111c4b">PIN_ApplicationBreakpoint()</a>, which the debugger prints at the console when the breakpoint triggers. A Pintool can use this string to tell the user why a breakpoint triggered. In our example tool, this string says something like "Thread 10 uses 4000 bytes of stack".</p>
<p>Please refer to the documentation of <a class="el" href="group__APPDEBUG__API.html#gad46f50d48ebcf2414e766c2978111c4b">PIN_ApplicationBreakpoint()</a> and read the note about avoiding an infinite loop of calls to the analysis function.</p>
<p>We can see the breakpoint feature in action in our example tool by using the "stackbreak 4000" command like this:</p>
<p><b>Linux:</b> </p><pre class="fragment">(gdb) monitor stackbreak 4000
Will break when thread uses more than 4000 bytes of stack.
(gdb) c
Continuing.
Thread 0 uses 4000 bytes of stack.
Program received signal SIGTRAP, Trace/breakpoint trap.
0x0000000000400e27 in Fibonacci (num=0) at fibonacci.cpp:34
(gdb)
</pre><p><b>macOS:</b> </p><pre class="fragment">(lldb) monitor stackbreak 4000
Will break when thread uses more than 4000 bytes of stack.
(lldb) c
Process 267 resuming
Process 267 stopped
* thread #1: tid = 0x010b, 0x00007fff6551d6b4 dyld`ImageLoaderMachOCompressed::resolveTwolevel(ImageLoader::LinkContext const&amp;,
ImageLoader const*, bool, char const*, bool, ImageLoader const**) + 20, stop reason = signal SIGTRAP
frame #0: 0x00007fff6551d6b4 dyld`ImageLoaderMachOCompressed::resolveTwolevel(ImageLoader::LinkContext const&amp;,
ImageLoader const*, bool, char const*, bool, ImageLoader const**) + 20
dyld`ImageLoaderMachOCompressed::resolveTwolevel:
-&gt; 0x7fff6551d6b4 &lt;+20&gt;: movl %r9d, -0x140(%rbp)
0x7fff6551d6bb &lt;+27&gt;: movq %r8, %r13
0x7fff6551d6be &lt;+30&gt;: movl %ecx, -0x144(%rbp)
0x7fff6551d6c4 &lt;+36&gt;: movq %rdx, %r15
</pre><p>When you are done, you can either continue the application and let it terminate, or you can quit from the debugger:</p>
<p><b>Linux:</b> </p><pre class="fragment">(gdb) quit
The program is running. Exit anyway? (y or n) y
</pre><p><b>macOS:</b> </p><pre class="fragment">(lldb) q
Quitting LLDB will kill one or more processes. Do you really want to proceed: [Y/n] y
</pre><h3><a class="anchor" id="APPDEBUG_UNIX_LATER"></a>
Connecting the Debugger Later</h3>
<p>In the previous example, we used the Pin switch <a class="el" href="group__KNOBS.html#SWITCH_APPDEBUG">-appdebug</a> to stop the application and debug it from the first instruction. You can also enable Pin's debugging extensions without stopping at the first instruction. The following example shows how you can use the stack-debugger tool to start the application and attach with the debugger only after it triggers a stack limit breakpoint.</p>
<p><b>Linux:</b> </p><pre class="fragment">$ ../../../pin -appdebug_enable -appdebug_silent -t obj-intel64/stack-debugger.so -stackbreak 4000 -- obj-intel64/fibonacci 1000
</pre><p><b>macOS:</b> </p><pre class="fragment">$ ../../../pin -appdebug_enable -appdebug_silent -t obj-intel64/stack-debugger.dylib -stackbreak 4000 -- obj-intel64/fibonacci.exe 1000
</pre><p>The <a class="el" href="group__KNOBS.html#SWITCH_APPDEBUG_ENABLE">-appdebug_enable</a> switch tells Pin to enable application debugging without stopping at the first instruction. The <a class="el" href="group__KNOBS.html#SWITCH_APPDEBUG_SILENT">-appdebug_silent</a> switch disables the message that tells how to connect with the debugger. As we will see later, the Pintool can print a custom message instead. Finally, the "-stackbreak 4000" switch tells the stack-debugger tool to trigger a breakpoint when the stack grows to 4000 bytes. When the tool does trigger a breakpoint, it prints a message like this:</p>
<p><b>Linux:</b> </p><pre class="fragment">Triggered stack-limit breakpoint.
Start GDB and enter this command:
target remote :45462
</pre><p><b>macOS:</b> </p><pre class="fragment">Triggered stack-limit breakpoint.
Start LLDB and enter this command:
gdb-remote 45462
</pre><p>You can now connect with the debugger as you did before, except now the debugger stops the application at the point where the stack-debugger tool triggered the stack-limit breakpoint.</p>
<p><b>Linux:</b> </p><pre class="fragment">gdb fibonacci
(gdb) target remote :45462
0x0000000000400e27 in Fibonacci (num=0) at fibonacci.cpp:37
(gdb)
</pre><p><b>macOS:</b> </p><pre class="fragment">(lldb) gdb-remote 45462
Process 267 stopped
* thread #1: tid = 0x010b, 0x00007fff635ebfa0 dyld`dyld::_main(macho_header const*, unsigned long, int, char const**,
char const**, char const**, unsigned long*) + 20, stop reason = signal SIGTRAP
frame #0: 0x00007fff635ebfa0 dyld`dyld::_main(macho_header const*, unsigned long, int, char const**, char const**,
char const**, unsigned long*) + 20
dyld`dyld::_main:
-&gt; 0x7fff635ebfa0 &lt;+20&gt;: movq %r9, %r14
0x7fff635ebfa3 &lt;+23&gt;: movq %r8, %r15
0x7fff635ebfa6 &lt;+26&gt;: movq %rcx, %r13
0x7fff635ebfa9 &lt;+29&gt;: movl %edx, %ebx
(lldb)
</pre><p>Let's look at the code in the tool that connects to the debugger now.</p>
<div class="fragment"><div class="line"><span class="keyword">static</span> <span class="keywordtype">void</span> ConnectDebugger()</div><div class="line">{</div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__APPDEBUG__API.html#gab15de5ddf44f7deef79a42e7b041ac12">PIN_GetDebugStatus</a>() != <a class="code" href="group__APPDEBUG__API.html#gga41e814fff526e0232f2f8c3055d6e88ba994b4c3ad3ae17936ecf71deaadf1f80">DEBUG_STATUS_UNCONNECTED</a>)</div><div class="line"> <span class="keywordflow">return</span>;</div><div class="line"></div><div class="line"> <a class="code" href="structDEBUG__CONNECTION__INFO.html">DEBUG_CONNECTION_INFO</a> info;</div><div class="line"> <span class="keywordflow">if</span> (!<a class="code" href="group__APPDEBUG__API.html#gadf62887d32f6c37118fe5503d008a976">PIN_GetDebugConnectionInfo</a>(&amp;info) || info.<a class="code" href="structDEBUG__CONNECTION__INFO.html#aad048415716dec2a5858fb0b82783bf1">_type</a> != <a class="code" href="group__APPDEBUG__API.html#gga25f41d731fbc522fea67abd02f9c04c6abc9902ef5ebfac00333f6ce7bd00cd57">DEBUG_CONNECTION_TYPE_TCP_SERVER</a>)</div><div class="line"> <span class="keywordflow">return</span>;</div><div class="line"></div><div class="line"> *Output &lt;&lt; <span class="stringliteral">&quot;Triggered stack-limit breakpoint.\n&quot;</span>;</div><div class="line"> *Output &lt;&lt; <span class="stringliteral">&quot;Start GDB and enter this command:\n&quot;</span>;</div><div class="line"> *Output &lt;&lt; <span class="stringliteral">&quot; target remote :&quot;</span> &lt;&lt; std::dec &lt;&lt; info._tcpServer.<a class="code" href="struct__tcpServerStruct.html#a263a119b2bc391cf181fb4718dc2968c">_tcpPort</a> &lt;&lt; <span class="stringliteral">&quot;\n&quot;</span>;</div><div class="line"> *Output &lt;&lt; std::flush;</div><div class="line"></div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__APPDEBUG__API.html#gab76db0d06ebabd4a42540a92016b9d13">PIN_WaitForDebuggerToConnect</a>(1000*KnobTimeout.Value()))</div><div class="line"> <span class="keywordflow">return</span>;</div><div class="line"></div><div class="line"> *Output &lt;&lt; <span class="stringliteral">&quot;No debugger attached after &quot;</span> &lt;&lt; KnobTimeout.Value() &lt;&lt; <span class="stringliteral">&quot; seconds.\n&quot;</span>;</div><div class="line"> *Output &lt;&lt; <span class="stringliteral">&quot;Resuming application without stopping.\n&quot;</span>;</div><div class="line"> *Output &lt;&lt; std::flush;</div><div class="line">}</div></div><!-- fragment --><p>The ConnectDebugger() function is called each time the tool wants to stop at a breakpoint. It first calls <a class="el" href="group__APPDEBUG__API.html#gab15de5ddf44f7deef79a42e7b041ac12">PIN_GetDebugStatus()</a> to see if Pin is already connected to a debugger. If not, it uses <a class="el" href="group__APPDEBUG__API.html#gadf62887d32f6c37118fe5503d008a976">PIN_GetDebugConnectionInfo()</a> to get the TCP port number that is needed to connect the debugger to Pin. This is, for example, the "45462" number that the user types in the "target remote" command. After asking the user to start the debugger, the tool then calls <a class="el" href="group__APPDEBUG__API.html#gab76db0d06ebabd4a42540a92016b9d13">PIN_WaitForDebuggerToConnect()</a> to wait for the debugger to connect. If the user doesn't start the debugger after a timeout period, the tool prints a message and then continues executing the application.</p>
<p>As before, you can either continue the application and let it terminate, or you can quit from the debugger:</p>
<p><b>Linux:</b> </p><pre class="fragment">(gdb) quit
The program is running. Exit anyway? (y or n) y
</pre><p><b>macOS:</b> </p><pre class="fragment">(lldb) q
Quitting LLDB will kill one or more processes. Do you really want to proceed: [Y/n] y
</pre><dl class="section warning"><dt>Warning</dt><dd>In macOS, for the debugger extensions to work properly, they currently require the target application symbols. Make sure to call PIN_InitSymbols in your Pintool.<br />
This also means that you need some Pintool in order to use PinADX even if the tool does nothing beside calling PIN_InitSymbols.</dd></dl>
<h2><a class="anchor" id="APPDEBUG_WINDOWS"></a>
Advanced Debugging Extensions on Windows</h2>
<p>On Windows, the advanced debugging extensions work with Microsoft Visual Studio 2012 or greater. There is no support for earlier versions of Visual Studio, so make sure you have that version installed. Also, the Express edition of Visual Studio doesn't support IDE extensions, so it will not work with the Pin debugger extensions. Therefore, you must install the Professional edition (or greater). If you are a student, you may be able to get the Professional edition for free. Check the Microsoft web site or with your school's IT department for details.</p>
<p>After you have installed Visual Studio, you must also install the Pin extension for Visual Studio. Look for an installer named "pinadx-vsextension-X.Y.bat" in the root of the Pin kit. Run it as administrator.</p>
<p>The remainder of this section assumes that you are able to build the "stack-debugger" tool, so if you want to follow along, you must have the following software installed:</p>
<ul>
<li>Visual Studio 2012, Professional edition (or greater).</li>
<li>The Pin debugger extension for Visual Studio 2012 or greater (pinadx-vsextension-X.Y.bat).</li>
</ul>
<p>In order to start this tutorial, you will probably want to build the example tool "stack-debugger.cpp", which is available in the directory "source\tools\ManualExamples". To do this, open a Visual Studio command shell and type the following commands. (Use "TARGET=intel64" instead, if you want to build a 64-bit version of the tool.)</p>
<pre class="fragment">C:\&gt; cd source\tools\ManualExamples
C:\&gt; make TARGET=ia32 obj-ia32/stack-debugger.dll
</pre><p>After you have done this, start Visual Studio and open the sample solution file at "source\tools\ManualExamples\stack-debugger-tutorial.sln". Then build the sample application "fibonacci" by pressing F7. Make sure you can run the application natively by pressing CTRL-F5.</p>
<p>Now let's try running the "fibonacci" application under Pin with the "stack-debugger" tool. To do this, you must first set the "Pin Kit Directory" from TOOLS-&gt;Options-&gt;Pin Debugger.</p>
<div class="image">
<img src="pin-debugger-option-pages-properties.png" alt="pin-debugger-option-pages-properties.png"/>
</div>
<p>Then you have to adjust the "fibonacci" project properties in Visual Studio: right-click on the "fibonacci" project in the Solution Explorer, choose Properties, and then click on Debugging. Change the drop-down titled "Debugger to launch" to "Pin Debugger" as shown in the figure below.</p>
<div class="image">
<img src="pin-debugger-project-properties1.png" alt="pin-debugger-project-properties1.png"/>
</div>
<p>Then, set the "Pin Tool Path" property by browsing to the "stack-debugger.dll". Press OK when you are done.</p>
<div class="image">
<img src="pin-debugger-project-properties2.png" alt="pin-debugger-project-properties2.png"/>
</div>
<p>Visual Studio is now configured to run the "fibonacci" application under your Pintool. However, before you continue, set a breakpoint in "main()" so that execution stops in the debugger. Then press F5 to start debugging.</p>
<p>You should now see a normal-looking debugger session, although your application is really running under control of Pin. All of the debugger features still work as you would expect. You can set breakpoints, continue execution, display the values of variables, and even view the disassembled code. All of the information that you observe in the debugger shows the application's "pure" state. The details of Pin and the tool's instrumentation are hidden. For example, the disassembly view shows only the application's instructions, not any of the instructions inserted by the tool. However, when you continue execution (e.g. with F5 or F10), the application executes along with your tool's instrumentation code.</p>
<p>Now, let's see an alternative way to debug the "fibonacci" application under Pin with the "stack-debugger" tool in Visual Studio. After you have built the "stack-debugger" tool, open a command shell and start the application with the debugging extensions enabled. This will cause Pin to stop immediately before the first instruction.</p>
<pre class="fragment">C:\&gt; cd source\tools\ManualExamples
C:\&gt; ..\..\..\pin -appdebug -t obj-ia32\stack-debugger.dll -- debug\fibonacci.exe 1000
Application stopped until continued from debugger.
Pin ready to accept debugger connection on port 30840
</pre><p>Open the source\tools\ManualExamples\fibonacci.cpp in Visual Studio and set a breakpoint to stop the execution in the debugger. To attach with Visual Studio to the process that is running under Pin, select "Attach to Pin Process" on the DEBUG menu. Select from the Available Processes table the "fibonacci" process, enter the port number that Pin printed and click Attach.</p>
<div class="image">
<img src="pin-debugger-attach.png" alt="pin-debugger-attach.png"/>
</div>
<h3><a class="anchor" id="APPDEBUG_WINDOWS_COMMANDS"></a>
Adding New Debugger Commands</h3>
<p>The previous section illustrated how you can enable the normal debugger features while running an application under Pin. Now, let's see how your Pintool can add new custom debugger commands, even without changing Visual Studio. Custom debugger commands are useful because they allow you to control your Pintool interactively from within a live debugger session. For example, you can ask your Pintool to print out information that it has collected, or you can interactively enable instrumentation only for certain phases of the application.</p>
<p>To illustrate, see the call to <a class="el" href="group__APPDEBUG__API.html#ga57d86fbcd855d998c28e27a8dfa56643">PIN_AddDebugInterpreter()</a> in the stack-debugger tool. That API sets up the following call-back function:</p>
<div class="fragment"><div class="line"><span class="keyword">static</span> BOOL DebugInterpreter(<a class="code" href="group__PIN__THREAD__API.html#ga645289be59039349ad77ad2fa7b0e2f3">THREADID</a> tid, <a class="code" href="group__CONTEXT__API.html#ga73f8f88949aaecf53a6d23f56399c676">CONTEXT</a> *ctxt, <span class="keyword">const</span> <span class="keywordtype">string</span> &amp;cmd, <span class="keywordtype">string</span> *result, VOID *)</div><div class="line">{</div><div class="line"> TINFO_MAP::iterator it = ThreadInfos.find(tid);</div><div class="line"> <span class="keywordflow">if</span> (it == ThreadInfos.end())</div><div class="line"> <span class="keywordflow">return</span> FALSE;</div><div class="line"> TINFO *tinfo = it-&gt;second;</div><div class="line"></div><div class="line"> std::string line = TrimWhitespace(cmd);</div><div class="line"> *result = <span class="stringliteral">&quot;&quot;</span>;</div><div class="line"></div><div class="line"> <span class="comment">// [...]</span></div><div class="line"></div><div class="line"> <span class="keywordflow">if</span> (line == <span class="stringliteral">&quot;stats&quot;</span>)</div><div class="line"> {</div><div class="line"> ADDRINT sp = <a class="code" href="group__CONTEXT__API.html#gac1358a6179f0a63300fdf34ecf8b741d">PIN_GetContextReg</a>(ctxt, <a class="code" href="group__REG__CPU__IA32.html#gga0f57fb50e80d686a588694f73046f2aaa2a6956c6a8b5a16cd95bf2f33586e10a">REG_STACK_PTR</a>);</div><div class="line"> tinfo-&gt;_os.str(<span class="stringliteral">&quot;&quot;</span>);</div><div class="line"> <span class="keywordflow">if</span> (sp &lt;= tinfo-&gt;_stackBase)</div><div class="line"> tinfo-&gt;_os &lt;&lt; <span class="stringliteral">&quot;Current stack usage: &quot;</span> &lt;&lt; std::dec &lt;&lt; (tinfo-&gt;_stackBase - sp) &lt;&lt; <span class="stringliteral">&quot; bytes.\n&quot;</span>;</div><div class="line"> <span class="keywordflow">else</span></div><div class="line"> tinfo-&gt;_os &lt;&lt; <span class="stringliteral">&quot;Current stack usage: -&quot;</span> &lt;&lt; std::dec &lt;&lt; (sp - tinfo-&gt;_stackBase) &lt;&lt; <span class="stringliteral">&quot; bytes.\n&quot;</span>;</div><div class="line"> tinfo-&gt;_os &lt;&lt; <span class="stringliteral">&quot;Maximum stack usage: &quot;</span> &lt;&lt; tinfo-&gt;_max &lt;&lt; <span class="stringliteral">&quot; bytes.\n&quot;</span>;</div><div class="line"> *result = tinfo-&gt;_os.str();</div><div class="line"> <span class="keywordflow">return</span> TRUE;</div><div class="line"> }</div><div class="line"> <span class="keywordflow">else</span> <span class="keywordflow">if</span> (line == <span class="stringliteral">&quot;stacktrace on&quot;</span>)</div><div class="line"> {</div><div class="line"> <span class="keywordflow">if</span> (!EnableInstrumentation)</div><div class="line"> {</div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#ga7f5784c3b9431086f3b5b750912ca0c2">PIN_RemoveInstrumentation</a>();</div><div class="line"> EnableInstrumentation = <span class="keyword">true</span>;</div><div class="line"> *result = <span class="stringliteral">&quot;Stack tracing enabled.\n&quot;</span>;</div><div class="line"> }</div><div class="line"> <span class="keywordflow">return</span> TRUE;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// [...]</span></div><div class="line"></div><div class="line"> <span class="keywordflow">return</span> FALSE; <span class="comment">// Unknown command</span></div><div class="line"></div><div class="line">}</div></div><!-- fragment --><p>The <a class="el" href="group__APPDEBUG__API.html#ga57d86fbcd855d998c28e27a8dfa56643">PIN_AddDebugInterpreter()</a> API allows a Pintool to establish a handler for extended debugger commands. For example, the code snippet above implements the new commands "stats" and "stacktrace on". You can execute these commands in Visual Studio by opening "DEBUG-&gt;Windows-&gt;Pin Console" in the IDE.</p>
<div class="image">
<img src="stack-debugger-commands.png" alt="stack-debugger-commands.png"/>
</div>
<p>A Pintool can do various things when the user types an extended debugger command. For example, the "stats" command prints out some information that the tool has collected. Any text that the tool writes to the "result" parameter is printed to the Visual Studio Pin Console window. Note that the CONTEXT parameter has the register state for the debugger's "focus" thread, so the tool can easily display information about this focus thread.</p>
<p>You can also use an extended debugger command to interactively enable or disable instrumentation in your Pintool, as demonstrated by the "stacktrace on" command. For example, if you wanted to quickly run your Pintool over the application's initial start-up phase, you could run with your Pintool's instrumentation disabled until a breakpoint is triggered. Then, you could use an extended command to enable instrumentation only during the interesting part of the application. In the stack-debugger example above, the call to <a class="el" href="group__PIN__CONTROL.html#ga7f5784c3b9431086f3b5b750912ca0c2">PIN_RemoveInstrumentation()</a> causes Pin to discard any previous instrumentation, so the tool re-instruments the code when the debugger continues execution of the application. As we will see later, the tool's global variable "EnableInstrumentation" adjusts the instrumentation that it inserts.</p>
<h3><a class="anchor" id="APPDEBUG_WINDOWS_BREAK"></a>
Semantic Breakpoints</h3>
<p>The last major feature of the advanced debugging extensions is the ability to stop execution at a breakpoint by calling an API from your tool's analysis code. This may sound simple, but it is very powerful. Your Pintool can use instrumentation to look for a complex condition and then stop at a breakpoint when that condition occurs.</p>
<p>The "stack-debugger" tool illustrates this by using instrumentation to observe all the instructions that allocate stack space, and then it stops at a breakpoint whenever the application's stack usage reaches some threshold. In effect, this adds a new feature to the debugger that could not be practically implemented using traditional debugger technology because a traditional debugger can not reasonably find all the instructions that allocate stack space. A Pintool, however, can do this quite easily via instrumentation.</p>
<p>The example code below from the "stack-debugger" tool uses Pin instrumentation to identify all the instructions that allocate stack space.</p>
<div class="fragment"><div class="line"><span class="keyword">static</span> VOID Instruction(INS ins, VOID *)</div><div class="line">{</div><div class="line"> <span class="keywordflow">if</span> (!EnableInstrumentation)</div><div class="line"> <span class="keywordflow">return</span>;</div><div class="line"></div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__INS__BASIC__API__GEN__IA32.html#gace8d6ad76944f2916071fc1519be39a2">INS_RegWContain</a>(ins, <a class="code" href="group__REG__CPU__IA32.html#gga0f57fb50e80d686a588694f73046f2aaa2a6956c6a8b5a16cd95bf2f33586e10a">REG_STACK_PTR</a>))</div><div class="line"> {</div><div class="line"> <a class="code" href="group__INST__ARGS.html#ga707ea08e31f44f4a81e2a7766123bad7">IPOINT</a> where = <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a42eff26179c6d87348abe492301c12ec">IPOINT_AFTER</a>;</div><div class="line"> <span class="keywordflow">if</span> (!<a class="code" href="group__INS__BASIC__API__GEN__IA32.html#gaabdbfe129a59dca362c8cb2e22ade56b">INS_IsValidForIpointAfter</a>(ins))</div><div class="line"> where = <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a5ef5b45901a8447e5173f50746ab029d">IPOINT_TAKEN_BRANCH</a>;</div><div class="line"></div><div class="line"> <a class="code" href="group__INS__INST__API.html#ga7907ad8ebd991b9e24df3b3b9cec4cac">INS_InsertIfCall</a>(ins, where, (AFUNPTR)OnStackChangeIf, <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dabe70796bf61230dac3ea1deaf4983c46">IARG_REG_VALUE</a>, <a class="code" href="group__REG__CPU__IA32.html#gga0f57fb50e80d686a588694f73046f2aaa2a6956c6a8b5a16cd95bf2f33586e10a">REG_STACK_PTR</a>,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dabe70796bf61230dac3ea1deaf4983c46">IARG_REG_VALUE</a>, RegTinfo, IARG_END);</div><div class="line"> <a class="code" href="group__INS__INST__API.html#ga952b2b061d3fa8f1cc4d5d59fef53a69">INS_InsertThenCall</a>(ins, where, (AFUNPTR)DoBreakpoint, <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dad3e65d643a63acb09d12b8538434ca45">IARG_CONST_CONTEXT</a>, <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451daadb6e5681193cc8435b9e57d13acf5d4">IARG_THREAD_ID</a>, IARG_END);</div><div class="line"> }</div><div class="line">}</div></div><!-- fragment --><p>The call to <a class="el" href="group__INS__BASIC__API__GEN__IA32.html#gace8d6ad76944f2916071fc1519be39a2">INS_RegWContain()</a> tests whether an instruction modifies the stack pointer. If it does, we insert an analysis call immediately after the instruction, which checks to see if the application's stack usage exceeds a threshold.</p>
<p>Also notice that all the instrumentation is gated by the global flag "EnableInstrumentation", which we saw earlier in the "stacktrace on" command. Thus, the user can disable instrumentation (with "stacktrace off") in order to execute quickly through uninteresting parts of the application, and then re-enable it (with "stacktrace on") for the interesting parts.</p>
<p>The analysis routine OnStackChangeIf() returns TRUE if the application's stack usage has exceeded the threshold. When this happens, the tool calls the DoBreakpoint() analysis routine, which will stop at the debugger breakpoint. Notice that we use if / then instrumentation here because the call to DoBreakpoint() requires a "CONTEXT *" parameter, which can be slow.</p>
<div class="fragment"><div class="line"><span class="keyword">static</span> ADDRINT OnStackChangeIf(ADDRINT sp, ADDRINT addrInfo)</div><div class="line">{</div><div class="line"> TINFO *tinfo = <span class="keyword">reinterpret_cast&lt;</span>TINFO *<span class="keyword">&gt;</span>(addrInfo);</div><div class="line"></div><div class="line"> <span class="comment">// The stack pointer may go above the base slightly. (For example, the application&#39;s dynamic</span></div><div class="line"> <span class="comment">// loader does this briefly during start-up.)</span></div><div class="line"> <span class="comment">//</span></div><div class="line"> <span class="keywordflow">if</span> (sp &gt; tinfo-&gt;_stackBase)</div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line"></div><div class="line"> <span class="comment">// Keep track of the maximum stack usage.</span></div><div class="line"> <span class="comment">//</span></div><div class="line"> <span class="keywordtype">size_t</span> size = tinfo-&gt;_stackBase - sp;</div><div class="line"> <span class="keywordflow">if</span> (size &gt; tinfo-&gt;_max)</div><div class="line"> tinfo-&gt;_max = size;</div><div class="line"></div><div class="line"> <span class="comment">// See if we need to trigger a breakpoint.</span></div><div class="line"> <span class="comment">//</span></div><div class="line"> <span class="keywordflow">if</span> (BreakOnNewMax &amp;&amp; size &gt; tinfo-&gt;_maxReported)</div><div class="line"> <span class="keywordflow">return</span> 1;</div><div class="line"> <span class="keywordflow">if</span> (BreakOnSize &amp;&amp; size &gt;= BreakOnSize)</div><div class="line"> <span class="keywordflow">return</span> 1;</div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keyword">static</span> VOID DoBreakpoint(<span class="keyword">const</span> <a class="code" href="group__CONTEXT__API.html#ga73f8f88949aaecf53a6d23f56399c676">CONTEXT</a> *ctxt, <a class="code" href="group__PIN__THREAD__API.html#ga645289be59039349ad77ad2fa7b0e2f3">THREADID</a> tid)</div><div class="line">{</div><div class="line"> TINFO *tinfo = <span class="keyword">reinterpret_cast&lt;</span>TINFO *<span class="keyword">&gt;</span>(<a class="code" href="group__CONTEXT__API.html#gac1358a6179f0a63300fdf34ecf8b741d">PIN_GetContextReg</a>(ctxt, RegTinfo));</div><div class="line"></div><div class="line"> <span class="comment">// Keep track of the maximum reported stack usage for &quot;stackbreak newmax&quot;.</span></div><div class="line"> <span class="comment">//</span></div><div class="line"> <span class="keywordtype">size_t</span> size = tinfo-&gt;_stackBase - <a class="code" href="group__CONTEXT__API.html#gac1358a6179f0a63300fdf34ecf8b741d">PIN_GetContextReg</a>(ctxt, <a class="code" href="group__REG__CPU__IA32.html#gga0f57fb50e80d686a588694f73046f2aaa2a6956c6a8b5a16cd95bf2f33586e10a">REG_STACK_PTR</a>);</div><div class="line"> <span class="keywordflow">if</span> (size &gt; tinfo-&gt;_maxReported)</div><div class="line"> tinfo-&gt;_maxReported = size;</div><div class="line"></div><div class="line"> ConnectDebugger(); <span class="comment">// Ask the user to connect a debugger, if it is not already connected.</span></div><div class="line"></div><div class="line"> <span class="comment">// Construct a string that the debugger will print when it stops. If a debugger is</span></div><div class="line"> <span class="comment">// not connected, no breakpoint is triggered and execution resumes immediately.</span></div><div class="line"> <span class="comment">//</span></div><div class="line"> tinfo-&gt;_os.str(<span class="stringliteral">&quot;&quot;</span>);</div><div class="line"> tinfo-&gt;_os &lt;&lt; <span class="stringliteral">&quot;Thread &quot;</span> &lt;&lt; std::dec &lt;&lt; tid &lt;&lt; <span class="stringliteral">&quot; uses &quot;</span> &lt;&lt; size &lt;&lt; <span class="stringliteral">&quot; bytes of stack.&quot;</span>;</div><div class="line"> <a class="code" href="group__APPDEBUG__API.html#gad46f50d48ebcf2414e766c2978111c4b">PIN_ApplicationBreakpoint</a>(ctxt, tid, FALSE, tinfo-&gt;_os.str());</div><div class="line">}</div></div><!-- fragment --><p>The analysis routine OnStackChangeIf() keeps track of some metrics on stack usage and tests whether the threshold has been reached. If the threshold is crossed, it returns non-zero, and Pin executes the DoBreakpoint() analysis routine.</p>
<p>The interesting part of DoBreakpoint() is at the very end, where it calls <a class="el" href="group__APPDEBUG__API.html#gad46f50d48ebcf2414e766c2978111c4b">PIN_ApplicationBreakpoint()</a>. This API causes Pin to stop the execution of all threads and triggers a breakpoint in the debugger. There is also a string parameter to <a class="el" href="group__APPDEBUG__API.html#gad46f50d48ebcf2414e766c2978111c4b">PIN_ApplicationBreakpoint()</a>, which is displayed in Visual Studio when the breakpoint triggers. A Pintool can use this string to tell the user why a breakpoint triggered. In our example tool, this string says something like "Thread 10 uses 4000 bytes of stack".</p>
<p>We can see the breakpoint feature in action in our example tool by typing this command in the Pin Console window:</p>
<pre class="fragment">&gt;stackbreak 4000
Will break when thread uses more than 4000 bytes of stack.
</pre><p>Then press F5 to continue execution. The application should stop in the debugger again with a message like this:</p>
<div class="image">
<img src="stack-debugger-custom-break.png" alt="stack-debugger-custom-break.png"/>
</div>
<p>When you are done, you can either continue the application with F5 or terminate it with SHIFT-F5.</p>
<p><br />
</p><hr/>
<h1><a class="anchor" id="EX"></a>
Applying a Pintool to an Application</h1>
<hr/>
<p>An application and a tool are invoked as follows:</p>
<pre class="fragment">pin [pin-option]... -t [toolname] [tool-options]... -- [application] [application-option]..
</pre><p>These are a few of the Pin options are currently available. See <a class="el" href="group__KNOBS.html">Command Line Switches</a> for the complete list. </p><ul>
<li>
-t <em>toolname</em>: Specifies the Pintool to use. If you are running a 32-bit application in an IA-32 architecture, or a 64-bit application on an Intel(R) 64 architecture, only -t &lt;toolname&gt; is needed. If you are running an application on an Intel(R) 64 architecture, where all of the components in the chain are either 32-bit or 64-bit, but not both, only -t &lt;toolname&gt; is needed. If you are running an application on an Intel(R) 64 architecture, where components in the chain are both 32-bit and 64-bit, use -t64 &lt;64-bit toolname&gt; to specify the 64-bit tool binary followed by -t &lt;32-bit toolname&gt; to specify the 32-bit tool binary and the tool options. For more information, see <a class="el" href="index.html#MIXED-MODE">Instrumenting Applications on Intel(R) 64 Architectures</a> </li>
<li>
-t64 <em>toolname</em>: Specify 64-bit tool binary for Intel(R) 64 architecture. If you are running an application on an Intel(R) 64 architecture, where components in the chain are both 32-bit and 64-bit, use -t64 together with -t as described above. See <a class="el" href="index.html#MIXED-MODE">Instrumenting Applications on Intel(R) 64 Architectures</a>. <br />
<b>Important</b>: Using -t64 without -t is not recommended, since in this case when given a 32-bit application, Pin will run the application without applying any tool. </li>
<li>
-p32 <em>toolname</em>: Specify Pin binary for IA-32 architecture. See <a class="el" href="index.html#MIXED-MODE">Instrumenting Applications on Intel(R) 64 Architectures</a> </li>
<li>
-p64 <em>toolname</em>: Specify Pin binary for Intel(R) 64 architecture. See <a class="el" href="index.html#MIXED-MODE">Instrumenting Applications on Intel(R) 64 Architectures</a> </li>
<li>
-pause_tool n: is a useful Pin-option which prints out the process id and pauses Pin for n seconds to permit attaching with gdb. See <a class="el" href="index.html#DEBUGGING">Tips for Debugging a Pintool</a>. </li>
<li>
-follow_execv: Execute with Pin all processes spawned by execv class system calls. </li>
<li>
<p class="startli">-injection <em>mode</em>: Where <em>mode</em> is one of dynamic, self, child, parent. <em>UNIX-only</em> See <a class="el" href="index.html#INJECTION">Injection</a>.</p>
<p class="endli"></p>
</li>
</ul>
<p>The tool-options follow immediately after the tool specification and depend on the tool used.</p>
<p>Everything following the <code>&ndash;</code> is the command line for the application.</p>
<p>For example, to apply the itrace example (<a class="el" href="index.html#IAddressTrace">Instruction Address Trace (Instruction Instrumentation)</a>) to a run of the "ls" program:</p>
<pre class="fragment">../../../pin -t obj-intel64/itrace.so -- /bin/ls
</pre><p>To get a listing of the available command line options for Pin:</p>
<pre class="fragment">pin -help
</pre><p>To get a listing of the available command line options for the itrace example:</p>
<pre class="fragment">../../../pin -t obj-intel64/itrace.so -help -- /bin/ls
</pre><p>Note that in the last case <code>/bin/ls</code> is necessary on the command line but will not be executed.</p>
<h2><a class="anchor" id="MIXED-MODE"></a>
Instrumenting Applications on Intel(R) 64 Architectures</h2>
<p>The Pin kit for IA-32 and Intel(R) 64 architectures is a combined kit. Both a 32-bit version and a 64-bit version of Pin are present in the kit. This allows Pin to instrument complex applications on Intel(R) 64 architectures which may have 32-bit and 64-bit components.</p>
<p>An application and a tool are invoked in "mixed-mode" as follows:</p>
<pre class="fragment">pin [pin-option]... -t64 &lt;64-bit toolname&gt; -t &lt;32-bit toolname&gt; [tool-options]...
-- &lt;application&gt; [application-option]..
</pre><p>Please note:</p><ul>
<li>The -t64 option must precede the -t option.</li>
<li>When using -t64 together with -t, -t specifies the 32-bit tool. Using -t64 without -t is not recommended, since in this case when given a 32-bit application, Pin will run the application without applying any tool.</li>
<li>The <em>[tool-options]</em> apply to both the 64-bit and the 32-bit tools and <b>must</b> be specified <b>after</b> <em>-t &lt;32-bit toolname&gt;</em>. It is not possible to specify different set of options for the 64-bit and the 32-bit tools.</li>
</ul>
<p>See source/tools/CrossIa32Intel64/makefile for a few examples.</p>
<p>The file "pin" is a c-based launcher executable that expects the Pin binary "pinbin" to be in the architecture-specific "bin" subdirectory (i.e. intel64/bin). The "pin" launcher distinguishes the 32-bit version of the Pin binary from the 64-bit version of the Pin binary by using the -p32/-p64 switches, respectively. Today, the 32-bit version of the Pin binary is invoked, and the path of the 64-bit version of Pin is passed as an argument using the -p64 switch. However, one could change this to invoke the 64-bit version of the Pin binary, and pass the 32-bit version of the Pin binary as an argument using the -p32 switch.</p>
<h2><a class="anchor" id="INJECTION"></a>
Injection</h2>
<p>The -injection switch is UNIX-only and controls the way Pin is injected into the application process. The default, dynamic, is recommended for all users. It uses parent injection unless it is unsupported (Linux 2.4 kernels). Child injection creates the application process as a child of the pin process so you will see both a pin process and the application process running. In parent injection, the pin process exits after injecting the application and is less likely to cause a problem. Using parent injection on an unsupported platform may lead to nondeterministic errors.</p>
<p>IMPORTANT: The description about invoking assumes that the application is a program binary (and not a shell script). If your application is invoked indirectly (from a shell script or using 'exec') then you need to change the actual invocation of the program binary by prefixing it with Pin/Pintool options. Here's one way of doing that:</p>
<pre class="fragment"> # Track down the actual application binary, say it is 'application_binary'.
% mv application_binary application_binary.real
# Write a shell script named 'application_binary' with the following contents.
# (change 'itrace' to your desired tool)
#!/bin/sh
../../../pin -t obj-intel64/itrace.so -- application_binary.real $*
</pre><p>After you do this, whenever 'application_binary' is invoked indirectly (from some shell script or using 'exec'), the real binary will get invoked with the right Pin/Pintool options.</p>
<h2><a class="anchor" id="PINTOOL_RESTRICTIONS"></a>
Restrictions</h2>
<p>There is a known problem of using Pin on systems protected by the "McAfee Host Intrusion Prevention"* antivirus software. We did not test coexistence of Pin with other antivirus products that perform run-time execution monitoring.</p>
<p>There is a known limitation of using Pin on Linux systems that prevent the use of ptrace attach via the sysctl /proc/sys/kernel/yama/ptrace_scope. Pin will still work when launching applications with the pin command line. However, Pin will fail in attach mode (that is, using the -pid knob). To resolve this, do the following (as root): </p><pre class="fragment">$ echo 0 &gt; /proc/sys/kernel/yama/ptrace_scope
</pre><p>Pin ignores a ptrace command with PT_DENY_ATTACH request coming from the application on macOS* systems (flag exists only on these systems). This means that if Pin launched an application and this application used PTRACE with PT_DENY_ATTACH flag, then:</p><ul>
<li>Pin will be able to do detach/re-attach</li>
<li>A debugger will be able to attach to the application process and debug Pin/tool</li>
<li>Pin ADX will be able to attach to the application process and debug it while running under Pin Note: Pin is currently unable to attach to an application which already executed ptrace with PT_DENY_ATTACH request.</li>
</ul>
<p><br />
</p><hr/>
<h1><a class="anchor" id="DEBUGGING"></a>
Tips for Debugging a Pintool</h1>
<hr/>
<h2><a class="anchor" id="XXX"></a>
Using gdb on Linux</h2>
<p>When running an application under the control of Pin and a Pintool there are two different programs residing in the address space. The application, and the Pin instrumentation engine together with your Pintool. The Pintool is normally a shared object loaded by Pin. This section describes how to use gdb to find bugs in a Pintool. You cannot run Pin directly from gdb since Pin uses the debugging API to start the application. Instead, you must invoke Pin from the command line with the -pause_tool switch, and use gdb to attach to the Pin process from another window. The -pause_tool n switch makes Pin print out the process identifier (pid) and pause for n seconds.</p>
<p>Pin searches for the tool in an internal search algorithm. Therefore in many cases gdb is unable to load the debug info for the tool. There are several options to help gdb find the debug info. </p><pre class="fragment"> Option 1 is to use full path to the tool when running pin.
Option 2 is to tell gdb to load the debugging information of the tool.
Pin prompts with the exact gdb command to be used in this case.
</pre><p>To check that gdb loaded the debugging info to the tool use the command "info sharedlibrary" and you should see that gdb has read the symbols for your tool (as in the example below).</p>
<pre class="fragment">(gdb) info sharedlibrary
From To Syms Read Shared Object Library
0x001b3ea0 0x001b4d80 Yes /lib/libdl.so.2
0x003b3820 0x00431d74 Yes /usr/intel/pkgs/gcc/4.2.0/lib/libstdc++.so.6
0x0084f4f0 0x00866f8c Yes /lib/i686/libm.so.6
0x00df8760 0x00dffcc4 Yes /usr/intel/pkgs/gcc/4.2.0/lib/libgcc_s.so.1
0x00e5fa00 0x00f60398 Yes /lib/i686/libc.so.6
0x40001c50 0x4001367f Yes /lib/ld-linux.so.2
0x008977f0 0x00af7784 Yes ./dcache.so
</pre> <pre class="fragment"> For example, if your tool is called opcodemix and the application is /bin/ls,
you can use gdb as described below. The following example is for the Intel(R) 64 Linux platform.
Substitute "ia32" for the IA-32 architecture.
Change directory to the directory where your
tool resides, and start gdb with pin, but do not use the run command.
</pre><pre class="fragment">$ /usr/bin/gdb ../../../intel64/bin/pinbin
GNU gdb Red Hat Linux (6.3.0.0-1.132.EL4rh)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu"...Using host libthread_db library "/lib64/tls/libthread_db.so.1"
(gdb)
</pre><p>In another window, start your application with the -pause_tool switch.</p>
<pre class="fragment">$ ../../../pin -pause_tool 10 -t obj-intel64/opcodemix.so -- /bin/ls
Pausing for 10 seconds to attach to process with pid 28769
To load the tool's debug info to gdb use:
add-symbol-file .../source/tools/SimpleExamples/obj-intel64/opcodemix.so 0x2a959e9830
</pre><p>Then go back to gdb and attach to the process.</p>
<pre class="fragment">(gdb) attach 28769
Attaching to program: .../intel64/bin/pinbin, process 28769
0x000000314b38f7a2 in ?? ()
(gdb)
</pre><p>Now, you should tell gdb to load the Pintool debugging information, by copying the debugging message we got when invoking pin with the -pause_tool switch..</p>
<pre class="fragment">(gdb) add-symbol-file .../source/tools/SimpleExamples/obj-intel64/opcodemix.so 0x2a959e9830
add symbol table from file ".../source/tools/SimpleExamples/obj-intel64/opcodemix.so" at
.text_addr = 0x2a959e9830
(y or n) y
Reading symbols from .../source/tools/SimpleExamples/obj-intel64/opcodemix.so...done.
(gdb)
</pre><p>Now, instead of using the gdb run command, you use the <code>cont</code> command to continue execution. You can also set breakpoints as normal.</p>
<pre class="fragment">(gdb) b opcodemix.cpp:447
Breakpoint 1 at 0x2a959ecf60: file opcodemix.cpp, line 447.
(gdb) cont
Continuing.
Breakpoint 1, main (argc=7, argv=0x3ff00f12f8) at opcodemix.cpp:447
447 int main(int argc, CHAR *argv[])
(gdb)
</pre><p>If the program does not exit, then you should detach so gdb will release control.</p>
<pre class="fragment">(gdb) detach
Detaching from program: .../intel64/bin/pinbin, process 28769
(gdb)
</pre><p>If you recompile your program and then use the run command, gdb will notice that the binary has been changed and reread the debug information from the file. This does not always happen automatically when using attach. In this case you must use the "add-symbol-file" command again to make gdb reread the debug information.</p>
<h2><a class="anchor" id="VSDBG"></a>
Using the Visual Studio Debugger on Windows</h2>
<p>When running an application under the control of Pin and a Pintool there are two different programs residing in the address space. The application, and the Pin instrumentation engine together with your Pintool. The Pintool is a dynamically loaded library (.dll) loaded by Pin. This section describes how to use the Visual Studio Debugger to find bugs in a Pintool. You cannot run Pin directly from the debugger since Pin uses the debugging API to start the application. Instead, you must invoke Pin from the command line with the -pause_tool switch, and use Visual Studio to attach to the Pin process from another window. The -pause_tool n switch makes Pin print out the process identifier (pid) and pause for n seconds. You have n seconds (20 in our example) to attach the application with the debugger. Note, application resumes once the timeout expires. Attaching debugger later will not have the desired effect.</p>
<pre class="fragment"> % pin &lt;pin options&gt; -pause_tool 20 -t &lt;tool name&gt; &lt;tool options&gt; -- &lt;app name&gt; &lt;app options&gt;
Pausing for 20 seconds to attach to process with pid 28769
</pre><p>In the Visual Studio window, attach to the application process using the "Debug"-&gt;"Attach to Process" menu selection and wait until a breakpoint occurs. Then you can set breakpoints in your tool in the usual way.</p>
<p>Note, it is necessary to build your Pintool with debug symbols if you want symbolic information.</p>
<h2><a class="anchor" id="WinDbg"></a>
Using the WinDbg Debugger on Windows</h2>
<p>WinDbg Debugger is the only available option to debug Pintool when it is necessary to attach to an instrumented process after Pin initialization. It also could be used instead of Visual Studio Debugger in scenario described above. The debugger is available at <a href="https://msdn.microsoft.com/en-us/library/windows/hardware/ff551063(v=vs.85).aspx">https://msdn.microsoft.com/en-us/library/windows/hardware/ff551063(v=vs.85).aspx</a></p>
<p>The following steps are necessary to properly debug Pintool in instrumented process: </p><pre class="fragment"> - Install latest WinDbg and Process Explorer utility
( https://technet.microsoft.com/en-us/sysinternals/processexplorer.aspx )
- Add Microsoft Symbol Server settings in WinDbg: in "File" -&gt; "Symbol File Path"
type &lt;b&gt; srv*c:\\symbols*http://msdl.microsoft.com/download/symbols &lt;/b&gt;.
Create c:\\symbols directory that will serve as local repository for OS DLLs symbols.
- Attach WinDbg to an instrumented process. Architectures of WinDbg and the process should match.
- Use Process Explorer to notice location of hidden DLLs (Pintool DLL, its dependencies and pinvm.dll).
Select process of interest in Process View, type &lt;em&gt;Ctrl-D&lt;/em&gt; , then double-click
on each hidden DLL of interest in DLL View to get location info.
- When Windbg stops after attach, enter the following command for each hidden DLL:
</pre> <pre class="fragment">.reload /f &lt;name&gt;=&lt;address&gt;,&lt;size&gt;
</pre><p> where <em>&lt;name&gt;</em> is DLL base name, <em>&lt;address&gt;</em> is its actual base address and <em>&lt;size&gt;</em> is its actual size in memory. Example: </p><pre class="fragment">.reload /f mytool.dll=0x50200000,0x420000
</pre><ul>
<li>From now on you can set breakpoints using symbolic info of the DLLs and see comprehensive call stacks.</li>
</ul>
<p><br />
</p><hr/>
<h1><a class="anchor" id="LOGGING"></a>
Logging Messages from a Pintool</h1>
<hr/>
<p>Pin provides a mechanism to write messages from a Pintool to a logfile. To use this capability, call the LOG() API with your message. The default filename is pintool.log, and it is created in the currently working directory. Use the -logfile switch after the tool name to change the path and file name of the log file.</p>
<div class="fragment"><div class="line">LOG( <span class="stringliteral">&quot;Replacing function in &quot;</span> + <a class="code" href="group__IMG__BASIC__API.html#ga22acd549352fc062c6c62c82e7a09354">IMG_Name</a>(img) + <span class="stringliteral">&quot;\n&quot;</span> );</div><div class="line">LOG( <span class="stringliteral">&quot;Address = &quot;</span> + <a class="code" href="group__MISC__PRINT.html#ga800b573e4c367225ce2d8f533c4c934f">hexstr</a>( <a class="code" href="group__RTN__BASIC__API.html#ga83a81fae96c9faabe0f1c90a0d7e865f">RTN_Address</a>(rtn)) + <span class="stringliteral">&quot;\n&quot;</span> );</div><div class="line">LOG( <span class="stringliteral">&quot;Image ID = &quot;</span> + <a class="code" href="group__MISC__PRINT.html#ga0a07c9fee11e18f9eb88ee3f18fa3948">decstr</a>( <a class="code" href="group__IMG__BASIC__API.html#gae9802263d9ceb357e46f215d86294548">IMG_Id</a>(img) ) + <span class="stringliteral">&quot;\n&quot;</span> );</div></div><!-- fragment --><p><br />
</p><hr/>
<h1><a class="anchor" id="PERFORMANCE"></a>
Performance Considerations When Writing a Pintool</h1>
<hr/>
<p>The way a Pintool is written can have great impact on the performace of the tool, i.e. how much it slows down the applications it is instrumenting. This section demonstrates some techniques that can be used to improve tool performance. Let's start with an example. The following piece of code is derived from the source/tools/SimpleExamples/edgcnt.cpp:</p>
<p>The instrumentation component of the tool is show below</p>
<div class="fragment"><div class="line">VOID Instruction(INS ins, <span class="keywordtype">void</span> *v)</div><div class="line">{</div><div class="line"> ...</div><div class="line"></div><div class="line"> <span class="keywordflow">if</span> ( [ins is a branch or a call instruction] )</div><div class="line"> {</div><div class="line"></div><div class="line"></div><div class="line"> <a class="code" href="group__INS__INST__API.html#ga74a956a0acde197043d04f4adcde4626">INS_InsertCall</a>(ins, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>, (AFUNPTR) docount2,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da623ad95758bce14fcb9427beef53736a">IARG_INST_PTR</a>,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451daa1b650f4229df434f3ac5ef61f14d0ed">IARG_BRANCH_TARGET_ADDR</a>,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da28140354d575f6b6404a6833552fed47">IARG_BRANCH_TAKEN</a>,</div><div class="line"> IARG_END);</div><div class="line"> }</div><div class="line"></div><div class="line"> ...</div><div class="line">}</div></div><!-- fragment --><p>The analysis component looks like this: </p><div class="fragment"><div class="line">VOID docount2( ADDRINT src, ADDRINT dst, INT32 taken )</div><div class="line">{</div><div class="line"> <span class="keywordflow">if</span>(!taken) <span class="keywordflow">return</span>;</div><div class="line"> COUNTER *pedg = Lookup( src,dst );</div><div class="line"> pedg-&gt;_count++;</div><div class="line">}</div></div><!-- fragment --><p>The purpose of the tool is to count how often each controlflow changing edge in the control flowgraph is traversed. The tool considers both calls and branches but for brevity we will not mention branches in our description. The tool works as follows: The instrumentation component instruments each branch with a call to docount2. As parameters we pass in the origin and the target of the branch and whether the branch was taken or not. Branch origin and target represent of the source and destination of the controlflow edges. If a branch is not taken the controlflow does not change and hence the analysis routine returns right away. If the branch is taken we use the src and dst parameters to look up the counter associated with this edge (Lookup will create a new one if this edge has not been seen before) and increment the counter. Note, that the tool could have been simplified somewhat by using IPOINT_TAKEN_BRANCH option with <a class="el" href="group__INS__INST__API.html#ga74a956a0acde197043d04f4adcde4626">INS_InsertCall()</a>.</p>
<h2><a class="anchor" id="shifting_computation"></a>
Shifting Computation for Analysis to Instrumentation Code</h2>
<p>About every 5th instruction executed in a typical application is a branch. Lookup will called whenever these instruction are executed, causing significant application slowdown. To improve the situation we note that the instrumentation code is typically called only once for every instruction, while the analysis code is called everytime the instruction is executed. If we can somehow shift computation from the analysis code to the instrumentation code we will improve the overall performance. Our example tools offer multiple such opportunites which will explore in turn. The first observation is that for most branches we can find out inside of Instruction() what the branch target will be . For those branches we can call Lookup inside of Instruction() rather than in docount2(), for indirect branches which are relatively rare we still have to use our original approach. All this is reflected in the folling code. We add a second "lighter" analsysis function, docount. While the original docount2() remains unchanged:</p>
<div class="fragment"><div class="line">VOID docount( COUNTER *pedg, INT32 taken )</div><div class="line">{</div><div class="line"> <span class="keywordflow">if</span>( !taken ) <span class="keywordflow">return</span>;</div><div class="line"> pedg-&gt;_count++;</div><div class="line">}</div></div><!-- fragment --><p>And the instrumentation will be somewhat more complex:</p>
<div class="fragment"><div class="line">VOID Instruction(INS ins, <span class="keywordtype">void</span> *v)</div><div class="line">{</div><div class="line"> ...</div><div class="line"></div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__INS__BASIC__API__GEN__IA32.html#gafbf707d5a79e83a85484d42b8aea0b05">INS_IsDirectControlFlow</a>(ins))</div><div class="line"> {</div><div class="line"> COUNTER *pedg = Lookup( <a class="code" href="group__INS__BASIC__API__GEN__IA32.html#ga6b685dec56c6a045f8cc3c03f52d054a">INS_Address</a>(ins), <a class="code" href="group__INS__BASIC__API__GEN__IA32.html#ga2d671f0dbc9e496207e3ac4407a40c32">INS_DirectControlFlowTargetAddress</a>(ins) );</div><div class="line"></div><div class="line"> <a class="code" href="group__INS__INST__API.html#ga74a956a0acde197043d04f4adcde4626">INS_InsertCall</a>(ins, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>, (AFUNPTR) docount,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da34126f334d65afac69784351a03615ad">IARG_ADDRINT</a>, pedg,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da28140354d575f6b6404a6833552fed47">IARG_BRANCH_TAKEN</a>,</div><div class="line"> IARG_END);</div><div class="line"> }</div><div class="line"> <span class="keywordflow">else</span></div><div class="line"> {</div><div class="line"> <a class="code" href="group__INS__INST__API.html#ga74a956a0acde197043d04f4adcde4626">INS_InsertCall</a>(ins, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>, (AFUNPTR) docount2,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da623ad95758bce14fcb9427beef53736a">IARG_INST_PTR</a>,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451daa1b650f4229df434f3ac5ef61f14d0ed">IARG_BRANCH_TARGET_ADDR</a>,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da28140354d575f6b6404a6833552fed47">IARG_BRANCH_TAKEN</a>,</div><div class="line"> IARG_END);</div><div class="line"> }</div><div class="line"></div><div class="line"> ...</div><div class="line">}</div></div><!-- fragment --><h2><a class="anchor" id="control_flow"></a>
Eliminating Control Flow</h2>
<p>The code for docount() is very compact which provides performance advantages; it may also allow it to be inlined by Pin, thereby avoiding the overhead of a call. The heuristics for when a analysis routine is inlined by Pin are subject to change. But small routines without any control flow (single basic block) are almost guaranteed to be inlined. Unfortunately, docount() does have (albeit limited) control flow. Observing that the parameter, 'taken', will be zero or one we can eliminate the remaining control flow as follows:</p>
<div class="fragment"><div class="line">VOID docount( COUNTER *pedg, INT32 taken )</div><div class="line">{</div><div class="line"> pedg-&gt;_count += taken;</div><div class="line">}</div></div><!-- fragment --><p>Now docount() can be inlined.</p>
<h2><a class="anchor" id="compiler_inlining"></a>
Compiler Considerations for Inlining</h2>
<p>The way that the tool is built affects inlining as well. If an analysis routine has a function call to another function, it would not be a candidate for inlining by Pin unless the function call was inlined by the compiler. If the function call is inlined by the compiler, the analysis routine would be a candidate for inlining by Pin. Therefore, it is advisable to write any subroutines called by the analysis routine in a way that allows the compiler to inline the subroutines.</p>
<p>On Linux IA-32 architectures, Pintools are built non-PIC (Position Independent Code), which allows the compiler to inline both local and global functions. Tools for Linux Intel(R) 64 architectures are built PIC, but the compiler will not inline any globally visible function due to function pre-emption. Therefore, it is advisable to declare the subroutines called by the analysis function as 'static' on Linux Intel(R) 64 architectures.</p>
<h2><a class="anchor" id="let_pin_decide"></a>
Letting Pin Decide Where to Instrument</h2>
<p>At times we do not care about the exact point where calls to analysis code are being inserted as long as it is within a given basic block. In this case we can let Pin make the decission where to insert. This has the advantage that Pin can select am insertion point that requires minimal register saving and restoring. The following code from ManualExamples/inscount2.cpp shows how this is done for the instruction count example using IPOINT_ANYWHERE with <a class="el" href="group__BBL__BASIC__API.html#gaeee9d7a6253d49d226bbed3f35768169">BBL_InsertCall()</a>.</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;fstream&gt;</span></div><div class="line"><span class="preprocessor">#include &quot;pin.H&quot;</span></div><div class="line"><span class="keyword">using</span> std::cerr;</div><div class="line"><span class="keyword">using</span> std::ofstream;</div><div class="line"><span class="keyword">using</span> std::ios;</div><div class="line"><span class="keyword">using</span> std::string;</div><div class="line"><span class="keyword">using</span> std::endl;</div><div class="line"></div><div class="line">ofstream OutFile;</div><div class="line"></div><div class="line"><span class="comment">// The running count of instructions is kept here</span></div><div class="line"><span class="comment">// make it static to help the compiler optimize docount</span></div><div class="line"><span class="keyword">static</span> UINT64 icount = 0;</div><div class="line"></div><div class="line"><span class="comment">// This function is called before every block</span></div><div class="line"><span class="comment">// Use the fast linkage for calls</span></div><div class="line">VOID <a class="code" href="group__INST__ARGS.html#ga5d3025eb005b7ea4745799f0ee1b86a6">PIN_FAST_ANALYSIS_CALL</a> docount(ADDRINT c) { icount += c; }</div><div class="line"> </div><div class="line"><span class="comment">// Pin calls this function every time a new basic block is encountered</span></div><div class="line"><span class="comment">// It inserts a call to docount</span></div><div class="line">VOID Trace(<a class="code" href="group__TRACE__BASIC__API.html#gaf9f3009a146688d5230a16f8d3e575be">TRACE</a> trace, VOID *v)</div><div class="line">{</div><div class="line"> <span class="comment">// Visit every basic block in the trace</span></div><div class="line"> <span class="keywordflow">for</span> (BBL bbl = <a class="code" href="group__TRACE__BASIC__API.html#ga008abc5ba1af8d9e9cd073ffe0aefa18">TRACE_BblHead</a>(trace); <a class="code" href="group__BBL__BASIC__API.html#ga58a8d019cd09ce46cfe431ec8f14a075">BBL_Valid</a>(bbl); bbl = <a class="code" href="group__BBL__BASIC__API.html#gadd7141abb47139b52922e04e0c4a10f3">BBL_Next</a>(bbl))</div><div class="line"> {</div><div class="line"> <span class="comment">// Insert a call to docount for every bbl, passing the number of instructions.</span></div><div class="line"> <span class="comment">// IPOINT_ANYWHERE allows Pin to schedule the call anywhere in the bbl to obtain best performance.</span></div><div class="line"> <span class="comment">// Use a fast linkage for the call.</span></div><div class="line"> <a class="code" href="group__BBL__BASIC__API.html#gaeee9d7a6253d49d226bbed3f35768169">BBL_InsertCall</a>(bbl, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7acf7dee2063098dd79907d19f9c7df65d">IPOINT_ANYWHERE</a>, AFUNPTR(docount), <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da892dbdf11883df94c327bb31fd0d5fcd">IARG_FAST_ANALYSIS_CALL</a>, <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dabd19b79248899659441e56e4738d5bfd">IARG_UINT32</a>, <a class="code" href="group__BBL__BASIC__API.html#ga76ceb2d9e0fb974d3c3769b2413ed634">BBL_NumIns</a>(bbl), IARG_END);</div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line">KNOB&lt;string&gt; KnobOutputFile(<a class="code" href="group__KNOB__BASIC.html#ggad45510089e3b85a88df038e900e9f8baa576ddd3b58b1121ff4070df605951cf6">KNOB_MODE_WRITEONCE</a>, <span class="stringliteral">&quot;pintool&quot;</span>,</div><div class="line"> <span class="stringliteral">&quot;o&quot;</span>, <span class="stringliteral">&quot;inscount.out&quot;</span>, <span class="stringliteral">&quot;specify output file name&quot;</span>);</div><div class="line"></div><div class="line"><span class="comment">// This function is called when the application exits</span></div><div class="line">VOID Fini(INT32 code, VOID *v)</div><div class="line">{</div><div class="line"> <span class="comment">// Write to a file since cout and cerr maybe closed by the application</span></div><div class="line"> OutFile.setf(ios::showbase);</div><div class="line"> OutFile &lt;&lt; <span class="stringliteral">&quot;Count &quot;</span> &lt;&lt; icount &lt;&lt; endl;</div><div class="line"> OutFile.close();</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Print Help Message */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line">INT32 Usage()</div><div class="line">{</div><div class="line"> cerr &lt;&lt; <span class="stringliteral">&quot;This tool counts the number of dynamic instructions executed&quot;</span> &lt;&lt; endl;</div><div class="line"> cerr &lt;&lt; endl &lt;&lt; KNOB_BASE::StringKnobSummary() &lt;&lt; endl;</div><div class="line"> <span class="keywordflow">return</span> -1;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Main */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> * argv[])</div><div class="line">{</div><div class="line"> <span class="comment">// Initialize pin</span></div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__PIN__CONTROL.html#ga783d3bd40c3fb2ca51b1f9af31a70c9c">PIN_Init</a>(argc, argv)) <span class="keywordflow">return</span> Usage();</div><div class="line"></div><div class="line"> OutFile.open(KnobOutputFile.Value().c_str());</div><div class="line"></div><div class="line"> <span class="comment">// Register Instruction to be called to instrument instructions</span></div><div class="line"> <a class="code" href="group__TRACE__BASIC__API.html#ga41381de13d25c4bbd968cb64cb719d56">TRACE_AddInstrumentFunction</a>(Trace, 0);</div><div class="line"></div><div class="line"> <span class="comment">// Register Fini to be called when the application exits</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gac167b8d28d255e53a0ac1f6e9edcd3ec">PIN_AddFiniFunction</a>(Fini, 0);</div><div class="line"> </div><div class="line"> <span class="comment">// Start the program, never returns</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gaded401aeb030a76ee3396137b06ad808">PIN_StartProgram</a>();</div><div class="line"> </div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment --><h2><a class="anchor" id="fast_linkage"></a>
Using Fast Call Linkages</h2>
<p>For very small analysis functions, the overhead to call the function can be comparable to the work done in the function. Some compilers offer optimized call linkages that eliminate some of the overhead. For example, gcc for the IA-32 architecture has a regparm attribute for passing arguments in registers. Pin supports a limited number of alternate linkages. To use it, you must annotate the declaration of the analysis function with <a class="el" href="group__INST__ARGS.html#ga5d3025eb005b7ea4745799f0ee1b86a6">PIN_FAST_ANALYSIS_CALL</a>. The InsertCall function must pass <a class="el" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da892dbdf11883df94c327bb31fd0d5fcd">IARG_FAST_ANALYSIS_CALL</a>. If you change one without changing the other, the arguments will not be passed correctly. See the inscount2.cpp example in the previous section for a sample use. For large analysis functions, the benefit may not be significant, but it is unlikely that PIN_FAST_ANALYSIS_CALL would ever cause a slowdown.</p>
<p>Another call linkage optimization is to eliminate the frame pointer. We recommend using -fomit-frame-pointer to compile tools with gcc. See the gcc documentation for an explanation of what it does. The standard Pintool makefiles include -fomit-frame-pointer. Like PIN_FAST_ANALYSIS_CALL, the benefit is largest for small analysis functions. Debuggers rely on frame pointers to display stack traces, so eliminate this option when trying to debug a PinTool. If you are using a standard PinTool makefile, you can do this by overriding the definition of OPT on the command line with</p>
<pre class="fragment">make OPT=-O0
</pre><h2><a class="anchor" id="partial_inline"></a>
Rewriting Conditional Analysis Code to Help Pin Inline</h2>
<p>Pin improves instrumentation performance by automatically inlining analysis routines that have no control-flow changes. Of course, many analysis routines do have control-flow changes. One particularly common case is that an analysis routine has a single "if-then" test, where a small amount of analysis code plus the test is always executed but the "then" part is executed only once a while. To inline this common case, Pin provides a set of conditional instrumentation APIs for the tool writer to rewrite their analysis routines into a form that does not have control-flow changes. The following example from source/tools/ManualExamples/isampling.cpp illustrates how such rewriting can be done:</p>
<div class="fragment"><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"> * This file contains a Pintool for sampling the IPs of instruction executed.</span></div><div class="line"><span class="comment"> * It serves as an example of a more efficient way to write analysis routines</span></div><div class="line"><span class="comment"> * that include conditional tests.</span></div><div class="line"><span class="comment"> * Currently, it works on IA-32 and Intel(R) 64 architectures.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"></div><div class="line"><span class="preprocessor">#include &lt;stdio.h&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;stdlib.h&gt;</span></div><div class="line"><span class="preprocessor">#include &quot;pin.H&quot;</span></div><div class="line"></div><div class="line">FILE * trace;</div><div class="line"></div><div class="line"><span class="keyword">const</span> INT32 N = 100000;</div><div class="line"><span class="keyword">const</span> INT32 M = 50000;</div><div class="line"></div><div class="line">INT32 icount = N;</div><div class="line"></div><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"> * IP-sampling could be done in a single analysis routine like:</span></div><div class="line"><span class="comment"> *</span></div><div class="line"><span class="comment"> * VOID IpSample(VOID *ip)</span></div><div class="line"><span class="comment"> * {</span></div><div class="line"><span class="comment"> * --icount;</span></div><div class="line"><span class="comment"> * if (icount == 0)</span></div><div class="line"><span class="comment"> * {</span></div><div class="line"><span class="comment"> * fprintf(trace, &quot;%p\n&quot;, ip);</span></div><div class="line"><span class="comment"> * icount = N + rand() % M;</span></div><div class="line"><span class="comment"> * }</span></div><div class="line"><span class="comment"> * }</span></div><div class="line"><span class="comment"> *</span></div><div class="line"><span class="comment"> * However, we break IpSample() into two analysis routines,</span></div><div class="line"><span class="comment"> * CountDown() and PrintIp(), to facilitate Pin inlining CountDown()</span></div><div class="line"><span class="comment"> * (which is the much more frequently executed one than PrintIp()).</span></div><div class="line"><span class="comment"> */</span></div><div class="line"></div><div class="line">ADDRINT CountDown()</div><div class="line">{</div><div class="line"> --icount;</div><div class="line"> <span class="keywordflow">return</span> (icount==0);</div><div class="line">}</div><div class="line"></div><div class="line"></div><div class="line"><span class="comment">// The IP of the current instruction will be printed and</span></div><div class="line"><span class="comment">// the icount will be reset to a random number between N and N+M.</span></div><div class="line">VOID PrintIp(VOID *ip)</div><div class="line">{</div><div class="line"> fprintf(trace, <span class="stringliteral">&quot;%p\n&quot;</span>, ip);</div><div class="line"> </div><div class="line"> <span class="comment">// Prepare for next period</span></div><div class="line"> icount = N + rand() % M; <span class="comment">// random number from N to N+M</span></div><div class="line">}</div><div class="line"></div><div class="line"></div><div class="line"><span class="comment">// Pin calls this function every time a new instruction is encountered</span></div><div class="line">VOID Instruction(INS ins, VOID *v)</div><div class="line">{</div><div class="line"> <span class="comment">// CountDown() is called for every instruction executed</span></div><div class="line"> <a class="code" href="group__INS__INST__API.html#ga7907ad8ebd991b9e24df3b3b9cec4cac">INS_InsertIfCall</a>(ins, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>, (AFUNPTR)CountDown, IARG_END);</div><div class="line"> </div><div class="line"> <span class="comment">// PrintIp() is called only when the last CountDown() returns a non-zero value.</span></div><div class="line"> <a class="code" href="group__INS__INST__API.html#ga952b2b061d3fa8f1cc4d5d59fef53a69">INS_InsertThenCall</a>(ins, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>, (AFUNPTR)PrintIp, <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da623ad95758bce14fcb9427beef53736a">IARG_INST_PTR</a>, IARG_END);</div><div class="line"> </div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// This function is called when the application exits</span></div><div class="line">VOID Fini(INT32 code, VOID *v)</div><div class="line">{</div><div class="line"> fprintf(trace, <span class="stringliteral">&quot;#eof\n&quot;</span>);</div><div class="line"> fclose(trace);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Print Help Message */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line">INT32 Usage()</div><div class="line">{</div><div class="line"> PIN_ERROR( <span class="stringliteral">&quot;This Pintool samples the IPs of instruction executed\n&quot;</span></div><div class="line"> + KNOB_BASE::StringKnobSummary() + <span class="stringliteral">&quot;\n&quot;</span>);</div><div class="line"> <span class="keywordflow">return</span> -1;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"><span class="comment">/* Main */</span></div><div class="line"><span class="comment">/* ===================================================================== */</span></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> * argv[])</div><div class="line">{</div><div class="line"> trace = fopen(<span class="stringliteral">&quot;isampling.out&quot;</span>, <span class="stringliteral">&quot;w&quot;</span>);</div><div class="line"> </div><div class="line"> <span class="comment">// Initialize pin</span></div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__PIN__CONTROL.html#ga783d3bd40c3fb2ca51b1f9af31a70c9c">PIN_Init</a>(argc, argv)) <span class="keywordflow">return</span> Usage();</div><div class="line"></div><div class="line"> <span class="comment">// Register Instruction to be called to instrument instructions</span></div><div class="line"> <a class="code" href="group__INS__INST__API.html#gaaff4a98e0ece27fc46c0050b4ae05c6d">INS_AddInstrumentFunction</a>(Instruction, 0);</div><div class="line"></div><div class="line"> <span class="comment">// Register Fini to be called when the application exits</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gac167b8d28d255e53a0ac1f6e9edcd3ec">PIN_AddFiniFunction</a>(Fini, 0);</div><div class="line"> </div><div class="line"> <span class="comment">// Start the program, never returns</span></div><div class="line"> <a class="code" href="group__PIN__CONTROL.html#gaded401aeb030a76ee3396137b06ad808">PIN_StartProgram</a>();</div><div class="line"> </div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment --><p>In the above example, the original analysis routine IpSample() has a conditional control-flow change. It is rewritten into two analysis routines: CountDown() and PrintIp(). CountDown() is the simpler one of the two, which doesn't have control-flow change. It also performs the original conditional test and returns the test result. We use the conditional instrumentaton APIs <a class="el" href="group__INS__INST__API.html#ga7907ad8ebd991b9e24df3b3b9cec4cac">INS_InsertIfCall()</a> and <a class="el" href="group__INS__INST__API.html#ga952b2b061d3fa8f1cc4d5d59fef53a69">INS_InsertThenCall()</a> to tell Pin that tbe analysis routine specified by an <a class="el" href="group__INS__INST__API.html#ga952b2b061d3fa8f1cc4d5d59fef53a69">INS_InsertThenCall()</a> (i.e. PrintIp() in this example) is executed only if the result of the analysis routine specified by the previous <a class="el" href="group__INS__INST__API.html#ga7907ad8ebd991b9e24df3b3b9cec4cac">INS_InsertIfCall()</a> (i.e. CountDown() in this example) is non-zero. Now CountDown(), the common case, can be inlined by Pin, and only once a while does Pin need to execute PrintIp(), the non-inlined case.</p>
<h2><a class="anchor" id="handling_reps"></a>
Optimizing Instrumentation of REP Prefixed Instructions</h2>
<p>The IA-32 and Intel(R) 64 architectures include REP prefixed string instructions. These use a REP prefix on a string operation to repeat the execution of the inner operation. For some instructions the repeat count is determined solely by the value in the count register. For others (SCAS,CMPS), the count register provides an upper limit on the number of iterations, while the REP opcode provides a condition to be tested which can exit the REP loop before the full number of iterations has been executed.</p>
<p>Pin treats REP prefixed instructions as an implicit loop around the inner instruction, so <a class="el" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a> and <a class="el" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a42eff26179c6d87348abe492301c12ec">IPOINT_AFTER</a> instrumentation is executed for that instruction once for each iteration of the (implicit) loop. Since each execution of the inner instruction is instrumented, IARG_MEMORY{READ,READ2,WRITE}_SIZE can be determined statically from the instruction (1,2,4,8 bytes), and IARG_MEMORY{OP,READ,READ2,WRITE}_EA can also be determined (even if DF==1, so the inner instructions are decrementing their arguments and moving backwards through store).</p>
<p>REP prefixed instructions are treated as predicated, where the predicate is that the count register is non-zero. Therefore canonical instrumentation for memory accesses such as</p>
<div class="fragment"><div class="line"><span class="keywordflow">if</span> (<a class="code" href="group__INS__BASIC__API__GEN__IA32.html#ga3fdb434cd56a5b72be15dd0931a2b19c">INS_MemoryOperandIsRead</a>(ins,memOp))</div><div class="line">{</div><div class="line"> <a class="code" href="group__INS__INST__API.html#ga26d02bff719bf8600421895956804252">INS_InsertPredicatedCall</a>(ins, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>,(AFUNPTR)logMemory,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da985747a3c70e3a4283fc8a2f16399e63">IARG_MEMORYOP_EA</a>, memOp,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dabd19b79248899659441e56e4738d5bfd">IARG_UINT32</a>, <a class="code" href="group__INS__BASIC__API__GEN__IA32.html#ga94566988c11db3575963c2bd064898a3">INS_MemoryOperandSize</a>(ins,memOp),</div><div class="line"> IARG_END);</div><div class="line">}</div></div><!-- fragment --><p>will see all of the memory accesses made by the REP prefixed operations.</p>
<p>To allow tools to count entries into a REP prefixed instruction, and to optimize, Pin provides <a class="el" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da4e8c634973d6966dba21ff70455c1f5b">IARG_FIRST_REP_ITERATION</a>, which can be passed as an argument to an analysis routine. It is TRUE if this is the first iteration of a REP prefixed instruction, FALSE otherwise.</p>
<p>Thus to perform an action only on the first iteration of a REP prefixed instruction, one can use code like this (assuming that "takeAction" wants to be called on the first iteration of all REP prefixed instructions, even ones with a zero repeat count):</p>
<p>To obtain the repeat count, you can use </p><div class="fragment"><div class="line">IARG_REGISTER_VALUE, <a class="code" href="group__INS__BASIC__API__IA32.html#ga8c243487db5a05e7410602ddd7087776">INS_RepCountRegister</a>(ins),</div></div><!-- fragment --><p> which will pass the value in the appropriate count register (one of REG_CX,REG_ECX,REG_RCX depending on the instruction).</p>
<p>As an example, here is code which counts the number of times REP prefixed instructions are executed, optimizing cases in which the REP prefixed instruction only depends on the count register.</p>
<div class="fragment"><div class="line"><span class="keyword">class </span>stats</div><div class="line">{</div><div class="line"> UINT64 count; <span class="comment">// Times we start the REP prefixed op</span></div><div class="line"> UINT64 repeatedCount; <span class="comment">// Times we execute the inner instruction</span></div><div class="line"> UINT64 zeroLength; <span class="comment">// Times we start but don&#39;t execute the inner instruction because count is zero</span></div><div class="line"><span class="keyword">public</span>:</div><div class="line"> stats() : count(0), repeatedCount(0), zeroLength(0) {}</div><div class="line"> VOID output() <span class="keyword">const</span>;</div><div class="line"> VOID add(UINT32 firstRep, UINT32 repCount)</div><div class="line"> {</div><div class="line"> count += firstRep;</div><div class="line"> repeatedCount += repCount;</div><div class="line"> <span class="keywordflow">if</span> (repCount == 0)</div><div class="line"> zeroLength += 1;</div><div class="line"> }</div><div class="line"> BOOL empty()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> count == 0; }</div><div class="line"> stats&amp; operator+= (<span class="keyword">const</span> stats &amp;other)</div><div class="line"> {</div><div class="line"> count += other.count;</div><div class="line"> repeatedCount += other.repeatedCount;</div><div class="line"> zeroLength += other.zeroLength;</div><div class="line"> <span class="keywordflow">return</span> *<span class="keyword">this</span>;</div><div class="line"> }</div><div class="line">};</div><div class="line"></div><div class="line"><span class="comment">// Trivial analysis routine to pass its argument back in an IfCall so that we can use it</span></div><div class="line"><span class="comment">// to control the next piece of instrumentation.</span></div><div class="line"><span class="keyword">static</span> ADDRINT returnArg (BOOL arg)</div><div class="line">{</div><div class="line"> <span class="keywordflow">return</span> arg;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// Analysis functions for execution counts.</span></div><div class="line"><span class="comment">// Analysis routine, FirstRep and Executing tell us the properties of the execution.</span></div><div class="line"><span class="keyword">static</span> VOID addCount (UINT32 opIdx, UINT32 firstRep, UINT32 repCount)</div><div class="line">{</div><div class="line"> stats * s = &amp;statistics[opIdx];</div><div class="line"></div><div class="line"> s-&gt;add(firstRep, repCount);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// Instrumentation routines.</span></div><div class="line"><span class="comment">// Insert code for counting how many times the instruction is executed</span></div><div class="line"><span class="keyword">static</span> VOID insertRepExecutionCountInstrumentation (INS ins, UINT32 opIdx)</div><div class="line">{</div><div class="line"> <span class="keywordflow">if</span> (takesConditionalRep(opIdx))</div><div class="line"> {</div><div class="line"> <span class="comment">// We have no smart way to lessen the number of</span></div><div class="line"> <span class="comment">// instrumentation calls because we can&#39;t determine when</span></div><div class="line"> <span class="comment">// the conditional instruction will finish. So we just</span></div><div class="line"> <span class="comment">// let the instruction execute and have our</span></div><div class="line"> <span class="comment">// instrumentation be called on each iteration. This is</span></div><div class="line"> <span class="comment">// the simplest way of handling REP prefixed instructions, where</span></div><div class="line"> <span class="comment">// each iteration appears as a separate instruction, and</span></div><div class="line"> <span class="comment">// is independently instrumented.</span></div><div class="line"> <a class="code" href="group__INS__INST__API.html#ga74a956a0acde197043d04f4adcde4626">INS_InsertCall</a>(ins, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>, (AFUNPTR)addCount,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dabd19b79248899659441e56e4738d5bfd">IARG_UINT32</a>, opIdx,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da4e8c634973d6966dba21ff70455c1f5b">IARG_FIRST_REP_ITERATION</a>,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da5f291cb55a7d61a40fa3ab98e191394e">IARG_EXECUTING</a>,</div><div class="line"> IARG_END);</div><div class="line"> }</div><div class="line"> <span class="keywordflow">else</span></div><div class="line"> {</div><div class="line"> <span class="comment">// The number of iterations is determined solely by the count register value,</span></div><div class="line"> <span class="comment">// therefore we can log all we need at the start of each REP &quot;loop&quot;, and skip the</span></div><div class="line"> <span class="comment">// instrumentation on all the other iterations of the REP prefixed operation. Simply use</span></div><div class="line"> <span class="comment">// IF/THEN instrumentation which tests IARG_FIRST_REP_ITERATION.</span></div><div class="line"> <span class="comment">//</span></div><div class="line"> <a class="code" href="group__INS__INST__API.html#ga7907ad8ebd991b9e24df3b3b9cec4cac">INS_InsertIfCall</a>(ins, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>, (AFUNPTR)returnArg, <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da4e8c634973d6966dba21ff70455c1f5b">IARG_FIRST_REP_ITERATION</a>, IARG_END);</div><div class="line"> <a class="code" href="group__INS__INST__API.html#ga952b2b061d3fa8f1cc4d5d59fef53a69">INS_InsertThenCall</a>(ins, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>, (AFUNPTR)addCount,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dabd19b79248899659441e56e4738d5bfd">IARG_UINT32</a>, opIdx,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dabd19b79248899659441e56e4738d5bfd">IARG_UINT32</a>, 1,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dabe70796bf61230dac3ea1deaf4983c46">IARG_REG_VALUE</a>, <a class="code" href="group__INS__BASIC__API__IA32.html#ga8c243487db5a05e7410602ddd7087776">INS_RepCountRegister</a>(ins),</div><div class="line"> IARG_END);</div><div class="line"> }</div><div class="line">}</div></div><!-- fragment --><p>To perform this optimization when collecting memory access addresses, you will also need to worry about the state of EFLAGS.DF, since the string operations work from high address to low address when EFLAGS.DF==1.</p>
<p>Here is an example which shows how to handle that. </p><div class="fragment"><div class="line"><span class="comment">// Compute the base address of the whole access given the initial address,</span></div><div class="line"><span class="comment">// repeat count and element size. It has to adjust for DF if it is asserted.</span></div><div class="line"><span class="keyword">static</span> ADDRINT computeEA (ADDRINT firstEA, UINT32 eflags, UINT32 count, UINT32 elementSize)</div><div class="line">{</div><div class="line"> <span class="keyword">enum</span> {</div><div class="line"> DF_MASK = 0x0400</div><div class="line"> };</div><div class="line"></div><div class="line"> <span class="keywordflow">if</span> (eflags &amp; DF_MASK)</div><div class="line"> {</div><div class="line"> ADDRINT size = elementSize*count;</div><div class="line"></div><div class="line"> <span class="comment">// The string ops post-decrement, so the lowest address is one elementSize above</span></div><div class="line"> <span class="comment">// where you might think it should be.</span></div><div class="line"> <span class="keywordflow">return</span> firstEA - size + elementSize;</div><div class="line"> }</div><div class="line"> <span class="keywordflow">else</span></div><div class="line"> <span class="keywordflow">return</span> firstEA;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keyword">static</span> VOID logMemoryAddress (UINT32 op, <span class="comment">// Index of instruction</span></div><div class="line"> BOOL first, <span class="comment">// First iteration?</span></div><div class="line"> ADDRINT baseEA, <span class="comment">// Effective address being accessed on this iteration</span></div><div class="line"> ADDRINT count, <span class="comment">// Iteration count</span></div><div class="line"> UINT32 size, <span class="comment">// Size in bytes of the per-iteration access</span></div><div class="line"> UINT32 eflags, <span class="comment">// Eflags</span></div><div class="line"> ADDRINT tag) <span class="comment">// Name for the type of access</span></div><div class="line">{</div><div class="line"> <span class="keyword">const</span> <span class="keywordtype">char</span> * tagString = <span class="keyword">reinterpret_cast&lt;</span><span class="keyword">const </span><span class="keywordtype">char</span> *<span class="keyword">&gt;</span>(tag);</div><div class="line"> UINT32 width = 20;</div><div class="line"></div><div class="line"> <span class="keywordflow">if</span> (!first)</div><div class="line"> {</div><div class="line"> out &lt;&lt; <span class="stringliteral">&quot; &quot;</span>; <span class="comment">// Indent REP iterations</span></div><div class="line"> width -= 2;</div><div class="line"> }</div><div class="line"> out &lt;&lt; opcodes[op].name &lt;&lt; <span class="charliteral">&#39; &#39;</span> &lt;&lt; tagString &lt;&lt; <span class="charliteral">&#39; &#39;</span>;</div><div class="line"> out &lt;&lt; std::hex &lt;&lt; std::setw(width) &lt;&lt; computeEA(baseEA, eflags, count, size) &lt;&lt; <span class="charliteral">&#39;:&#39;</span>;</div><div class="line"> out &lt;&lt; std::dec &lt;&lt; std::setw(20) &lt;&lt; size*count &lt;&lt; endl;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// Insert instrumentation to log memory addresses accessed.</span></div><div class="line"><span class="keyword">static</span> VOID insertRepMemoryTraceInstrumentation(INS ins, UINT32 opIdx)</div><div class="line">{</div><div class="line"> <span class="keyword">const</span> opInfo * op = &amp;opcodes[opIdx];</div><div class="line"></div><div class="line"> <span class="keywordflow">if</span> (takesConditionalRep(opIdx))</div><div class="line"> {</div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__INS__BASIC__API__GEN__IA32.html#ga53406fedba9cbde8633a8da58c262e31">INS_IsMemoryRead</a>(ins))</div><div class="line"> {</div><div class="line"> <a class="code" href="group__INS__INST__API.html#ga74a956a0acde197043d04f4adcde4626">INS_InsertCall</a>(ins, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>, (AFUNPTR)logMemoryAddress,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dabd19b79248899659441e56e4738d5bfd">IARG_UINT32</a>, opIdx,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da4e8c634973d6966dba21ff70455c1f5b">IARG_FIRST_REP_ITERATION</a>,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da2138787daf04a57e6684eb0b368e120e">IARG_MEMORYREAD_EA</a>,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da5f291cb55a7d61a40fa3ab98e191394e">IARG_EXECUTING</a>,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dabd19b79248899659441e56e4738d5bfd">IARG_UINT32</a>, op-&gt;size,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dabd19b79248899659441e56e4738d5bfd">IARG_UINT32</a>, 0, <span class="comment">// Fake Eflags, since we&#39;re called at each iteration it doesn&#39;t matter</span></div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da34126f334d65afac69784351a03615ad">IARG_ADDRINT</a>, (ADDRINT)<span class="stringliteral">&quot;Read &quot;</span>,</div><div class="line"> IARG_END);</div><div class="line"> }</div><div class="line"> <span class="comment">// And similar code for MEMORYREAD2, MEMORYWRITE</span></div><div class="line"> }</div><div class="line"> <span class="keywordflow">else</span></div><div class="line"> {</div><div class="line"> <span class="keywordflow">if</span> (<a class="code" href="group__INS__BASIC__API__GEN__IA32.html#ga53406fedba9cbde8633a8da58c262e31">INS_IsMemoryRead</a>(ins))</div><div class="line"> {</div><div class="line"> <a class="code" href="group__INS__INST__API.html#ga7907ad8ebd991b9e24df3b3b9cec4cac">INS_InsertIfCall</a>(ins, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>, (AFUNPTR)returnArg, <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da4e8c634973d6966dba21ff70455c1f5b">IARG_FIRST_REP_ITERATION</a>, IARG_END);</div><div class="line"> <a class="code" href="group__INS__INST__API.html#ga952b2b061d3fa8f1cc4d5d59fef53a69">INS_InsertThenCall</a>(ins, <a class="code" href="group__INST__ARGS.html#gga707ea08e31f44f4a81e2a7766123bad7a7c7cbebb7a62a40e9f803b1db2e6ce20">IPOINT_BEFORE</a>, (AFUNPTR)logMemoryAddress,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dabd19b79248899659441e56e4738d5bfd">IARG_UINT32</a>, opIdx,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dacac3cb99011b351eeb3f675bc8c62b83">IARG_BOOL</a>, TRUE, <span class="comment">// First must be TRUE else we wouldn&#39;t be called</span></div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da2138787daf04a57e6684eb0b368e120e">IARG_MEMORYREAD_EA</a>,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dabe70796bf61230dac3ea1deaf4983c46">IARG_REG_VALUE</a>, <a class="code" href="group__INS__BASIC__API__IA32.html#ga8c243487db5a05e7410602ddd7087776">INS_RepCountRegister</a>(ins),</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dabd19b79248899659441e56e4738d5bfd">IARG_UINT32</a>, op-&gt;size,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451dabe70796bf61230dac3ea1deaf4983c46">IARG_REG_VALUE</a>, REG_EFLAGS,</div><div class="line"> <a class="code" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da34126f334d65afac69784351a03615ad">IARG_ADDRINT</a>, (ADDRINT)<span class="stringliteral">&quot;Read &quot;</span>,</div><div class="line"> IARG_END);</div><div class="line"> }</div><div class="line"> <span class="comment">// And similar code for MEMORYREAD2, MEMORYWRITE</span></div><div class="line"> }</div><div class="line">}</div></div><!-- fragment --><p>Since there are real codes where a significant proportion of all instructions are REP prefixed, using <a class="el" href="group__INST__ARGS.html#gga089c27ca15e9ff139dd3a3f8a6f8451da4e8c634973d6966dba21ff70455c1f5b">IARG_FIRST_REP_ITERATION</a> to collect information at the beginning of the REP "loop" while skipping it for the later iterations can be a significant optimization.</p>
<p>A tool which demonstrates all of these techniques can be found in source/tools/ManualExamples/countreps.cpp, from which these (slightly edited) code snippets were taken.</p>
<p><br />
</p><hr/>
<h1><a class="anchor" id="MEMORY"></a>
Memory management</h1>
<hr/>
<h2><a class="anchor" id="Pin"></a>
Pin</h2>
<p>Pin allows the Pintool to dynamically allocate memory (e.g. using malloc()) without interfering with the execution of the application that is run under Pin. In order to achieve this, Pin implements its own memory allocator which is separate from the application's memory allocator, and allocates memory in different memory regions.</p>
<h2><a class="anchor" id="Restrict"></a>
Pin's dynamic memory allocation regions</h2>
<p>By default, the memory address region used by Pin to dynamically allocate memory for both Pin usage and Pintool usage is unrestricted. However, if Pin memory allocation should be restricted to specific memory regions, the -pin_memory-range knob can be used in Pin's command line to make Pin allocate memory only inside the specified regions. Note that restricting Pin memory allocation to specific regions doesn't mean that it will allocate/reserve the entire memory available those regions!</p>
<h2><a class="anchor" id="Limit"></a>
the maximum memory that Pin can allocate</h2>
<p>Pin can be forced to limit the amount of memory it can allocate (in bytes) by using the -pin_memory_size knob in Pin's command line. When a Pintool cannot allocate more memory due to -pin_memory_size limitation, its out of memory callback is called (see <a class="el" href="group__PIN__CONTROL.html#ga897b98855a1853146f9d291687f41946">PIN_AddOutOfMemoryFunction()</a>). By default, the number of bytes that Pin can allocate is unlimited. We recommend that if a memory limitation is specified, it will be at least 30MB.</p>
<h2><a class="anchor" id="JIT"></a>
mode</h2>
<p>In JIT mode, Pin needs to manage memory for the code cache in addition to the dynamically allocated memory. This means that the memory regions specified by -pin_memory-range restricts both the dynamically allocated memory and the code cache blocks allocated by Pin.</p>
<p>In order to limit the code cache memory allocation, one can specify the -cc_memory_size knob in Pin's command line. Note that the specified limit must be a multiple of the code cache block size (specified with -cache_block_size).</p>
<h2><a class="anchor" id="Pin"></a>
Pin</h2>
<p>Another component that requires memory while running Pin on an application is the images of Pin, tool, and their shared libraries (aka dynamic link libraries).</p>
<p>In order to restrict the memory that Pin image loader will use when placing the images mentioned above, one can use the -restrict_memory knob in Pin's command line. This will specify memory regions that the Pin loader should not use. Note that the logic of the -restrict_memory knob is reversed from all the other memory range knobs for Pin - as it specifies which memory regions the Pin loader should <em>NOT</em> use.</p>
<p><br />
</p><hr/>
<h1><a class="anchor" id="RESTRICTIONS"></a>
Pintool Information and Restrictions</h1>
<hr/>
<h2><a class="anchor" id="PinCRT"></a>
PinCRT</h2>
<p>Pin is built and distributed with its own OS-agnostic, compiler-agnostic runtime, named PinCRT. PinCRT exposes three layers of generic APIs which practically eliminate Pin's and the tools' dependency on the host system:</p><ul>
<li>A generic operating system interface, supplying basic OS services such as process control, thread control etc.</li>
<li>A C-runtime layer supplying a standard C implementation. This is complemented by compiler-runtime functions necessary for enabling gcc, msvc, clang and icc.</li>
<li>A C++ runtime. Please note that the current version does not support C++11 and RTTI (Run-Time Type Information).</li>
</ul>
<p>Tools are obliged to use (link with) PinCRT instead of any system runtime. Tools must refrain from using any native system calls, and use PinCRT APIs for any needed functionality. Note that PinCRT APIs may differ from the native system APIs. For additional information see the OS APIs user guide in extras/crt/docs/html and the PinCRT documentation at <a href="https://software.intel.com/sites/default/files/managed/8e/f5/PinCRT.pdf">https://software.intel.com/sites/default/files/managed/8e/f5/PinCRT.pdf</a></p>
<h2><a class="anchor" id="General"></a>
General</h2>
<p>Tools are restricted from linking with any system libraries and/or calling any system calls. See <a class="el" href="index.html#PinCRT">PinCRT</a> for more information.</p>
<p>There are several things that a Pintool writer must be aware of.</p><ul>
<li>IARG_REG_VALUE cannot be used to pass floating point register values to an analysis routine.</li>
<li>Also, see the OS-specific restrictions below. <a class="el" href="index.html#WINDOWS_OS">Windows OS</a> or <a class="el" href="index.html#LINUX_OS">Linux OS</a></li>
</ul>
<p>Often, a Pintool writer wants to run the SPEC benchmarks to see the results of their research. There are many ways one can update the scripts to invoke Pin on the SPEC tests; this is one. In your $SPEC/config file, add the following two lines:</p>
<div class="fragment"><div class="line">submit=$PIN_HOME/intel64/bin/pin -t /my/pin/tool -- $command</div><div class="line">use_submit_for_speed=yes</div></div><!-- fragment --><p>Now the SPEC harness will automatically run Pin with whatever benchmarks it runs. Note that you need the full path name for Pin and Pintool binaries. Replace "intel64" with "ia32" if you are using a 32-bit system.</p>
<h2><a class="anchor" id="LINUX_OS"></a>
Linux OS</h2>
<p>Pin identifies system calls at the actual system call trap instruction, not the libc function call wrapper. Tools need to be aware of oddities like this when interpreting system call arguments, etc.</p>
<h2><a class="anchor" id="WINDOWS_OS"></a>
Windows OS</h2>
<p>Tool are restricted from calling any win32 APIs. All system interaction should go through PinCRT.</p>
<p>Pin on Windows separates DLLs loaded by the tool from the application DLLs - it makes separate copies of any DLL loaded by Pin and Pintool using the PinCRT loader. Separate copies of system DLLs are not supported by the OS. In order to avoid isolation problems, Pintool should not dynamically load any system DLL. For the same reason, Pintool should avoid static links to any system DLL.</p>
<p>In probe mode, the application runs natively, and the probe is placed in the original code. If a tool replaces a function shared by the tool and the application, an undesirable behavior may occur. For example, if a tool replaces EnterCriticalSection() with an analysis routine that calls printf(), this could result in an infinite loop, because printf() can also call EnterCriticalSection(). The application would call EnterCriticalSection(), and the control flow would go to the replacement routine, and it would call EnterCriticalSection() (via printf) which would call the replacement routine, and so on.</p>
<h2><a class="anchor" id="MACOS_OS"></a>
macOS OS</h2>
<p>Note that if SIP (System integrity Protection) is an enabled on the machine then Pin will not be able to run system files. The only way to run system files will be to disable SIP on that machine. More information about SIP and how to disable it can be found online.</p>
<h2><a class="anchor" id="namespace"></a>
Conflicts between Pin and Windows</h2>
<p>Pin uses some base types that conflict with Windows types. If you use "windows.h", you may see compilation errors. To avoid this problem, we recommend wrapping the windows.h file as follows. Items that reside in the windows.h file must be referenced using the WINDOWS:: prefix.</p>
<div class="fragment"><div class="line"><span class="keyword">namespace </span>WINDOWS</div><div class="line">{</div><div class="line"><span class="preprocessor">#include &lt;windows.h&gt;</span></div><div class="line">}</div></div><!-- fragment --><p><br />
</p><hr/>
<h1><a class="anchor" id="WINDOWS_TOOLS"></a>
Building Tools on windows</h1>
<hr/>
<h2><a class="anchor" id="building"></a>
Building Tools in Visual Studio</h2>
<p>An example VS project that builds Pintool in the Visual Studio IDE can be found in the directory. Enter this directory and open the project or solution file. To build the tool, select "Build Solution".</p>
<p>To run an application, instrumented by MyPinTool, select Tool-&gt;External Tools. In the "Menu contents" window choose "run pin". Add to the "Arguments" box the path of the required application that you want to run with Pin. For example: -t MyPinTool.dll -count 1 &ndash; "C:\Users\..\my_app.exe" and select "OK". A Popup window may appear on the screen with the following message: "The command is not a valid executable. Would you like to change the command?" select "No". To start running your application select Tool-&gt;pin run.</p>
<p>You can select another application and change tool's switches in the "MyPinTool Properties-&gt;Debugging" page.</p>
<p>You can use MyPinTool as a template for your own project. Please, look carefully at the compilation and linking switches in the MyPinTool property pages. Mandatory switches can be found in the win.vars file in the kit's source/tools/Config directory. Also note the library order, as this is important, too. See <a class="el" href="index.html#MAKEFILES">Pin's makefile Infrastructure</a> for further details.</p>
<h2><a class="anchor" id="multi"></a>
Constructing PinTools from multiple DLLs on Windows</h2>
<p>A Pintool can be composed from multiple DLLs:</p><ul>
<li>"main DLL", which is specified in the Pin command line after "-t" switch</li>
<li>a number of "secondary DLLs", linked to the "main DLL" statically.</li>
</ul>
<p>When considering this configuration, take into account that multi-DLL Pin tool may increase memory fragmentation and cause layout conflicts with application images. If there is no compelling reasons for using multiple DLLs, build your tool as a single DLL to reduce the risk of memory conflicts.</p>
<p>Limitations and instructions:</p><ul>
<li>Don't use any Pin API in "secondary DLLs". Only "main DLL" can use Pin API!</li>
<li>In order to run Pintool put "main DLL" and its "secondary DLLs" in the same directory.</li>
<li>IMPORTANT: Build each DLL with the recommended Pintool building flags (see <a class="el" href="index.html#building">Building Tools in Visual Studio</a>).</li>
<li>Remove /EXPORT:main link flag for "secondary DLLs".</li>
<li>Specify different base address for each DLL (/BASE link flag). When choosing base addresses, try to minimize memory fragmentation and layout conflicts.</li>
</ul>
<h2><a class="anchor" id="supported"></a>
Supported executables</h2>
<p>Pin can instrument Windows* subsystem executables.<br />
It can't instrument other executables (such as MS-DOS, Win16 or a POSIX subsystem executables).</p>
<p><br />
</p><hr/>
<h1><a class="anchor" id="WINLIBRARIES"></a>
Libraries for Windows</h1>
<hr/>
<p>Pin on Windows uses dbghelp.dll by Microsoft* to provide symbolic information. dbghelp.dll version 6.11.1.404 is distributed with the kit. Please use the provided version, as other versions may not work properly with Pin.</p>
<p><br />
</p><hr/>
<h1><a class="anchor" id="LIBRARIES"></a>
Libraries for Linux</h1>
<hr/>
<h2><a class="anchor" id="PIN_LAUNCHER"></a>
The "pin" Executable (Launcher)</h2>
<p>The kit's root directory contains a "pin" executable. This is a 32-bit launcher, used for launching Pin in 32 and 64 bit modes. The launcher sets up the environment to find the libraries supplied with the kit. The kit's runtime directories will be searched first, followed by directories that are on the LD_LIBRARY_PATH. The launcher will then invoke the actual Pin executable - "pinbin".</p>
<p>If you need to change the directory structure or copy pin to a different directory, then you should note the following. The "pin" launcher expects the binary "pinbin" to be in the architecture-specific "bin" subdirectory (e.g. ia32/bin). The launcher expects the libraries to be found in the architecture-specific "runtime" and subdirectory (i.e. ia32/runtime). If you need a different directory structure, you need to build your own launcher or find a different way to set up the environment to allow the pinbin executable to find the necessary runtime libraries. The pinbin binary itself makes no assumptions about the directory structure. The launcher's sources may be found in &lt;kit root&gt;=""&gt;/source/launcher.</p>
<p><br />
</p><hr/>
<h1><a class="anchor" id="INSTALLATION"></a>
Installing Pin</h1>
<hr/>
<p>To install a kit, unpack a kit and change to the directory.</p>
<p>Linux / macOS*: </p><pre class="fragment">$ tar zxf pin-3.2-81205-gcc-linux.tar.gz
$ cd pin-3.2-81205-gcc-linux
</pre><p> Use the macOS* kit names respectively.</p>
<p>Windows: Unzip the installation files, extracting all files in the kit. </p><pre class="fragment">$ cd pin-3.2-81205-msvc-windows
</pre><p>For better security, be advised to install on secure location.</p>
<p><br />
</p><hr/>
<h1><a class="anchor" id="BUILDINGTOOLS"></a>
Building Your Own Tool</h1>
<hr/>
<p>Table of Contents</p><ul>
<li><a class="el" href="index.html#BuildingInsideKit">Building a Tool From Within the Kit Directory Tree</a></li>
<li><a class="el" href="index.html#BuildingOutOfKit">Building a Tool Out of the Kit Directory Tree</a></li>
</ul>
<p>To write your own tool, copy one of the example directories and edit the makefile.rules file to add your tool. The sample tool MyPinTool is recommended. This tool allows you to build either inside or outside the kit directory tree. See <a class="el" href="index.html#AddingTests">Adding Tests, Tools and Applications to the makefile</a> and <a class="el" href="index.html#DefiningbuildRules">Defining Build Rules for Tools and Applications</a> for further details on makefile modification.</p>
<h2><a class="anchor" id="BuildingInsideKit"></a>
Building a Tool From Within the Kit Directory Tree</h2>
<p>You may either modify MyPinTool or copy it as directed above. If you're using MyPinTool, and the default build rule suffices, you may not have to change makefile.rules. If you are adding a new tool, or you require special build flags for your tool, you will need to modify the makefile.rules file to add your tool and/or specify a customized build rule.</p>
<p>Building YourTool.so (from YourTool.cpp): </p><pre class="fragment">make obj-intel64/YourTool.so
</pre><p> For the IA-32 architecture, use "obj-ia32" instead of "obj-intel64". See for commonly used make flags to add to your build.</p>
<h2><a class="anchor" id="BuildingOutOfKit"></a>
Building a Tool Out of the Kit Directory Tree</h2>
<p>Copy the MyPinTool directory to a place of your choosing. This directory will serve as a basis for your tool. Modify the makefile.rules file to add your tool and/or specify a customized build rule.</p>
<p>Building YourTool.so (from YourTool.cpp): </p><pre class="fragment">make PIN_ROOT=&lt;path to Pin kit&gt; obj-intel64/YourTool.so
</pre><p> For the IA-32 architecture, use "obj-ia32" instead of "obj-intel64". See for commonly used make flags to add to your build.</p>
<p>For changing the directory where the tool will be created, override the OBJDIR variable from the command line: </p><pre class="fragment">make PIN_ROOT=&lt;path to Pin kit&gt; OBJDIR=&lt;path to output dir&gt; &lt;path to output dir&gt;/YourTool.so
</pre><p><br />
</p><hr/>
<h1><a class="anchor" id="MAKEFILES"></a>
Pin's makefile Infrastructure</h1>
<hr/>
<p>Table of Contents</p><ul>
<li><a class="el" href="index.html#MakefileUsage">Using Pin's makefile Infrastructure</a></li>
<li><a class="el" href="index.html#ConfigDirectory">The Config Directory</a></li>
<li><a class="el" href="index.html#TestDirectories">The Test Directories</a></li>
<li><a class="el" href="index.html#AddingTests">Adding Tests, Tools and Applications to the makefile</a></li>
<li><a class="el" href="index.html#DefiningbuildRules">Defining Build Rules for Tools and Applications</a></li>
<li><a class="el" href="index.html#DefiningTestRecipes">Defining Test Recipes in makefile.rules</a></li>
<li><a class="el" href="index.html#UsefulVariables">Useful make Variables and Flags</a></li>
</ul>
<h2><a class="anchor" id="MakefileUsage"></a>
Using Pin's makefile Infrastructure</h2>
<p>Pintools are built using make on all target platforms. This section describes the basic flags available in Pin's makefile infrastructure. This is not a makefile tutorial. For general information about makefiles, refer to the makefile manual available at <em><a href="http://www.gnu.org/software/make/manual/make.html">http://www.gnu.org/software/make/manual/make.html</a></em>.</p>
<h2><a class="anchor" id="ConfigDirectory"></a>
The Config Directory</h2>
<p>The source/tools/Config directory holds the common make configuration files which should not be changed and template files which may serve as a basis for your own makefiles. This sections gives a short overview of the most notable files in the directory. The experienced user is welcome to read through the complete set of configuration files for better understanding the tools' build process.</p>
<p><code>makefile.config</code>: This is the first file to be included in the make include chain. It holds documentation of all the relevant flags and variables available to users, both within the makefile and from the command shell. Also, this file includes the OS-specific configuration files.</p>
<p><code>makefile.unix.config</code>: This file holds the Unix definitions of the makefile variables. See <code>makefile.win.config</code> for the Windows definitions.</p>
<p><code>unix.vars</code>: This file holds the Unix definitions of some architectural variables and utilities used by the makefiles. See <code>win.vars</code> for the Windows definitions.</p>
<p><code>makefile.default.rules</code>: This file holds the default make targets, test recipes and build rules.</p>
<h2><a class="anchor" id="TestDirectories"></a>
The Test Directories</h2>
<p>Each test directory in source/tools/ contains two files in the makefile chain.</p>
<p><code>makefile</code>: This is the makefile which will be invoked when running make. This file should not be changed. It holds the include directives for all the relevant configuration files of the makefile chain in the correct order. Changing this order may result in unexpected behavior. This is a generic file, it is identical in all test directories.</p>
<p><code>makefile.rules</code>: This is the directory-specific makefile. It holds the logic of the current directory. All tools, applications and tests that should be built and run in a directory are defined in this file. See <a class="el" href="index.html#AddingTests">Adding Tests, Tools and Applications to the makefile</a> for adding tests, tools and applications to makefile.rules.</p>
<h2><a class="anchor" id="AddingTests"></a>
Adding Tests, Tools and Applications to the makefile</h2>
<p>This section describes how to define your applications, tools and tests in the makefile. The sections below describe how to build the binaries and how to run the tests.</p>
<p>The variables detailed below, hold the tests, applications and tools definitions. They are defined in the "Test targets" section of makefile.rules. See this section for additional variables and more detailed documentation for each variable.</p>
<p><code>TOOL_ROOTS</code>: Define the name of your tool here, without the file extension. The correct extension, according to the OS, will be added automatically by make. For example, for adding YourTool.so: </p><pre class="fragment">TOOL_ROOTS := YourTool
</pre><p><code>APP_ROOTS</code>: Define your application here, without the file extension. The correct extension according to the OS, will be added automatically by make. For example, for adding YourApp.exe: </p><pre class="fragment">APP_ROOTS := YourApp
</pre><p><code>TEST_ROOTS</code>: Define your tests here without the .test suffix. This suffix will be added automatically by make. For example, for adding YourTest.test: </p><pre class="fragment">TEST_ROOTS := YourTest
</pre><h2><a class="anchor" id="DefiningbuildRules"></a>
Defining Build Rules for Tools and Applications</h2>
<p>Default build rules for tools and applications are defined in source/tools/Config/makefile.default.rules. The default tool requires a single c/cpp source file and will generate a tool of the same name. For example, for YourTool.cpp make will generate YourTool.so with the default build rule. However, if your tool requires more than one source file, or you need a customized build rule, add your rule at the bottom of makefile.rules in the "Build rules" section". There is no need to add the $(OBJDIR) dependency to the build rule, it will be added automatically. This dependency creates the build output directory obj-intel64 (or obj-ia32 for the IA-32 architecture). See source/tools/Config/makefile.config for all available compilation and link flags.</p>
<p>Here are a few useful examples:</p>
<p>Building an unoptimized tool from a single source: </p><pre class="fragment"># Build the intermediate object file.
$(OBJDIR)YourTool$(OBJ_SUFFIX): YourTool.cpp
$(CXX) $(TOOL_CXXFLAGS_NOOPT) $(COMP_OBJ)$@ $&lt;
# Build the tool as a dll (shared object).
$(OBJDIR)YourTool$(PINTOOL_SUFFIX): $(OBJDIR)YourTool$(OBJ_SUFFIX)
$(LINKER) $(TOOL_LDFLAGS_NOOPT) $(LINK_EXE)$@ $&lt; $(TOOL_LPATHS) $(TOOL_LIBS)
</pre><p>Building an optimized tool from several source files: </p><pre class="fragment"># Build the intermediate object file.
$(OBJDIR)Source1$(OBJ_SUFFIX): Source1.cpp
$(CXX) $(TOOL_CXXFLAGS) $(COMP_OBJ)$@ $&lt;
# Build the intermediate object file.
$(OBJDIR)Source2$(OBJ_SUFFIX): Source2.c Source2.h
$(CC) $(TOOL_CXXFLAGS) $(COMP_OBJ)$@ $&lt;
# Build the tool as a dll (shared object).
$(OBJDIR)YourTool$(PINTOOL_SUFFIX): $(OBJDIR)Source1$(OBJ_SUFFIX) $(OBJDIR)Source2$(OBJ_SUFFIX) Source2.h
$(LINKER) $(TOOL_LDFLAGS_NOOPT) $(LINK_EXE)$@ $(^:%.h=) $(TOOL_LPATHS) $(TOOL_LIBS)
</pre><h2><a class="anchor" id="DefiningTestRecipes"></a>
Defining Test Recipes in makefile.rules</h2>
<p>A default test recipe is defined in source/tools/Config/makefile.default.rules. For most users, this recipe is insufficient. You may specify your own test recipes in makefile.rules in the "Test recipes" section. There is no need to add the $(OBJDIR) dependency to the build rule, it will be added automatically. This dependency creates the build output directory obj-intel64 (or obj-ia32 for the IA-32 architecture).</p>
<p>Example: </p><pre class="fragment">YourTest.test: $(OBJDIR)YourTool$(PINTOOL_SUFFIX) $(OBJDIR)YourApp$(EXE_SUFFIX)
$(PIN) -t $&lt; -- $(OBJDIR)YourApp$(EXE_SUFFIX)
</pre><h2><a class="anchor" id="UsefulVariables"></a>
Useful make Variables and Flags</h2>
<p>For a complete list of all the available variables and flags, see source/tools/Config/makefile.config . Here is a short list of the most useful flags: <br />
<code>PIN_ROOT</code>: Specify the location for the Pin kit when building a tool outside of the kit. <br />
<code>CC</code>: Override the default c compiler for tools. <br />
<code>CXX</code>: Override the default c++ compiler for tools <br />
<code>APP_CC</code>: Override the default c compiler for applications. If not defined, APP_CC will be the same as CC. <br />
<code>APP_CXX</code>: Override the default c++ compiler for applications. If not defined, APP_CXX will be the same as CXX. <br />
<code>TARGET</code>: Override the default target architecture e.g. for cross-compilation. <br />
<code>ICC</code>: Specify ICC=1 when building tools with the Intel Compiler. <br />
<code>DEBUG</code>: When DEBUG=1 is specified, debug information will be generated when building tools and applications. Also, no compilation and/or link optimizations will be performed.</p>
<p><br />
</p><hr/>
<h1><a class="anchor" id="FEEDBACK"></a>
Questions? Bugs?</h1>
<hr/>
<p>Send bugs and questions at <a href="https://groups.io/g/pinheads">https://groups.io/g/pinheads</a>. Complete bug reports that are easy to reproduce are fixed faster, so try to provide as much information as possible. Include: kit number, your OS version, compiler version. Try to reproduce the problem in a simple example that you can send us.</p>
<p><br />
</p><hr/>
<h1><a class="anchor" id="LEGAL"></a>
Disclaimer and Legal Information</h1>
<hr/>
<p>The information in this manual is subject to change without notice and Intel Corporation assumes no responsibility or liability for any errors or inaccuracies that may appear in this document or any software that may be provided in association with this document. This document and the software described in it are furnished under license and may only be used or copied in accordance with the terms of the license. No license, express or implied, by estoppel or otherwise, to any intellectual property rights is granted by this document. The information in this document is provided in connection with Intel products and should not be construed as a commitment by Intel Corporation.</p>
<p>EXCEPT AS PROVIDED IN INTEL'S TERMS AND CONDITIONS OF SALE FOR SUCH PRODUCTS, INTEL ASSUMES NO LIABILITY WHATSOEVER, AND INTEL DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY, RELATING TO SALE AND/OR USE OF INTEL PRODUCTS INCLUDING LIABILITY OR WARRANTIES RELATING TO FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR INFRINGEMENT OF ANY PATENT, COPYRIGHT OR OTHER INTELLECTUAL PROPERTY RIGHT. Intel products are not intended for use in medical, life saving, life sustaining, critical control or safety systems, or in nuclear facility applications.</p>
<p>Designers must not rely on the absence or characteristics of any features or instructions marked "reserved" or "undefined." Intel reserves these for future definition and shall have no responsibility whatsoever for conflicts or incompatibilities arising from future changes to them.</p>
<p>The software described in this document may contain software defects which may cause the product to deviate from published specifications. Current characterized software defects are available on request.</p>
<p>Intel, Xeon, and Intel Xeon Phi are trademarks of Intel Corporation in the U.S. and/or other countries.</p>
<p>Microsoft, Windows, and the Windows logo are trademarks, or registered trademarks of Microsoft Corporation in the United States and/or other countries.</p>
<p>Java is a registered trademark of Oracle and/or its affiliates.</p>
<p>Other names and brands may be claimed as the property of others.</p>
<p>Copyright 2004-2019 Intel Corporation.</p>
<p>Intel Corporation, 2200 Mission College Blvd., Santa Clara, CA 95052-8119, USA.</p>
<hr/>
</div></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.13
</small></address>
</body>
</html>