ibm-information-center/dist/eclipse/plugins/i5OS.ic.apis_5.4.0.1/users_h1.htm

502 lines
21 KiB
HTML
Raw Normal View History

2024-04-02 14:02:31 +00:00
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Copyright" content="Copyright (c) 2006 by IBM Corporation">
<title>pthread_trace_init_np()--Initialize or Re-initialize pthread
tracing</title>
<!-- All rights reserved. Licensed Materials Property of IBM -->
<!-- US Government Users Restricted Rights -->
<!-- Use, duplication or disclosure restricted by -->
<!-- GSA ADP Schedule Contract with IBM Corp. -->
<!-- Begin Header Records ========================================== -->
<!-- NETMG2 SCRIPT A converted by B2H R4.1 (346) (CMS) by HOLTJM at -->
<!-- RCHVMW2 on 29 Jan 1999 at 10:01:37 -->
<!--File Edited November 2001 -->
<!--End Header Records -->
<link rel="stylesheet" type="text/css" href="../rzahg/ic.css">
</head>
<body>
<!-- Java sync-link -->
<script language="Javascript" src="../rzahg/synch.js" type="text/javascript">
</script>
<a name="Top_Of_Page"></a>
<h2>pthread_trace_init_np()--Initialize or Re-initialize pthread tracing</h2>
<div class="box" style="width: 50%;">
<br>
&nbsp;&nbsp;Syntax:
<pre>
#include &lt;pthread.h&gt;
int pthread_trace_init_np(void);
</pre>
&nbsp;&nbsp;Service Program Name: QP0WPTHR<br>
<!-- iddvc RMBR -->
<br>
&nbsp;&nbsp;Default Public Authority: *USE<br>
<!-- iddvc RMBR -->
<br>
&nbsp;&nbsp;Threadsafe: Yes<br>
<!-- iddvc RMBR -->
<br>
&nbsp;&nbsp;Signal Safe: No<br>
<!-- iddvc RMBR -->
<br>
</div>
<p>The <strong>pthread_trace_init_np</strong>() API initializes or refreshes
both the Pthreads library trace level and the application trace level. The
Pthreads library trace level is maintained internally by the Pthreads library,
while the application trace level is stored in the <em>Qp0wTraceLevel</em>
external variable and can be used by the <strong>PTHREAD_TRACE_NP</strong>()
macro.</p>
<p>When a program or service program that uses the Pthread APIs causes the
Pthread APIs to be loaded (activated), the Pthreads library automatically calls
the <strong>pthread_trace_init_np</strong>() function in order to initialize
tracing based on the value of the <strong>QIBM_PTHREAD_TRACE_LEVEL</strong>
environment variable at that time.</p>
<p>The application can call <strong>pthread_trace_init_np</strong>() at an
arbitrary time during execution to initialize or refresh the current Pthreads
library tracing level and the application trace level. The trace level is set
based on the value of the <strong>QIBM_PTHREAD_TRACE_LEVEL</strong> environment
variable at the time of the call. The new tracing level is also returned.</p>
<p>The Pthreads library tracing level is used to control trace records written
by the Pthreads library functions at runtime. The following table describes the
preprocessor macros representing the various trace levels, the setting of the
<strong>QIBM_PTHREAD_TRACE_LEVEL</strong> environment variable, and the
conditions that are traced.</p>
<table border cellpadding="5">
<!-- cols="35 35 30" -->
<tr>
<th valign="top">Trace Level</th>
<th valign="top">EnvVar</th>
<th valign="top">Description</th>
</tr>
<tr>
<td align="left" valign="top"><strong>PTHREAD_TRACE_NONE_NP</strong></td>
<td align="left" valign="top">"QIBM_PTHREAD_TRACE_LEVEL=0"<br>
(or not set)</td>
<td align="left" valign="top">No tracing is performed by the Pthreads library.
Application tracing may still be done.</td>
</tr>
<tr>
<td align="left" valign="top"><strong>PTHREAD_TRACE_ERROR_NP</strong></td>
<td align="left" valign="top">"QIBM_PTHREAD_TRACE_LEVEL=1"</td>
<td align="left" valign="top">Error level traces error conditions and the
causes of most error return codes.</td>
</tr>
<tr>
<td align="left" valign="top"><strong>PTHREAD_TRACE_INFO_NP</strong></td>
<td align="left" valign="top">"QIBM_PTHREAD_TRACE_LEVEL=2"</td>
<td align="left" valign="top">Informational level traces error level
tracepoints, plus entry to and exit from functions, parameters passed to and
return codes from functions, major changes in control flow.</td>
</tr>
<tr>
<td align="left" valign="top"><strong>PTHREAD_TRACE_VERBOSE_NP</strong></td>
<td align="left" valign="top">"QIBM_PTHREAD_TRACE_LEVEL=3"</td>
<td align="left" valign="top">Verbose level traces informational level
tracepoints, plus detailed information about application parameters, threads
and data structures including information about Pthreads library processing
information.</td>
</tr>
</table>
<p>The application provides tracing support similar to the Pthreads library
using the <strong>PTHREAD_TRACE_NP</strong>() macro.</p>
<p>The <strong>PTHREAD_TRACE_NP</strong>() macro uses the external variable
<em>Qp0wTraceLevel</em>. <em>Qp0wTraceLevel</em> may be used directly by the
application to set application trace level without effecting the current
Pthread library trace level. Set the value of <em>Qp0wTraceLevel</em> to one of
<strong>PTHREAD_TRACE_NONE_NP</strong>,
<strong>PTHREAD_TRACE_ERROR_NP</strong>,
<strong>PTHREAD_TRACE_INFO_NP</strong>, or
<strong>PTHREAD_TRACE_VERBOSE_NP</strong>.</p>
<p>The <strong>PTHREAD_TRACE_NP</strong>() macro can be used in conjunction
with the following APIs to put trace records into the user trace flight
recorder. The following system APIs defined in the qp0ztrc.h header file:</p>
<ul>
<li>Qp0zUprintf - print formatted trace data</li>
<li>Qp0zDump - dump formatted hex data</li>
<li>Qp0zDumpStack - dump the call stack of the calling thread</li>
<li>Qp0zDumpTargetStack - dump the call stack of the target thread</li>
</ul>
<p>The trace records are written to the user trace flight recorder and can be
accessed by the following CL commands:</p>
<ul>
<li>DMPUSRTRC - dump the contents of a specified job's trace</li>
<li>CHGUSRTRC - change attributes (size, wrapping, clear) of a specified job's
trace</li>
<li>DLTUSRTRC - delete the persistent trace object associated with a job's
trace</li>
</ul>
<br>
<h3>Authorities and Locks</h3>
<p>None.</p>
<br>
<h3>Parameters</h3>
<p>None.</p>
<br>
<h3>Return Value</h3>
<dl>
<dt><strong>value</strong></dt>
<dd>The new trace level. One of <strong>PTHREAD_TRACE_NONE_NP</strong>,
<strong>PTHREAD_TRACE_ERROR_NP</strong>,
<strong>PTHREAD_TRACE_INFO_NP</strong>, or
<strong>PTHREAD_TRACE_VERBOSE_NP</strong>.</dd>
</dl>
<br>
<h3>Error Conditions</h3>
<p>None.</p>
<br>
<h3>Related Information</h3>
<ul>
<li>The &lt;<strong>pthread.h</strong>&gt; header file. See <a href=
"rzah4hed.htm">Header files for Pthread functions</a>.<br>
<br>
</li>
<li><a href="users_h2.htm">PTHREAD_TRACE_NP()</a>--Execute code based on trace
level (Macro)</li>
</ul>
<br>
<h3>Example</h3>
<p>See <a href="../apiref/aboutapis.htm#codedisclaimer">Code disclaimer information</a>
for information pertaining to code examples.</p>
<pre>
#define _MULTI_THREADED
#include &lt;pthread.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;unistd.h&gt;
#include &lt;qp0ztrc.h&gt;
#define checkResults(string, val) { \
if (val) { \
printf("Failed with %d at %s", val, string); \
exit(1); \
} \
}
typedef struct {
int threadSpecific1;
int threadSpecific2;
} threadSpecific_data_t;
#define NUMTHREADS 2
pthread_key_t threadSpecificKey;
void foo(void);
void bar(void);
void dataDestructor(void *);
void *theThread(void *parm) {
int rc;
threadSpecific_data_t *gData;
PTHREAD_TRACE_NP({
Qp0zUprintf("Thread Entered\n");
Qp0zDump("Global Data", parm, sizeof(threadSpecific_data_t));},
PTHREAD_TRACE_INFO_NP);
gData = (threadSpecific_data_t *)parm;
rc = pthread_setspecific(threadSpecificKey, gData);
checkResults("pthread_setspecific()\n", rc);
foo();
return NULL;
}
void foo() {
threadSpecific_data_t *gData =
(threadSpecific_data_t *)pthread_getspecific(threadSpecificKey);
PTHREAD_TRACE_NP(Qp0zUprintf("foo(), threadSpecific data=%d %d\n",
gData-&gt;threadSpecific1, gData-&gt;threadSpecific2);,
PTHREAD_TRACE_INFO_NP);
bar();
PTHREAD_TRACE_NP(Qp0zUprintf("foo(): This is an error tracepoint\n");,
PTHREAD_TRACE_ERROR_NP);
}
void bar() {
threadSpecific_data_t *gData =
(threadSpecific_data_t *)pthread_getspecific(threadSpecificKey);
PTHREAD_TRACE_NP(Qp0zUprintf("bar(), threadSpecific data=%d %d\n",
gData-&gt;threadSpecific1, gData-&gt;threadSpecific2);,
PTHREAD_TRACE_INFO_NP);
PTHREAD_TRACE_NP(Qp0zUprintf("bar(): This is an error tracepoint\n");
Qp0zDumpStack("This thread's stack at time of error in bar()");,
PTHREAD_TRACE_ERROR_NP);
return;
}
void dataDestructor(void *data) {
PTHREAD_TRACE_NP(Qp0zUprintf("dataDestructor: Free data\n");,
PTHREAD_TRACE_INFO_NP);
pthread_setspecific(threadSpecificKey, NULL); free(data);
/* If doing verbose tracing we'll even write a message to the job log */
PTHREAD_TRACE_NP(Qp0zLprintf("Free'd the thread specific data\n");,
PTHREAD_TRACE_VERBOSE_NP);
}
/* Call this testcase with an optional parameter 'PTHREAD_TRACING' */
/* If the PTHREAD_TRACING parameter is specified, then the */
/* Pthread tracing environment variable will be set, and the */
/* pthread tracing will be re initialized from its previous value. */
/* NOTE: We set the trace level to informational, tracepoints cut */
/* using PTHREAD_TRACE_NP at a VERBOSE level will NOT show up*/
int main(int argc, char **argv) {
pthread_t thread[NUMTHREADS];
int rc=0;
int i;
threadSpecific_data_t *gData;
char buffer[50];
PTHREAD_TRACE_NP(Qp0zUprintf("Enter Testcase - %s\n", argv[0]);,
PTHREAD_TRACE_INFO_NP);
if (argc == 2 &amp;&amp; !strcmp("PTHREAD_TRACING", argv[1])) {
/* Turn on internal pthread function tracing support */
/* Or, use ADDENVVAR, CHGENVVAR CL commands to set this envvar*/
sprintf(buffer, "QIBM_PTHREAD_TRACE_LEVEL=%d", PTHREAD_TRACE_INFO_NP);
putenv(buffer);
/* Refresh the Pthreads internal tracing with the environment */
/* variables value. */
pthread_trace_init_np();
}
else {
/* Trace only our application, not the Pthread code */
Qp0wTraceLevel = PTHREAD_TRACE_INFO_NP;
}
rc = pthread_key_create(&amp;threadSpecificKey, dataDestructor);
checkResults("pthread_key_create()\n", rc);
for (i=0; i &lt;NUMTHREADS; ++i) {
PTHREAD_TRACE_NP(Qp0zUprintf("Create/start a thread\n");,
PTHREAD_TRACE_INFO_NP);
/* Create per-thread threadSpecific data and pass it to the thread */
gData = (threadSpecific_data_t *)malloc(sizeof (threadSpecific_data_t));
gData-&gt;threadSpecific1 = i;
gData-&gt;threadSpecific2 = (i+1)*2;
rc = pthread_create( &amp;thread[i], NULL, theThread, gData);
checkResults("pthread_create()\n", rc);
PTHREAD_TRACE_NP(Qp0zUprintf("Wait for the thread to complete, "
"and release their resources\n");,
PTHREAD_TRACE_INFO_NP);
rc = pthread_join(thread[i], NULL);
checkResults("pthread_join()\n", rc);
}
pthread_key_delete(threadSpecificKey);
PTHREAD_TRACE_NP(Qp0zUprintf("Main completed\n");,
PTHREAD_TRACE_INFO_NP);
return 0;
}
</pre>
<p><strong>Output</strong></p>
<p>Use CL command <strong>DMPUSRTRC</strong> to output the following tracing
information that the example creates. The <strong>DMPUSRTRC</strong> CL command
causes the following information to be put into file QTEMP/QAP0ZDMP or to
standard output depending on the options used for the CL command.</p>
<p>Note the following:</p>
<ul>
<li>The trace records are indented and labeled based on thread id plus a
microsecond timestamp at the time the tracepoint was cut. In the following
trace record, the value <em>00000018</em> indicates the thread ID of the thread
that created the tracepoint. The value <em>972456</em> indicates that the
tracepoint occurred 972456 microseconds after the last timestamp indicator.
<pre>
00000018:972456 pthread_trace_init_np(): New traceLevel=2
</pre>
</li>
<li>You can use the Pthread library tracepoints to debug incorrect calls to the
Pthreads library from your application.</li>
<li>The following trace output occurs when the optional parameter
'PTHREAD_TRACING' IS specified when calling this program. The 'PTHREAD_TRACING'
parameter causes the <strong>pthread_trace_init_np()</strong>() function to be
used which initializes the Pthreads library tracing.</li>
<li>There is <strong>significantly</strong> more information traced than the
example shown in the documentation for the <strong>PTHREAD_TRACE_NP</strong>()
macro</li>
<li>The function names for threads and data destructors are traced.</li>
<li>The values for many Pthread API parameters are traced, allowing application
debug.</li>
<li>Some internal Pthread API information is traced at an information-level
tracing when the control flow information is critical.</li>
</ul>
<pre>
User Trace Dump for job 097979/KULACK/PTHREADT. Size: 300K, Wrapped 0 times.
--- 11/09/1998 15:15:56 ---
00000018:972456 pthread_trace_init_np(): New traceLevel=2
00000018:972592 pthread_key_create(entry): dtor=a1000000 00000000 d161cc19 45001a00
00000018:993920 destructor name is 'dataDestructor__FPv'
00000018:994048 pthread_key_create(exit): newKey=0, rc=0
00000018:994120 Create/start a thread
00000018:994224 pthread_create(entry): thread=80000000 00000000 f11d9cc7 23000400
00000018:994296 attr=00000000 00000000 00000000 00000000
00000018:994376 start_routine=a1000000 00000000 d161cc19 45006980
00000018:995320 routine name is 'theThread__FPv'
00000018:995432 arg=80000000 00000000 e7c74b3e 04001cd0
00000018:995992 pthread_create(status): Create a new thread
00000018:996088 Joinable-1
00000018:996152 PrioInheritSched-EXPLICIT Prio-0
00000018:997488 pthread_create(exit): Success
00000018:997632 tcb=80000000 00000000 feb52907 07001000
00000018:997704 thread id=00000000 00000019 handle=00000007
00000018:997792 Wait for the thread to complete, and release their resources
00000018:997896 pthread_join_processor(entry):Target 00000000 00000019,Detach=1,time=00000000 sec,00000000 nanosec.
00000018:997968 statusp = 00000000 00000000 00000000 00000000
00000019:998720 pthread_create_part2(status): run the new thread: 00000000 00000019
00000019:998864 Thread Entered
00000019:998984 E7C74B3E04:001CD0 L:0008 Global Data
00000019:999144 E7C74B3E04:001CD0 00000000 00000002 *................*
00000019:999240 pthread_setspecific(entry): value=80000000 00000000 e7c74b3e 04001cd0, key=0
00000019:999320 pthread_getspecific(entry): key=0
00000019:999392 foo(), threadSpecific data=0 2
00000019:999464 pthread_getspecific(entry): key=0
00000019:999536 bar(), threadSpecific data=0 2
00000019:999600 bar(): This is an error tracepoint
00000019:999664 Stack Dump For Current Thread
00000019:999728 Stack: This thread's stack at time of error in bar()
--- 11/09/1998 15:15:57 ---
00000019:000304 Stack: Library / Program Module Stmt Procedure
00000019:000472 Stack: QSYS / QLESPI QLECRTTH 774 : LE_Create_Thread2__FP12crtth_parm_t
00000019:000560 Stack: QSYS / QP0WPTHR QP0WPTHR 1008 : pthread_create_part2
00000019:000656 Stack: KULACK / PTHREADT PTHREADT 19 : theThread__FPv
00000019:000728 Stack: KULACK / PTHREADT PTHREADT 29 : foo__Fv
00000019:000808 Stack: KULACK / PTHREADT PTHREADT 46 : bar__Fv
00000019:000888 Stack: QSYS / QP0ZCPA QP0ZUDBG 87 : Qp0zDumpStack
00000019:007416 Stack: QSYS / QP0ZSCPA QP0ZSCPA 276 : Qp0zSUDumpStack
00000019:007504 Stack: QSYS / QP0ZSCPA QP0ZSCPA 287 : Qp0zSUDumpTargetStack
00000019:007544 Stack: Completed
00000019:007664 foo(): This is an error tracepoint
00000019:007752 pthread_create_part2(status):return from start routine,status=00000000 00000000 00000000 00000000
00000019:007816 pthread_cleanup(entry): Thread termination started
00000019:007888 Qp0wTlsVector::invokeHandlers(entry):
00000019:007952 Qp0wTlsVector::invokeHandler(invoke): key=0
00000019:008040 dtor=a1000000 00000000 d161cc19 45001a00,
00000019:010792 destructor name is 'dataDestructor__FPv'
00000019:010920 arg=80000000 00000000 e7c74b3e 04001cd0
00000019:011008 dataDestructor: Free data
00000019:011096 pthread_setspecific(entry): value=00000000 00000000 00000000 00000000, key=0
00000019:011184 pthread_cleanup(exit): returning
00000018:011624 pthread_join_processor(status):target status=00000000 00000000 00000000 00000000,state=0x03, YES
00000018:011752 Create/start a thread
00000018:011880 pthread_create(entry): thread=80000000 00000000 f11d9cc7 23000430
00000018:011952 attr=00000000 00000000 00000000 00000000
00000018:012032 start_routine=a1000000 00000000 d161cc19 45006980
00000018:013464 routine name is 'theThread__FPv'
00000018:013576 arg=80000000 00000000 e7c74b3e 04001cd0
00000018:013704 Qp0wTcb::Qp0wTcb(status): Tcb was reused: tcb=80000000 00000000 feb52907 07001000
00000018:013784 pthread_create(status): Create a new thread
00000018:013848 Joinable-1
00000018:013912 PrioInheritSched-EXPLICIT Prio-0
00000018:014736 pthread_create(exit): Success
00000018:014912 tcb=80000000 00000000 feb52907 07001000
00000018:014984 thread id=00000000 0000001a handle=00000007
00000018:015072 Wait for the thread to complete, and release their resources
00000018:015168 pthread_join_processor(entry):Target 00000000 0000001a,Detach=1,time=00000000 sec,00000000 nanosec.
00000018:015240 statusp = 00000000 00000000 00000000 00000000
0000001A:015696 pthread_create_part2(status): run the new thread: 00000000 0000001a
0000001A:015840 Thread Entered
0000001A:015968 E7C74B3E04:001CD0 L:0008 Global Data
0000001A:016128 E7C74B3E04:001CD0 00000001 00000004 *................*
0000001A:016232 pthread_setspecific(entry): value=80000000 00000000 e7c74b3e 04001cd0, key=0
0000001A:016304 pthread_getspecific(entry): key=0
0000001A:016384 foo(), threadSpecific data=1 4
0000001A:016456 pthread_getspecific(entry): key=0
0000001A:016528 bar(), threadSpecific data=1 4
0000001A:016584 bar(): This is an error tracepoint
0000001A:016648 Stack Dump For Current Thread
0000001A:016712 Stack: This thread's stack at time of error in bar()
0000001A:016904 Stack: Library / Program Module Stmt Procedure
0000001A:017048 Stack: QSYS / QLESPI QLECRTTH 774 : LE_Create_Thread2__FP12crtth_parm_t
0000001A:017144 Stack: QSYS / QP0WPTHR QP0WPTHR 1008 : pthread_create_part2
0000001A:017232 Stack: KULACK / PTHREADT PTHREADT 19 : theThread__FPv
0000001A:018680 Stack: KULACK / PTHREADT PTHREADT 29 : foo__Fv
0000001A:018760 Stack: KULACK / PTHREADT PTHREADT 46 : bar__Fv
0000001A:018840 Stack: QSYS / QP0ZCPA QP0ZUDBG 87 : Qp0zDumpStack
0000001A:018928 Stack: QSYS / QP0ZSCPA QP0ZSCPA 276 : Qp0zSUDumpStack
0000001A:019000 Stack: QSYS / QP0ZSCPA QP0ZSCPA 287 : Qp0zSUDumpTargetStack
0000001A:019040 Stack: Completed
0000001A:019136 foo(): This is an error tracepoint
0000001A:019224 pthread_create_part2(status):return from start routine,status=00000000 00000000 00000000 00000000
0000001A:019288 pthread_cleanup(entry): Thread termination started
0000001A:019352 Qp0wTlsVector::invokeHandlers(entry):
0000001A:019424 Qp0wTlsVector::invokeHandler(invoke): key=0
0000001A:019504 dtor=a1000000 00000000 d161cc19 45001a00,
0000001A:021360 destructor name is 'dataDestructor__FPv'
0000001A:021496 arg=80000000 00000000 e7c74b3e 04001cd0
0000001A:021576 dataDestructor: Free data
0000001A:021664 pthread_setspecific(entry): value=00000000 00000000 00000000 00000000, key=0
0000001A:021752 pthread_cleanup(exit): returning
00000018:022112 pthread_join_processor(status):target status=00000000 00000000 00000000 00000000,state=0x03, YES
00000018:022272 pthread_key_delete(entry): key=0
00000018:022336 pthread_key_delete(exit): rc=0
00000018:022408 Main completed
</pre>
<br>
<hr>
API introduced: V4R3
<hr>
<center>
<table cellpadding="2" cellspacing="2">
<tr align="center">
<td valign="middle" align="center"><a href="#Top_Of_Page">Top</a> | <a href=
"rzah4mst.htm">Pthread APIs</a> | <a href="aplist.htm">APIs by
category</a></td>
</tr>
</table>
</center>
</body>
</html>