|
| enum | {
TLS_KEY_INTERNAL_EXCEPTION
,
TLS_KEY_CLIENT_FIRST
,
TLS_KEY_CLIENT_LAST = TLS_KEY_CLIENT_FIRST + 63
} |
| |
A group of Pin threading primitives. These APIs are available in any thread, including any internal thread spawned by the tool. They allows the user to stop all application threads, examine and modify their state and then resume them. It is available in analysis routines and internal threads
◆ OS_PROCESS_ID
Process ID assigned by OS.
◆ OS_THREAD_ID
Thread ID assigned by PINOS (Pin's Operating System abstraction layer).
◆ PIN_THREAD_UID
Unique thread ID which, unlike THREADID identifier, is not reused by Pin after the thread termination. The uniqueness of this identifier allows to use it in the PIN_WaitForThreadTermination() function which monitors the thread's state.
◆ ROOT_THREAD_FUNC
| typedef VOID ROOT_THREAD_FUNC(VOID *arg) |
Main (starting) function of a thread.
- Parameters
-
| [in] | arg | argument of the main thread function, as specified by the thread creator. |
◆ THREADID
Thread ID assigned by PIN.
◆ TLS_KEY
Type that represents TLS key - a unique identifier of a slot in the thread local storage.
◆ anonymous enum
Keys to access client data in the thread local storage
◆ PIN_CreateThreadDataKey()
| TLS_KEY PIN_CreateThreadDataKey |
( |
DESTRUCTFUN |
destruct_func | ) |
|
|
extern |
Allocate a new TLS key and associate it with a given data destruction function. Upon successful return, any thread of the process can use PIN_SetThreadData() and PIN_GetThreadData() functions to 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. At the thread exit, if a key has a non-NULL pointer to the cleanup (destruction) function, and the thread has a non-NULL value in the corresponding slot, the function is called with the slot's value as its sole argument. The order in which destructors are invoked is undefined.
- Parameters
-
| [in] | destructFun | optional parameter that specifies data destruction function to be associated with the new key. This function is called just after notifying the client about VM thread exit. By default (NULL destructor), the data is not cleaned up. |
- Returns
- allocated TLS key, upon success; -1, if number of already allocated keys reached the MAX_CLIENT_TLS_KEYS limit.
- Availability:
- Mode: JIT
O/S: Linux, Windows
CPU: All
◆ PIN_DeleteThreadDataKey()
| BOOL PIN_DeleteThreadDataKey |
( |
TLS_KEY |
key | ) |
|
|
extern |
Release TLS key, allocated by a previous call to the PIN_CreateThreadDataKey() function. The function has no effect if specified key is not allocated/already released. After the key is released, a client should not attempt to use it for any further TLS access. Doing otherwise results in undefined behavior.
- Parameters
-
| [in] | key | TLS key to be released |
- Returns
- TRUE, upon success; FALSE, if if specified key is invalid
- Availability:
- Mode: JIT
O/S: Linux, Windows
CPU: All
◆ PIN_ExitThread()
| VOID PIN_ExitThread |
( |
INT32 |
exitCode | ) |
|
|
extern |
Terminate the current thread.
This function is intended for threads created by the tool (see PIN_SpawnInternalThread()) and is not normally used for threads created by the application, since application threads exit automatically when Pin executes a thread termination system call on their behalf.
If this call is made on an application thread, Pin will make any callbacks registered for thread exit before the thread is terminated.
- Parameters
-
- Returns
- the function never returns.
- Note
- The vm lock is obtained during the call of this API.
- Availability:
- Mode: JIT & Probe
O/S: Linux, Windows
CPU: All
◆ PIN_GetNativeTid()
| NATIVE_TID PIN_GetNativeTid |
( |
| ) |
|
|
extern |
Get native OS identifier of the current thread.
- Returns
- native OS ID of the current thread.
- Availability:
- Mode: JIT & Probe
O/S: Linux, Windows
CPU: All
◆ PIN_GetNativeTidFromSysTid()
| NATIVE_TID PIN_GetNativeTidFromSysTid |
( |
OS_THREAD_ID |
sysThreadId | ) |
|
|
extern |
Get native OS identifier from a system thread id.
- Parameters
-
- Returns
- native OS ID of for the given system thread id.
- Availability:
- Mode: JIT & Probe
O/S: Linux, Windows
CPU: All
◆ PIN_GetNativeTidFromThreadId()
| NATIVE_TID PIN_GetNativeTidFromThreadId |
( |
THREADID |
tid | ) |
|
|
extern |
Get native OS identifier from Pin's internal thread id.
- Parameters
-
- Returns
- native OS ID for the given thread id.
- Availability:
- Mode: JIT & Probe
O/S: Linux, Windows
CPU: All
◆ PIN_GetParentTid()
Get system identifier of the parent thread, if known.
- Returns
- system ID of the parent thread or INVALID_OS_THREAD_ID if the parent thread is unknown. For internal threads this function always returns INVALID_OS_THREAD_ID. On Windows the result is always INVALID_OS_THREAD_ID, since there is, in general, no well defined parent child relationship between threads.
- Availability:
- Mode: JIT
O/S: Linux, Windows
CPU: All
◆ PIN_GetStoppedThreadContext()
This function returns the CONTEXT (register state) of a stopped application thread. The caller can inspect the stopped thread's register state via PIN_GetContextReg() and related API's.
- Parameters
-
| [in] | tid | Pin ID of a stopped thread. |
- Returns
- The CONTEXT for thread tid or NULL if that thread is not stopped.
- Availability:
- Mode: JIT
O/S: Linux, Windows
CPU: IA-32 and Intel(R) 64 architectures
◆ PIN_GetStoppedThreadCount()
| UINT32 PIN_GetStoppedThreadCount |
( |
| ) |
|
|
extern |
This function can be called in two scenarios. First, it may be called after stopping threads with PIN_StopApplicationThreads(), in which case it tells the number of application threads that were stopped with that API.
Alternatively, this function may be called from a call-back that is registered via PIN_AddDebugInterpreter(). In this case, it tells the number of application threads that are stopped in the debugger.
- Returns
- The number of stopped application threads. Returns zero if threads are not currently stopped.
- Availability:
- Mode: JIT
O/S: Linux, Windows
CPU: IA-32 and Intel(R) 64 architectures
◆ PIN_GetStoppedThreadId()
| THREADID PIN_GetStoppedThreadId |
( |
UINT32 |
i | ) |
|
|
extern |
This function returns the Pin thread ID of a stopped application thread.
- Parameters
-
- Returns
- The ID of the indexed thread, which is currently stopped. Returns INVALID_THREADID if i is out of range.
- Availability:
- Mode: JIT
O/S: Linux, Windows
CPU: IA-32 and Intel(R) 64 architectures
◆ PIN_GetStoppedThreadWriteableContext()
This function is similar to PIN_GetStoppedThreadContext(), but it returns a CONTEXT that may be modified. The caller may modify the stopped thread's register state via PIN_SetContextReg() and related API's. The stopped thread uses the new register state when it resumes.
- Parameters
-
| [in] | tid | Pin ID of a stopped thread. |
- Returns
- The CONTEXT for thread tid or NULL if that thread is not stopped.
- Availability:
- Mode: JIT
O/S: Linux, Windows
CPU: IA-32 and Intel(R) 64 architectures
◆ PIN_GetThreadData()
Get the value stored in the specified TLS slot of the thread.
- Parameters
-
| [in] | key | TLS key, referencing the slot, whose value is requested. The key should be allocated by a previous call to the PIN_CreateThreadDataKey() function. |
| [in] | threadId | Thread ID assigned by pin of the thread for which TLS access is desired, not necessarily the current thread. This ID can be obtained by the PIN_ThreadId() function call or received as the value of the IARG_THREAD_ID argument. |
- Returns
- value stored in the specified slot of the thread, if specified key is currently allocated; NULL, if specified key is invalid or the given thread is not yet registered in the pin thread database; undefined, if specified key is valid, but it is not currently allocated
- Availability:
- Mode: JIT
O/S: Linux, Windows
CPU: All
◆ PIN_GetTid()
Threading API for clients
Get system identifier of the current thread.
- Note
- The System thread id is not the underlying OS tid. To get the underlying OS tid please use PIN_GetNativeTid().
- Returns
- system ID of the current thread.
- Availability:
- Mode: JIT & Probe
O/S: Linux, Windows
CPU: All
◆ PIN_InitializeInternalThread()
| VOID PIN_InitializeInternalThread |
( |
| ) |
|
|
extern |
Perform initialization required for a thread created using std::thread/pthread_create to work properly with pin API. Among other things this function allocates Pin fast TLS for the thread and blocks asynchronous signals for the thread.
Pin 4.x allows a pintool writers to use std::thread and pthreads to create and manage threads. However using the standard API circumvents initialization done by PIN_SpawInternalThread. To be able to properly and safely use PIN API from the new thread one should call PIN_InitializeInternalThread at the begining of the thread function. To properly release resources allocated by this function, the thread should exit using PIN_ExitThread. It is reccomended that the thread function/procedure that is used for std::thread/pthreead_create has the following structure:
{
...
}
VOID PIN_InitializeInternalThread()
Perform initialization required for a thread created using std::thread/pthread_create to work properl...
VOID PIN_ExitThread(INT32 exitCode)
- Returns
- VOID
- Availability:
- Mode: JIT & Probe
O/S: Linux, Windows
CPU: All
◆ PIN_IsApplicationThread()
| BOOL PIN_IsApplicationThread |
( |
| ) |
|
|
extern |
Check to see if the current thread is created by the application or it is an internal thread spawned by the tool or Pin itself (see PIN_SpawnInternalThread()).
- Returns
- TRUE, if this function is called in a thread created by the application; FALSE, if this function is called in an internal thread spawned by the tool or Pin.
- Availability:
- Mode: JIT
O/S: Linux, Windows
CPU: All
◆ PIN_IsThreadStoppedInDebugger()
| BOOL PIN_IsThreadStoppedInDebugger |
( |
THREADID |
tid | ) |
|
|
extern |
This function returns true if the thread with denoted by 'tid' given by its arguments was stopped in the debugger. Note: If there is no thread with ID 'tid', this function returns false.
- Parameters
-
| [in] | tid | The Pin thread ID to check |
- Returns
- TRUE if the specified thread was stopped in the debugger. FALSE indicates that the thread is either running, or doesn't exist
- Availability:
- Mode: JIT
O/S: Linux, Windows
CPU: IA-32 and Intel(R) 64 architectures
◆ PIN_ResumeApplicationThreads()
| VOID PIN_ResumeApplicationThreads |
( |
THREADID |
tid | ) |
|
|
extern |
This function may be called after a successful call to PIN_StopApplicationThreads() in order to resume execution of the stopped application threads. If a thread's CONTEXT was changed while it was stopped, it resumes with the new CONTEXT.
@Note When used in application thread, it is highly recommended to call it in the same analysis function that called PIN_StopApplicationThreads(). Deferring the call could result in a deadlock when the thread later tries to acquire a lock held by other application thread it suspended.
- Parameters
-
- Note
- The vm lock is obtained during the call of this API.
- Availability:
- Mode: JIT
O/S: Linux, Windows
CPU: IA-32 and Intel(R) 64 architectures
◆ PIN_SetThreadData()
| BOOL PIN_SetThreadData |
( |
TLS_KEY |
key, |
|
|
const VOID * |
data, |
|
|
THREADID |
threadId |
|
) |
| |
|
extern |
Store specified value in the specified TLS slot of the thread.
- Parameters
-
| [in] | key | TLS key, referencing the slot, where the value will be stored upon successful return. The key should be allocated by a previous call to the PIN_CreateThreadDataKey() function. |
| [in] | data | value to be stored in the TLS slot of the current thread. |
| [in] | threadId | Thread ID assigned by pin of the thread for which TLS access is desired, not necessarily the current thread. This ID can be obtained by the PIN_ThreadId() function call or received as the value of the IARG_THREAD_ID argument. |
- Returns
- TRUE, if specified key is currently allocated; FALSE, if specified key is invalid or the given thread is not yet registered in the pin thread database; undefined, if specified key is valid, but it is not currently allocated
- Availability:
- Mode: JIT
O/S: Linux, Windows
CPU: All
◆ PIN_SpawnApplicationThread()
| NATIVE_TID PIN_SpawnApplicationThread |
( |
const CONTEXT * |
ctxt | ) |
|
|
extern |
Start a new application thread with the register state specified by ctxt.
The context must contain at least a valid flags register, even if the tool later replaces the thread's register state from a thread-start callback. On Windows, the stack pointer in ctxt must point to a valid stack that is large enough for the new thread to enter user mode.
- Parameters
-
| [in] | ctxt | Initial context for the new thread. |
- Returns
- The native OS thread ID of the spawned thread, or INVALID_NATIVE_TID if the thread could not be created.
- Note
- This function is intended primarily for replay scenarios that use segment virtualization. In normal instrumentation flows, tools should usually create application threads by calling the application's thread-creation routine, such as
pthread_create, through PIN_CallApplicationFunction.
-
Native application code executed by a thread created with this API is limited unless the thread has valid OS and CRT TLS state. In particular, code that accesses TLS through FS or GS, such as
printf or errno, may fault. This limitation is typically less severe on Windows because the OS allocates TLS for the new thread, but this API is still not recommended for normal instrumentation flows.
-
A tool can avoid the TLS limitation by forcing valid FS/GS selector and base values after control transfers to the requested context. These values must point to TLS state that is properly initialized for the OS and CRT, which is difficult to do robustly.
-
Code called from an analysis routine in the context of the spawned thread has no special limitations. The TLS limitations above apply to native application code executed by the spawned thread.
-
FS/GS selector and base values in ctxt are not used as the actual FS/GS register state for the new thread.
-
Segment virtualization can be enabled with
-xyzzy -virtual_segments 1.
-
On Windows, virtual registers, Pin registers, and pintool registers in ctxt are ignored. Only general-purpose registers and the flags register are initialized from ctxt. On Linux, all registers are initialized from ctxt except FS/GS selectors and FS/GS base values.
-
On Windows, the THREAD_START_CALLBACK callback for the new thread receives a context that differs from ctxt. The kernel enters user mode at an OS entry point rather than at the IP specified in ctxt, so other registers may also differ. In particular, the stack pointer differs because the kernel places the OS entry-point arguments on the stack before entering user mode. The default user-mode code then transfers to ctxt using NtContinue. A tool can change this behavior by modifying the callback context.
-
THREAD_START_CALLBACK runs while Pin holds the VM lock. Therefore, tools may reuse one initial stack for multiple threads created with this API as long as the callback changes each thread's stack pointer and IP before execution continues. On Windows, however, the thread is not fully initialized for Win32 usage unless the default behavior is preserved. This is another reason to avoid this API in normal instrumentation flows.
- Availability:
- Mode: JIT
O/S: Linux, Windows
CPU: IA-32 and Intel(R) 64 architectures
◆ PIN_SpawnInternalThread()
Create a new tool internal thread in the current process.
It is safe to create internal threads anywhere in the tool's code, including from instrumentation callbacks, analysis callbacks or from from existing internal threads.
In order to ensure graceful termination of internal threads on the application's exit, the tool can use the following recommended method:
- The tool uses the PIN_AddPrepareForFiniFunction() function to register a PREPARE_FOR_FINI_CALLBACK callback. When the registered function is called in an "unlocked" thread, the tool requests each other internal thread to exit and waits until the PIN_WaitForThreadTermination() function returns.
- Note
- Pin doesn't wait for internal threads termination after the callbacks.
Many of Pin's APIs, that are primarily intended for application threads, are also available in internal threads. Look at the API's description ( Availability paragraph) or the description of the corresponding group of APIs to check whether a specific API is available in internal threads.
- Parameters
-
| [in] | pThreadFunc | main (starting) function of the thread |
| [in] | arg | argument of the main thread function |
| [in] | stackSize | size of the thread's stack, in bytes. The function rounds this value up to the page size. If this parameter is zero, DEFAULT_THREAD_STACK_SIZE bytes will be allocated for the stack. |
| [out] | pThreadUid | pointer to a variable that receives the unique identifier of the new thread in Pin. This identifier can be used in the PIN_WaitForThreadTermination() function to join the thread. If the caller specifies NULL for this parameter, the unique thread ID is not returned and the creatred thread will not be joinable using PIN_WaitForThreadTermination. |
- Returns
- Pin thread ID of the new thread in Pin or INVALID_THREADID if the thread creation failed.
- Note
- Starting with Pin 4.0, internal threads may also be created using pthread_create() and std::thread(). clone()/clone3() on Linux or CreateThread() on Windows should not be used.
- Pin makes an effort to hide internal threads from the application so, usually, a tool's threads do not interfere with the application. However, the complete transparency of internal threads is not guaranteed, so tools should only use them when their instrumentation tasks cannot be done (effectively) by analysis routines within application threads. For example, a need to execute Windows services (Win32 APIs) may be a reason for creating a private thread in the tool. All Win32 APIs that do not modify the application's resources can be freely used in internal threads. In application threads, on the contrary, using Win32 APIs in analysis routines and Pin callbacks is not supported due to possible reentrancy and isolation problems.
- Internal threads remain blocked inside Pin until PIN_StartProgram() is called and Pin completes some initialization. On Linux, internal threads start running pThreadFunc before Pin executes the first application instruction. On Windows all threads, including Pin internal threads, start executing from the system runtime before they execute the pThreadFunc function. However, the system runtime blocks threads until the application has finished initializing its DLL's (i.e. until the application releases the internal "loader lock"). As a result, Pin internal threads on Windows do not execute pThreadFunc until after the application finishes executing the DLL initialization code. On Linux for all architectures and on Windows for 64 bit applications, it is possible to start a thread before PIN_StartProgram by using pthread_create() or std::thread() instead of PIN_SpawnInternalThread(). See PIN_InitializeInternalThread and PIN_WaitForProgramStart().
- Note
- Trying to create a thread using pthread_create or std::thread in Windows 32-bit applications running on Windows 64-bit OS (WOW64) before PIN_StartProgram might result in a deadlock.
- Availability:
- Mode: JIT & Probe
O/S: Linux, Windows
CPU: All
◆ PIN_StopApplicationThreads()
| BOOL PIN_StopApplicationThreads |
( |
THREADID |
tid | ) |
|
|
extern |
Pin client functions to temporarily stop all application threads, examine their state and resume.
This function may be called by either an application thread or by a Pin internal thread to stop all other application threads at a "safe point". Threads that are stopped at a safe point are always stopped in between traces, so the caller is guaranteed that they are not stopped in the middle of any analysis functions or call-back functions. Once stopped, the calling thread can examine and modify the registers of the stopped threads.
If this function is called by an internal thread, it stops all application threads. If it is called by an application thread, it stops all other application threads. When called by an application thread, this function may be called from an analysis function, but not from a call-back function.
Since this function blocks until other application threads finish their current trace, the caller must not hold any locks that the other threads might try to acquire. Doing so could result in a deadlock.
- Parameters
-
| [in] | tid | The Pin thread ID of the calling thread. |
- Returns
- TRUE if the target threads are successfully stopped. FALSE indicates that some other thread is trying to stop the calling thread. In such a case, the caller should return from its analysis function to avoid a deadlock.
- Note
- The vm lock is obtained during the call of this API.
- Availability:
- Mode: JIT
O/S: Linux, Windows
CPU: IA-32 and Intel(R) 64 architectures
◆ PIN_ThreadId()
Get Pin's internal identifier of the current thread in Pin.
- Returns
- ID of the current thread in Pin or INVALID_THREADID upon failure.
- Availability:
- Mode: JIT
O/S: Linux, Windows
CPU: All
◆ PIN_WaitForProgramStart()
| BOOL PIN_WaitForProgramStart |
( |
| ) |
|
|
extern |
Block the calling thread until Pin finishes it's internal initialization after a call to PIN_StartProgram or PIN_StartProgramProbed.
This function is intended to be called from a thread created using pthread_create or std::thread to mimic the behavior of threads created using PIN_SpawnInternalThread, that waits for program start.
To avoid deadlocks this function must be called from a thread different than the main tool thread. It's possible to call this function from any other thread in the tool, even from an application thread. However calling this function from a thread created using PIN_SpawnInternalThread or an application thread, will return immediately with a return value of true.
- Returns
- TRUE - the program has started and the thread can continue, FALSE - shutdown was initiated before the program started. The calling thread should exit.
- Availability:
- Mode: JIT & Probe
O/S: Linux, Windows
CPU: All
◆ PIN_WaitForThreadTermination()
| BOOL PIN_WaitForThreadTermination |
( |
const PIN_THREAD_UID & |
threadUid, |
|
|
UINT32 |
milliseconds, |
|
|
INT32 * |
pExitCode |
|
) |
| |
|
extern |
Delay the current thread until the specified thread is terminated or the time-out interval elapses.
To avoid deadlocks, the caller should not hold any lock that the target thread may try to acquire. For example, this function can be safely used in the PREPARE_FOR_FINI_CALLBACK callback if it is registered by the PIN_AddPrepareForFiniFunction(). However, it is not recommended to use this function in other Pin callbacks if the target thread is an application thread or an internal thread that uses Pin APIs. This is because most of Pin APIs and callbacks are serialized by the same internal lock.
- This function can not be used to wait for the termination of the calling thread.
- This function can not be used to wait for an application thread.
- This function can not be used to wait on threads created using
pthread_create or std::thread. Use pthread_join and std::thread::join respectively.
- This function can not be called twice on the same unique id.
- Parameters
-
| [in] | threadUid | unique identifier of the thread to be waited for termination, provided by PIN_SpawnInternalThread(). |
| [in] | milliseconds | time-out interval, in milliseconds. If this parameter is zero, the function tests the thread's state and returns immediately. If this parameter is PIN_INFINITE_TIMEOUT, the time-out interval never elapses. |
| [out] | pExitCode | optional pointer to a variable that receives exit code of the thread. If this pointer is NULL or the thread has not terminated, the exit code is not returned. |
- Returns
- TRUE - the thread has terminated, FALSE - the specified time-out interval elapsed or threadUid is not valid or corresponds to current thread or specified thread is not yet started when application shutdown begins.
- Availability:
- Mode: JIT & Probe
O/S: Linux, Windows
CPU: All
◆ FUTURE_THREADID
Invalid value of the THREADID type.
◆ INVALID_OS_THREAD_ID
| const OS_THREAD_ID INVALID_OS_THREAD_ID = INVALID_NATIVE_TID |
Invalid value of the OS_THREAD_ID type.
◆ INVALID_PIN_THREAD_UID
Invalid value of the PIN_THREAD_UID type.
◆ INVALID_THREADID
Invalid value of the THREADID type.
◆ INVALID_TLS_KEY
| const TLS_KEY INVALID_TLS_KEY = (-1) |
Invalid value of the TLS_KEY type.
◆ MAX_CLIENT_TLS_KEYS
| const UINT32 MAX_CLIENT_TLS_KEYS = (TLS_KEY_CLIENT_LAST - TLS_KEY_CLIENT_FIRST + 1) |
Maximum number of TLS keys that can be allocated by tool