|
From: <sv...@va...> - 2009-01-03 20:46:25
|
Author: sewardj Date: 2009-01-03 20:46:17 +0000 (Sat, 03 Jan 2009) New Revision: 371 Log: Add new (and missing) manual pieces. Added: trunk/docs/manual/drd-manual.html trunk/docs/manual/pc-manual.html trunk/docs/manual/vg_basic.css Added: trunk/docs/manual/drd-manual.html =================================================================== --- trunk/docs/manual/drd-manual.html (rev 0) +++ trunk/docs/manual/drd-manual.html 2009-01-03 20:46:17 UTC (rev 371) @@ -0,0 +1,1273 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> +<title>8.DRD: a thread error detector</title> +<link rel="stylesheet" href="vg_basic.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.69.1"> +<link rel="start" href="index.html" title="Valgrind Documentation"> +<link rel="up" href="manual.html" title="Valgrind User Manual"> +<link rel="prev" href="hg-manual.html" title="7.Helgrind: a thread error detector"> +<link rel="next" href="ms-manual.html" title="9.Massif: a heap profiler"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<div><table class="nav" width="100%" cellspacing="3" cellpadding="3" border="0" summary="Navigation header"><tr> +<td width="22px" align="center" valign="middle"><a accesskey="p" href="hg-manual.html"><img src="images/prev.png" width="18" height="21" border="0" alt="Prev"></a></td> +<td width="25px" align="center" valign="middle"><a accesskey="u" href="manual.html"><img src="images/up.png" width="21" height="18" border="0" alt="Up"></a></td> +<td width="31px" align="center" valign="middle"><a accesskey="h" href="index.html"><img src="images/home.png" width="27" height="20" border="0" alt="Up"></a></td> +<th align="center" valign="middle">Valgrind User Manual</th> +<td width="22px" align="center" valign="middle"><a accesskey="n" href="ms-manual.html"><img src="images/next.png" width="18" height="21" border="0" alt="Next"></a></td> +</tr></table></div> +<div class="chapter" lang="en"> +<div class="titlepage"><div><div><h2 class="title"> +<a name="drd-manual"></a>8.DRD: a thread error detector</h2></div></div></div> +<div class="toc"> +<p><b>Table of Contents</b></p> +<dl> +<dt><span class="sect1"><a href="drd-manual.html#drd-manual.overview">8.1. Background</a></span></dt> +<dd><dl> +<dt><span class="sect2"><a href="drd-manual.html#drd-manual.mt-progr-models">8.1.1. Multithreaded Programming Paradigms</a></span></dt> +<dt><span class="sect2"><a href="drd-manual.html#drd-manual.pthreads-model">8.1.2. POSIX Threads Programming Model</a></span></dt> +<dt><span class="sect2"><a href="drd-manual.html#drd-manual.mt-problems">8.1.3. Multithreaded Programming Problems</a></span></dt> +<dt><span class="sect2"><a href="drd-manual.html#drd-manual.data-race-detection">8.1.4. Data Race Detection</a></span></dt> +</dl></dd> +<dt><span class="sect1"><a href="drd-manual.html#drd-manual.using-drd">8.2. Using DRD</a></span></dt> +<dd><dl> +<dt><span class="sect2"><a href="drd-manual.html#drd-manual.options">8.2.1. Command Line Options</a></span></dt> +<dt><span class="sect2"><a href="drd-manual.html#drd-manual.data-races">8.2.2. Detected Errors: Data Races</a></span></dt> +<dt><span class="sect2"><a href="drd-manual.html#drd-manual.lock-contention">8.2.3. Detected Errors: Lock Contention</a></span></dt> +<dt><span class="sect2"><a href="drd-manual.html#drd-manual.api-checks">8.2.4. Detected Errors: Misuse of the POSIX threads API</a></span></dt> +<dt><span class="sect2"><a href="drd-manual.html#drd-manual.clientreqs">8.2.5. Client Requests</a></span></dt> +<dt><span class="sect2"><a href="drd-manual.html#drd-manual.gnome">8.2.6. Debugging GNOME Programs</a></span></dt> +<dt><span class="sect2"><a href="drd-manual.html#drd-manual.qt">8.2.7. Debugging Qt Programs</a></span></dt> +<dt><span class="sect2"><a href="drd-manual.html#drd-manual.boost.thread">8.2.8. Debugging Boost.Thread Programs</a></span></dt> +<dt><span class="sect2"><a href="drd-manual.html#drd-manual.openmp">8.2.9. Debugging OpenMP Programs</a></span></dt> +<dt><span class="sect2"><a href="drd-manual.html#drd-manual.cust-mem-alloc">8.2.10. DRD and Custom Memory Allocators</a></span></dt> +<dt><span class="sect2"><a href="drd-manual.html#drd-manual.drd-versus-memcheck">8.2.11. DRD Versus Memcheck</a></span></dt> +<dt><span class="sect2"><a href="drd-manual.html#drd-manual.resource-requirements">8.2.12. Resource Requirements</a></span></dt> +<dt><span class="sect2"><a href="drd-manual.html#drd-manual.effective-use">8.2.13. Hints and Tips for Effective Use of DRD</a></span></dt> +</dl></dd> +<dt><span class="sect1"><a href="drd-manual.html#drd-manual.Pthreads">8.3. Using the POSIX Threads API Effectively</a></span></dt> +<dd><dl> +<dt><span class="sect2"><a href="drd-manual.html#drd-manual.mutex-types">8.3.1. Mutex types</a></span></dt> +<dt><span class="sect2"><a href="drd-manual.html#drd-manual.condvar">8.3.2. Condition variables</a></span></dt> +<dt><span class="sect2"><a href="drd-manual.html#drd-manual.pctw">8.3.3. pthread_cond_timedwait() and timeouts</a></span></dt> +<dt><span class="sect2"><a href="drd-manual.html#drd-manual.naming-threads">8.3.4. Assigning names to threads</a></span></dt> +</dl></dd> +<dt><span class="sect1"><a href="drd-manual.html#drd-manual.limitations">8.4. Limitations</a></span></dt> +<dt><span class="sect1"><a href="drd-manual.html#drd-manual.feedback">8.5. Feedback</a></span></dt> +</dl> +</div> +<p>To use this tool, you must specify +<code class="computeroutput">--tool=drd</code> +on the Valgrind command line.</p> +<div class="sect1" lang="en"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both"> +<a name="drd-manual.overview"></a>8.1.Background</h2></div></div></div> +<p> +DRD is a Valgrind tool for detecting errors in multithreaded C and C++ +shared-memory programs. The tool works for any program that uses the +POSIX threading primitives or that uses threading concepts built on +top of the POSIX threading primitives. +</p> +<div class="sect2" lang="en"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="drd-manual.mt-progr-models"></a>8.1.1.Multithreaded Programming Paradigms</h3></div></div></div> +<p> +For many applications multithreading is a necessity. There are two +reasons why the use of threads may be required: +</p> +<div class="itemizedlist"><ul type="disc"> +<li><p> + To model concurrent activities. Managing the state of one + activity per thread can be a great simplification compared to + multiplexing the states of multiple activities in a single + thread. This is why most server and embedded software is + multithreaded. + </p></li> +<li><p> + To let computations run on multiple CPU cores + simultaneously. This is why many High Performance Computing + (HPC) applications are multithreaded. + </p></li> +</ul></div> +<p> +</p> +<p> +Multithreaded programs can use one or more of the following +paradigms. Which paradigm is appropriate a.o. depends on the +application type -- modeling concurrent activities versus HPC. +Some examples of multithreaded programming paradigms are: +</p> +<div class="itemizedlist"><ul type="disc"> +<li><p> + Locking. Data that is shared between threads may only be + accessed after a lock has been obtained on the mutex associated + with the shared data item. A.o. the POSIX threads library, the + Qt library and the Boost.Thread library support this paradigm + directly. + </p></li> +<li><p> + Message passing. No data is shared between threads, but threads + exchange data by passing messages to each other. Well known + implementations of the message passing paradigm are MPI and + CORBA. + </p></li> +<li><p> + Automatic parallelization. A compiler converts a sequential + program into a multithreaded program. The original program may + or may not contain parallelization hints. As an example, + <code class="computeroutput">gcc</code> supports the OpenMP + standard from gcc version 4.3.0 on. OpenMP is a set of compiler + directives which tell a compiler how to parallelize a C, C++ or + Fortran program. + </p></li> +<li><p> + Software Transactional Memory (STM). Data is shared between + threads, and shared data is updated via transactions. After each + transaction it is verified whether there were conflicting + transactions. If there were conflicts, the transaction is + aborted, otherwise it is committed. This is a so-called + optimistic approach. There is a prototype of the Intel C + Compiler (<code class="computeroutput">icc</code>) available that + supports STM. Research is ongoing about the addition of STM + support to <code class="computeroutput">gcc</code>. + </p></li> +</ul></div> +<p> +</p> +<p> +DRD supports any combination of multithreaded programming paradigms as +long as the implementation of these paradigms is based on the POSIX +threads primitives. DRD however does not support programs that use +e.g. Linux' futexes directly. Attempts to analyze such programs with +DRD will cause DRD to report many false positives. +</p> +</div> +<div class="sect2" lang="en"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="drd-manual.pthreads-model"></a>8.1.2.POSIX Threads Programming Model</h3></div></div></div> +<p> +POSIX threads, also known as Pthreads, is the most widely available +threading library on Unix systems. +</p> +<p> +The POSIX threads programming model is based on the following abstractions: +</p> +<div class="itemizedlist"><ul type="disc"> +<li><p> + A shared address space. All threads running within the same + process share the same address space. All data, whether shared or + not, is identified by its address. + </p></li> +<li><p> + Regular load and store operations, which allow to read values + from or to write values to the memory shared by all threads + running in the same process. + </p></li> +<li><p> + Atomic store and load-modify-store operations. While these are + not mentioned in the POSIX threads standard, most + microprocessors support atomic memory operations. And some + compilers provide direct support for atomic memory operations + through built-in functions like + e.g. <code class="computeroutput">__sync_fetch_and_add()</code> + which is supported by both <code class="computeroutput">gcc</code> + and <code class="computeroutput">icc</code>. + </p></li> +<li><p> + Threads. Each thread represents a concurrent activity. + </p></li> +<li><p> + Synchronization objects and operations on these synchronization + objects. The following types of synchronization objects are + defined in the POSIX threads standard: mutexes, condition + variables, semaphores, reader-writer locks, barriers and + spinlocks. + </p></li> +</ul></div> +<p> +</p> +<p> +Which source code statements generate which memory accesses depends on +the <span class="emphasis"><em>memory model</em></span> of the programming language +being used. There is not yet a definitive memory model for the C and +C++ languagues. For a draft memory model, see also document <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2338.html" target="_top"> +WG21/N2338</a>. +</p> +<p> +For more information about POSIX threads, see also the Single UNIX +Specification version 3, also known as +<a href="http://www.unix.org/version3/ieee_std.html" target="_top"> +IEEE Std 1003.1</a>. +</p> +</div> +<div class="sect2" lang="en"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="drd-manual.mt-problems"></a>8.1.3.Multithreaded Programming Problems</h3></div></div></div> +<p> +Depending on which multithreading paradigm is being used in a program, +one or more of the following problems can occur: +</p> +<div class="itemizedlist"><ul type="disc"> +<li><p> + Data races. One or more threads access the same memory + location without sufficient locking. + </p></li> +<li><p> + Lock contention. One thread blocks the progress of one or more other + threads by holding a lock too long. + </p></li> +<li><p> + Improper use of the POSIX threads API. The most popular POSIX + threads implementation, NPTL, is optimized for speed. The NPTL + will not complain on certain errors, e.g. when a mutex is locked + in one thread and unlocked in another thread. + </p></li> +<li><p> + Deadlock. A deadlock occurs when two or more threads wait for + each other indefinitely. + </p></li> +<li><p> + False sharing. If threads that run on different processor cores + access different variables located in the same cache line + frequently, this will slow down the involved threads a lot due + to frequent exchange of cache lines. + </p></li> +</ul></div> +<p> +</p> +<p> +Although the likelihood of the occurrence of data races can be reduced +through a disciplined programming style, a tool for automatic +detection of data races is a necessity when developing multithreaded +software. DRD can detect these, as well as lock contention and +improper use of the POSIX threads API. +</p> +</div> +<div class="sect2" lang="en"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="drd-manual.data-race-detection"></a>8.1.4.Data Race Detection</h3></div></div></div> +<p> +Synchronization operations impose an order on interthread memory +accesses. This order is also known as the happens-before relationship. +</p> +<p> +A multithreaded program is data-race free if all interthread memory +accesses are ordered by synchronization operations. +</p> +<p> +A well known way to ensure that a multithreaded program is data-race +free is to ensure that a locking discipline is followed. It is e.g. +possible to associate a mutex with each shared data item, and to hold +a lock on the associated mutex while the shared data is accessed. +</p> +<p> +All programs that follow a locking discipline are data-race free, but +not all data-race free programs follow a locking discipline. There +exist multithreaded programs where access to shared data is arbitrated +via condition variables, semaphores or barriers. As an example, a +certain class of HPC applications consists of a sequence of +computation steps separated in time by barriers, and where these +barriers are the only means of synchronization. +</p> +<p> +There exist two different algorithms for verifying the correctness of +multithreaded programs at runtime. The so-called Eraser algorithm +verifies whether all shared memory accesses follow a consistent +locking strategy. And the happens-before data race detectors verify +directly whether all interthread memory accesses are ordered by +synchronization operations. While the happens-before data race +detection algorithm is more complex to implement, and while it is more +sensitive to OS scheduling, it is a general approach that works for +all classes of multithreaded programs. Furthermore, the happens-before +data race detection algorithm does not report any false positives. +</p> +<p> +DRD is based on the happens-before algorithm. +</p> +</div> +</div> +<div class="sect1" lang="en"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both"> +<a name="drd-manual.using-drd"></a>8.2.Using DRD</h2></div></div></div> +<div class="sect2" lang="en"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="drd-manual.options"></a>8.2.1.Command Line Options</h3></div></div></div> +<p>The following command-line options are available for controlling the +behavior of the DRD tool itself:</p> +<div class="variablelist"> +<a name="drd.opts.list"></a><dl> +<dt><span class="term"> + <code class="option">--check-stack-var=<yes|no> [default: no]</code> + </span></dt> +<dd><p> + Controls whether <code class="constant">DRD</code> reports data races + for stack variables. This is disabled by default in order to + accelerate data race detection. Most programs do not share + stack variables over threads. + </p></dd> +<dt><span class="term"> + <code class="option">--exclusive-threshold=<n> [default: off]</code> + </span></dt> +<dd><p> + Print an error message if any mutex or writer lock has been + held longer than the specified time (in milliseconds). This + option enables detecting lock contention. + </p></dd> +<dt><span class="term"> + <code class="option"> + --report-signal-unlocked=<yes|no> [default: yes] + </code> + </span></dt> +<dd><p> + Whether to report calls to + <code class="function">pthread_cond_signal()</code> and + <code class="function">pthread_cond_broadcast()</code> where the mutex + associated with the signal through + <code class="function">pthread_cond_wait()</code> or + <code class="function">pthread_cond_timed_wait()</code>is not locked at + the time the signal is sent. Sending a signal without holding + a lock on the associated mutex is a common programming error + which can cause subtle race conditions and unpredictable + behavior. There exist some uncommon synchronization patterns + however where it is safe to send a signal without holding a + lock on the associated mutex. + </p></dd> +<dt><span class="term"> + <code class="option">--segment-merging=<yes|no> [default: yes]</code> + </span></dt> +<dd><p> + Controls segment merging. Segment merging is an algorithm to + limit memory usage of the data race detection + algorithm. Disabling segment merging may improve the accuracy + of the so-called 'other segments' displayed in race reports + but can also trigger an out of memory error. + </p></dd> +<dt><span class="term"> + <code class="option">--shared-threshold=<n> [default: off]</code> + </span></dt> +<dd><p> + Print an error message if a reader lock has been held longer + than the specified time (in milliseconds). This option enables + detection of lock contention. + </p></dd> +<dt><span class="term"> + <code class="option">--show-confl-seg=<yes|no> [default: yes]</code> + </span></dt> +<dd><p> + Show conflicting segments in race reports. Since this + information can help to find the cause of a data race, this + option is enabled by default. Disabling this option makes the + output of DRD more compact. + </p></dd> +<dt><span class="term"> + <code class="option">--show-stack-usage=<yes|no> [default: no]</code> + </span></dt> +<dd><p> + Print stack usage at thread exit time. When a program creates + a large number of threads it becomes important to limit the + amount of virtual memory allocated for thread stacks. This + option makes it possible to observe how much stack memory has + been used by each thread of the the client program. Note: the + DRD tool allocates some temporary data on the client thread + stack itself. The space necessary for this temporary data must + be allocated by the client program, but is not included in the + reported stack usage. + </p></dd> +<dt><span class="term"> + <code class="option">--var-info=<yes|no> [default: no]</code> + </span></dt> +<dd><p> + Display the names of global, static and stack variables when a + data race is reported. While this information can be very + helpful, it is not loaded into memory by default. This is + because for big programs reading in all debug information at + once may cause an out of memory error. + </p></dd> +</dl> +</div> +<p> +The following options are available for monitoring the behavior of the +client program: +</p> +<div class="variablelist"> +<a name="drd.debugopts.list"></a><dl> +<dt><span class="term"> + <code class="option">--trace-addr=<address> [default: none]</code> + </span></dt> +<dd><p> + Trace all load and store activity for the specified + address. This option may be specified more than once. + </p></dd> +<dt><span class="term"> + <code class="option">--trace-barrier=<yes|no> [default: no]</code> + </span></dt> +<dd><p> + Trace all barrier activity. + </p></dd> +<dt><span class="term"> + <code class="option">--trace-cond=<yes|no> [default: no]</code> + </span></dt> +<dd><p> + Trace all condition variable activity. + </p></dd> +<dt><span class="term"> + <code class="option">--trace-fork-join=<yes|no> [default: no]</code> + </span></dt> +<dd><p> + Trace all thread creation and all thread termination events. + </p></dd> +<dt><span class="term"> + <code class="option">--trace-mutex=<yes|no> [default: no]</code> + </span></dt> +<dd><p> + Trace all mutex activity. + </p></dd> +<dt><span class="term"> + <code class="option">--trace-rwlock=<yes|no> [default: no]</code> + </span></dt> +<dd><p> + Trace all reader-writer lock activity. + </p></dd> +<dt><span class="term"> + <code class="option">--trace-semaphore=<yes|no> [default: no]</code> + </span></dt> +<dd><p> + Trace all semaphore activity. + </p></dd> +</dl> +</div> +</div> +<div class="sect2" lang="en"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="drd-manual.data-races"></a>8.2.2.Detected Errors: Data Races</h3></div></div></div> +<p> +DRD prints a message every time it detects a data race. Please keep +the following in mind when interpreting DRD's output: +</p> +<div class="itemizedlist"><ul type="disc"> +<li><p> + Every thread is assigned two <span class="emphasis"><em>thread ID's</em></span>: + one thread ID is assigned by the Valgrind core and one thread ID + is assigned by DRD. Both thread ID's start at one. Valgrind + thread ID's are reused when one thread finishes and another + thread is created. DRD does not reuse thread ID's. Thread ID's + are displayed e.g. as follows: 2/3, where the first number is + Valgrind's thread ID and the second number is the thread ID + assigned by DRD. + </p></li> +<li><p> + The term <span class="emphasis"><em>segment</em></span> refers to a consecutive + sequence of load, store and synchronization operations, all + issued by the same thread. A segment always starts and ends at a + synchronization operation. Data race analysis is performed + between segments instead of between individual load and store + operations because of performance reasons. + </p></li> +<li><p> + There are always at least two memory accesses involved in a data + race. Memory accesses involved in a data race are called + <span class="emphasis"><em>conflicting memory accesses</em></span>. DRD prints a + report for each memory access that conflicts with a past memory + access. + </p></li> +</ul></div> +<p> +</p> +<p> +Below you can find an example of a message printed by DRD when it +detects a data race: +</p> +<pre class="programlisting"> +$ valgrind --tool=drd --var-info=yes drd/tests/rwlock_race +... +==9466== Thread 3: +==9466== Conflicting load by thread 3/3 at 0x006020b8 size 4 +==9466== at 0x400B6C: thread_func (rwlock_race.c:29) +==9466== by 0x4C291DF: vg_thread_wrapper (drd_pthread_intercepts.c:186) +==9466== by 0x4E3403F: start_thread (in /lib64/libpthread-2.8.so) +==9466== by 0x53250CC: clone (in /lib64/libc-2.8.so) +==9466== Location 0x6020b8 is 0 bytes inside local var "s_racy" +==9466== declared at rwlock_race.c:18, in frame #0 of thread 3 +==9466== Other segment start (thread 2/2) +==9466== at 0x4C2847D: pthread_rwlock_rdlock* (drd_pthread_intercepts.c:813) +==9466== by 0x400B6B: thread_func (rwlock_race.c:28) +==9466== by 0x4C291DF: vg_thread_wrapper (drd_pthread_intercepts.c:186) +==9466== by 0x4E3403F: start_thread (in /lib64/libpthread-2.8.so) +==9466== by 0x53250CC: clone (in /lib64/libc-2.8.so) +==9466== Other segment end (thread 2/2) +==9466== at 0x4C28B54: pthread_rwlock_unlock* (drd_pthread_intercepts.c:912) +==9466== by 0x400B84: thread_func (rwlock_race.c:30) +==9466== by 0x4C291DF: vg_thread_wrapper (drd_pthread_intercepts.c:186) +==9466== by 0x4E3403F: start_thread (in /lib64/libpthread-2.8.so) +==9466== by 0x53250CC: clone (in /lib64/libc-2.8.so) +... +</pre> +<p> +The above report has the following meaning: +</p> +<div class="itemizedlist"><ul type="disc"> +<li><p> + The number in the column on the left is the process ID of the + process being analyzed by DRD. + </p></li> +<li><p> + The first line ("Thread 3") tells you Valgrind's thread ID for + the thread in which context the data race was detected. + </p></li> +<li><p> + The next line tells which kind of operation was performed (load + or store) and by which thread. Both Valgrind's and DRD's thread + ID's are displayed. On the same line the start address and the + number of bytes involved in the conflicting access are also + displayed. + </p></li> +<li><p> + Next, the call stack of the conflicting access is displayed. If + your program has been compiled with debug information (-g), this + call stack will include file names and line numbers. The two + bottommost frames in this call stack (<code class="function">clone</code> + and <code class="function">start_thread</code>) show how the NPTL starts + a thread. The third frame + (<code class="function">vg_thread_wrapper</code>) is added by DRD. The + fourth frame (<code class="function">thread_func</code>) is the first + interesting line because it shows the thread entry point, that + is the function that has been passed as the third argument to + <code class="function">pthread_create()</code>. + </p></li> +<li><p> + Next, the allocation context for the conflicting address is + displayed. For dynamically allocated data the allocation call + stack is shown. For static variables and stack variables the + allocation context is only shown when the option + <code class="computeroutput">--var-info=yes</code> has been + specified. Otherwise DRD will print <code class="computeroutput">Allocation + context: unknown</code>. + </p></li> +<li> +<p> + A conflicting access involves at least two memory accesses. For + one of these accesses an exact call stack is displayed, and for + the other accesses an approximate call stack is displayed, + namely the start and the end of the segments of the other + accesses. This information can be interpreted as follows: + </p> +<div class="orderedlist"><ol type="1"> +<li><p> + Start at the bottom of both call stacks, and count the + number stack frames with identical function name, file + name and line number. In the above example the three + bottommost frames are identical + (<code class="function">clone</code>, + <code class="function">start_thread</code> and + <code class="function">vg_thread_wrapper</code>). + </p></li> +<li><p> + The next higher stack frame in both call stacks now tells + you between in which source code region the other memory + access happened. The above output tells that the other + memory access involved in the data race happened between + source code lines 28 and 30 in file + <code class="computeroutput">rwlock_race.c</code>. + </p></li> +</ol></div> +<p> + </p> +</li> +</ul></div> +<p> +</p> +</div> +<div class="sect2" lang="en"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="drd-manual.lock-contention"></a>8.2.3.Detected Errors: Lock Contention</h3></div></div></div> +<p> +Threads must be able to make progress without being blocked for too +long by other threads. Sometimes a thread has to wait until a mutex or +reader-writer lock is unlocked by another thread. This is called +<span class="emphasis"><em>lock contention</em></span>. +</p> +<p> +Lock contention causes delays. Such delays should be as short as +possible. The two command line options +<code class="literal">--exclusive-threshold=<n></code> and +<code class="literal">--shared-threshold=<n></code> make it possible to +detect excessive lock contention by making DRD report any lock that +has been held longer than the specified threshold. An example: +</p> +<pre class="programlisting"> +$ valgrind --tool=drd --exclusive-threshold=10 drd/tests/hold_lock -i 500 +... +==10668== Acquired at: +==10668== at 0x4C267C8: pthread_mutex_lock (drd_pthread_intercepts.c:395) +==10668== by 0x400D92: main (hold_lock.c:51) +==10668== Lock on mutex 0x7fefffd50 was held during 503 ms (threshold: 10 ms). +==10668== at 0x4C26ADA: pthread_mutex_unlock (drd_pthread_intercepts.c:441) +==10668== by 0x400DB5: main (hold_lock.c:55) +... +</pre> +<p> +The <code class="literal">hold_lock</code> test program holds a lock as long as +specified by the <code class="literal">-i</code> (interval) argument. The DRD +output reports that the lock acquired at line 51 in source file +<code class="literal">hold_lock.c</code> and released at line 55 was held during +503 ms, while a threshold of 10 ms was specified to DRD. +</p> +</div> +<div class="sect2" lang="en"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="drd-manual.api-checks"></a>8.2.4.Detected Errors: Misuse of the POSIX threads API</h3></div></div></div> +<p> + DRD is able to detect and report the following misuses of the POSIX + threads API: + </p> +<div class="itemizedlist"><ul type="disc"> +<li><p> + Passing the address of one type of synchronization object + (e.g. a mutex) to a POSIX API call that expects a pointer to + another type of synchronization object (e.g. a condition + variable). + </p></li> +<li><p> + Attempts to unlock a mutex that has not been locked. + </p></li> +<li><p> + Attempts to unlock a mutex that was locked by another thread. + </p></li> +<li><p> + Attempts to lock a mutex of type + <code class="literal">PTHREAD_MUTEX_NORMAL</code> or a spinlock + recursively. + </p></li> +<li><p> + Destruction or deallocation of a locked mutex. + </p></li> +<li><p> + Sending a signal to a condition variable while no lock is held + on the mutex associated with the signal. + </p></li> +<li><p> + Calling <code class="function">pthread_cond_wait()</code> on a mutex + that is not locked, that is locked by another thread or that + has been locked recursively. + </p></li> +<li><p> + Associating two different mutexes with a condition variable + through <code class="function">pthread_cond_wait()</code>. + </p></li> +<li><p> + Destruction or deallocation of a condition variable that is + being waited upon. + </p></li> +<li><p> + Destruction or deallocation of a locked reader-writer lock. + </p></li> +<li><p> + Attempts to unlock a reader-writer lock that was not locked by + the calling thread. + </p></li> +<li><p> + Attempts to recursively lock a reader-writer lock exclusively. + </p></li> +<li><p> + Reinitialization of a mutex, condition variable, reader-writer + lock, semaphore or barrier. + </p></li> +<li><p> + Destruction or deallocation of a semaphore or barrier that is + being waited upon. + </p></li> +<li><p> + Exiting a thread without first unlocking the spinlocks, + mutexes or reader-writer locks that were locked by that + thread. + </p></li> +</ul></div> +<p> +</p> +</div> +<div class="sect2" lang="en"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="drd-manual.clientreqs"></a>8.2.5.Client Requests</h3></div></div></div> +<p> +Just as for other Valgrind tools it is possible to let a client +program interact with the DRD tool. +</p> +<p> +The interface between client programs and the DRD tool is defined in +the header file <code class="literal"><valgrind/drd.h></code>. The +available client requests are: +</p> +<div class="itemizedlist"><ul type="disc"> +<li><p> + <code class="varname">VG_USERREQ__DRD_GET_VALGRIND_THREAD_ID</code>. + Query the thread ID that was assigned by the Valgrind core to + the thread executing this client request. Valgrind's thread ID's + start at one and are recycled in case a thread stops. + </p></li> +<li><p> + <code class="varname">VG_USERREQ__DRD_GET_DRD_THREAD_ID</code>. + Query the thread ID that was assigned by DRD to + the thread executing this client request. DRD's thread ID's + start at one and are never recycled. + </p></li> +<li><p> + <code class="varname">VG_USERREQ__DRD_START_SUPPRESSION</code>. Some + applications contain intentional races. There exist + e.g. applications where the same value is assigned to a shared + variable from two different threads. It may be more convenient + to suppress such races than to solve these. This client request + allows to suppress such races. See also the macro + <code class="literal">DRD_IGNORE_VAR(x)</code> defined in + <code class="literal"><valgrind/drd.h></code>. + </p></li> +<li><p> + <code class="varname">VG_USERREQ__DRD_FINISH_SUPPRESSION</code>. Tell DRD + to no longer ignore data races in the address range that was + suppressed via + <code class="varname">VG_USERREQ__DRD_START_SUPPRESSION</code>. + </p></li> +<li><p> + <code class="varname">VG_USERREQ__DRD_START_TRACE_ADDR</code>. Trace all + load and store activity on the specified address range. When DRD + reports a data race on a specified variable, and it's not + immediately clear which source code statements triggered the + conflicting accesses, it can be helpful to trace all activity on + the offending memory location. See also the macro + <code class="literal">DRD_TRACE_VAR(x)</code> defined in + <code class="literal"><valgrind/drd.h></code>. + </p></li> +<li><p> + <code class="varname">VG_USERREQ__DRD_STOP_TRACE_ADDR</code>. Do no longer + trace load and store activity for the specified address range. + </p></li> +</ul></div> +<p> +</p> +<p> +Note: if you compiled Valgrind yourself, the header file +<code class="literal"><valgrind/drd.h></code> will have been installed in +the directory <code class="literal">/usr/include</code> by the command +<code class="literal">make install</code>. If you obtained Valgrind by +installing it as a package however, you will probably have to install +another package with a name like <code class="literal">valgrind-devel</code> +before Valgrind's header files are present. +</p> +</div> +<div class="sect2" lang="en"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="drd-manual.gnome"></a>8.2.6.Debugging GNOME Programs</h3></div></div></div> +<p> +GNOME applications use the threading primitives provided by the +<code class="computeroutput">glib</code> and +<code class="computeroutput">gthread</code> libraries. These libraries +are built on top of POSIX threads, and hence are directly supported by +DRD. Please keep in mind that you have to call +<code class="function">g_thread_init()</code> before creating any threads, or +DRD will report several data races on glib functions. See also the +<a href="http://library.gnome.org/devel/glib/stable/glib-Threads.html" target="_top">GLib +Reference Manual</a> for more information about +<code class="function">g_thread_init()</code>. +</p> +<p> +One of the many facilities provided by the <code class="literal">glib</code> +library is a block allocator, called <code class="literal">g_slice</code>. You +have to disable this block allocator when using DRD by adding the +following to the shell environment variables: +<code class="literal">G_SLICE=always-malloc</code>. See also the <a href="http://library.gnome.org/devel/glib/stable/glib-Memory-Slices.html" target="_top">GLib +Reference Manual</a> for more information. +</p> +</div> +<div class="sect2" lang="en"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="drd-manual.qt"></a>8.2.7.Debugging Qt Programs</h3></div></div></div> +<p> +The Qt library is the GUI library used by the KDE project. Currently +there are two versions of the Qt library in use: Qt3 by KDE 3 and Qt4 +by KDE 4. If possible, use Qt4 instead of Qt3. Qt3 is no longer +supported, and there are known problems with multithreading support in +Qt3. As an example, using QString objects in more than one thread will +trigger race reports (this has been confirmed by Trolltech -- see also +Trolltech task <a href="http://trolltech.com/developer/task-tracker/index_html" target="_top">#206152</a>). +</p> +<p> +Qt4 applications are supported by DRD, but only if the +<code class="literal">libqt4-debuginfo</code> package has been installed. Some +of the synchronization and threading primitives in Qt4 bypass the +POSIX threads library, and DRD can only intercept these if symbol +information for the Qt4 library is available. DRD won't tell you if it +has not been able to load the Qt4 debug information, but a huge number +of data races will be reported on data protected via +<code class="literal">QMutex</code> objects. +</p> +</div> +<div class="sect2" lang="en"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="drd-manual.boost.thread"></a>8.2.8.Debugging Boost.Thread Programs</h3></div></div></div> +<p> +The Boost.Thread library is the threading library included with the +cross-platform Boost Libraries. This threading library is an early +implementation of the upcoming C++0x threading library. +</p> +<p> +Applications that use the Boost.Thread library should run fine under DRD. +</p> +<p> +More information about Boost.Thread can be found here: +</p> +<div class="itemizedlist"><ul type="disc"> +<li><p> + Anthony Williams, <a href="http://www.boost.org/doc/libs/1_37_0/doc/html/thread.html" target="_top">Boost.Thread</a> + Library Documentation, Boost website, 2007. + </p></li> +<li><p> + Anthony Williams, <a href="http://www.ddj.com/cpp/211600441" target="_top">What's New in Boost + Threads?</a>, Recent changes to the Boost Thread library, + Dr. Dobbs Magazine, October 2008. + </p></li> +</ul></div> +<p> +</p> +</div> +<div class="sect2" lang="en"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="drd-manual.openmp"></a>8.2.9.Debugging OpenMP Programs</h3></div></div></div> +<p> +OpenMP stands for <span class="emphasis"><em>Open Multi-Processing</em></span>. The +OpenMP standard consists of a set of compiler directives for C, C++ +and Fortran programs that allows a compiler to transform a sequential +program into a parallel program. OpenMP is well suited for HPC +applications and allows to work at a higher level compared to direct +use of the POSIX threads API. While OpenMP ensures that the POSIX API +is used correctly, OpenMP programs can still contain data races. So it +makes sense to verify OpenMP programs with a thread checking tool. +</p> +<p> +DRD supports OpenMP shared-memory programs generated by gcc. The gcc +compiler supports OpenMP since version 4.2.0. Gcc's runtime support +for OpenMP programs is provided by a library called +<code class="literal">libgomp</code>. The synchronization primites implemented +in this library use Linux' futex system call directly, unless the +library has been configured with the +<code class="literal">--disable-linux-futex</code> flag. DRD only supports +libgomp libraries that have been configured with this flag and in +which symbol information is present. For most Linux distributions this +means that you will have to recompile gcc. See also the script +<code class="literal">drd/scripts/download-and-build-gcc</code> in the +Valgrind source tree for an example of how to compile gcc. You will +also have to make sure that the newly compiled +<code class="literal">libgomp.so</code> library is loaded when OpenMP programs +are started. This is possible by adding a line similar to the +following to your shell startup script: +</p> +<pre class="programlisting"> +export LD_LIBRARY_PATH=~/gcc-4.3.2/lib64:~/gcc-4.3.2/lib: +</pre> +<p> +As an example, the test OpenMP test program +<code class="literal">drd/tests/omp_matinv</code> triggers a data race +when the option -r has been specified on the command line. The data +race is triggered by the following code: +</p> +<pre class="programlisting"> +#pragma omp parallel for private(j) +for (j = 0; j < rows; j++) +{ + if (i != j) + { + const elem_t factor = a[j * cols + i]; + for (k = 0; k < cols; k++) + { + a[j * cols + k] -= a[i * cols + k] * factor; + } + } +} +</pre> +<p> +The above code is racy because the variable <code class="literal">k</code> has +not been declared private. DRD will print the following error message +for the above code: +</p> +<pre class="programlisting"> +$ valgrind --check-stack-var=yes --var-info=yes --tool=drd drd/tests/omp_matinv 3 -t 2 -r +... +Conflicting store by thread 1/1 at 0x7fefffbc4 size 4 + at 0x4014A0: gj.omp_fn.0 (omp_matinv.c:203) + by 0x401211: gj (omp_matinv.c:159) + by 0x40166A: invert_matrix (omp_matinv.c:238) + by 0x4019B4: main (omp_matinv.c:316) +Allocation context: unknown. +... +</pre> +<p> +In the above output the function name <code class="function">gj.omp_fn.0</code> +has been generated by gcc from the function name +<code class="function">gj</code>. Unfortunately the variable name +<code class="literal">k</code> is not shown as the allocation context -- it is +not clear to me whether this is caused by Valgrind or whether this is +caused by gcc. The most usable information in the above output is the +source file name and the line number where the data race has been detected +(<code class="literal">omp_matinv.c:203</code>). +</p> +<p> +Note: DRD reports errors on the <code class="literal">libgomp</code> library +included with gcc 4.2.0 up to and including 4.3.2. This might indicate +a race condition in the POSIX version of <code class="literal">libgomp</code>. +</p> +<p> +For more information about OpenMP, see also +<a href="http://openmp.org/" target="_top">openmp.org</a>. +</p> +</div> +<div class="sect2" lang="en"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="drd-manual.cust-mem-alloc"></a>8.2.10.DRD and Custom Memory Allocators</h3></div></div></div> +<p> +DRD tracks all memory allocation events that happen via either the +standard memory allocation and deallocation functions +(<code class="function">malloc</code>, <code class="function">free</code>, +<code class="function">new</code> and <code class="function">delete</code>) or via entry +and exit of stack frames. DRD uses memory allocation and deallocation +information for two purposes: +</p> +<div class="itemizedlist"><ul type="disc"> +<li><p> + To know where the scope ends of POSIX objects that have not been + destroyed explicitly. It is e.g. not required by the POSIX + threads standard to call + <code class="function">pthread_mutex_destroy()</code> before freeing the + memory in which a mutex object resides. + </p></li> +<li><p> + To know where the scope of variables ends. If e.g. heap memory + has been used by one thread, that thread frees that memory, and + another thread allocates and starts using that memory, no data + races must be reported for that memory. + </p></li> +</ul></div> +<p> +</p> +<p> +It is essential for correct operation of DRD that the tool knows about +memory allocation and deallocation events. DRD does not yet support +custom memory allocators, so you will have to make sure that any +program which runs under DRD uses the standard memory allocation +functions. As an example, the GNU libstdc++ library can be configured +to use standard memory allocation functions instead of memory pools by +setting the environment variable +<code class="literal">GLIBCXX_FORCE_NEW</code>. For more information, see also +the <a href="http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt04ch11.html" target="_top">libstdc++ +manual</a>. +</p> +</div> +<div class="sect2" lang="en"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="drd-manual.drd-versus-memcheck"></a>8.2.11.DRD Versus Memcheck</h3></div></div></div> +<p> +It is essential for correct operation of DRD that there are no memory +errors such as dangling pointers in the client program. Which means that +it is a good idea to make sure that your program is memcheck-clean +before you analyze it with DRD. It is possible however that some of +the memcheck reports are caused by data races. In this case it makes +sense to run DRD before memcheck. +</p> +<p> +So which tool should be run first ? In case both DRD and memcheck +complain about a program, a possible approach is to run both tools +alternatingly and to fix as many errors as possible after each run of +each tool until none of the two tools prints any more error messages. +</p> +</div> +<div class="sect2" lang="en"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="drd-manual.resource-requirements"></a>8.2.12.Resource Requirements</h3></div></div></div> +<p> +The requirements of DRD with regard to heap and stack memory and the +effect on the execution time of client programs are as follows: +</p> +<div class="itemizedlist"><ul type="disc"> +<li><p> + When running a program under DRD with default DRD options, + between 1.1 and 3.6 times more memory will be needed compared to + a native run of the client program. More memory will be needed + if loading debug information has been enabled + (<code class="literal">--var-info=yes</code>). + </p></li> +<li><p> + DRD allocates some of its temporary data structures on the stack + of the client program threads. This amount of data is limited to + 1 - 2 KB. Make sure that thread stacks are sufficiently large. + </p></li> +<li><p> + Most applications will run between 20 and 50 times slower under + DRD than a native single-threaded run. Applications such as + Firefox which perform very much mutex lock / unlock operations + however will run too slow to be usable under DRD. This issue + will be addressed in a future DRD version. + </p></li> +</ul></div> +<p> +</p> +</div> +<div class="sect2" lang="en"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="drd-manual.effective-use"></a>8.2.13.Hints and Tips for Effective Use of DRD</h3></div></div></div> +<p> +The following information may be helpful when using DRD: +</p> +<div class="itemizedlist"><ul type="disc"> +<li><p> + Make sure that debug information is present in the executable + being analysed, such that DRD can print function name and line + number information in stack traces. Most compilers can be told + to include debug information via compiler option + <code class="option">-g</code>. + </p></li> +<li><p> + Compile with flag <code class="option">-O1</code> instead of + <code class="option">-O0</code>. This will reduce the amount of generated + code, may reduce the amount of debug info and will speed up + DRD's processing of the client program. For more information, + see also <a href="manual-core.html#manual-core.started">Getting started</a>. + </p></li> +<li><p> + If DRD reports any errors on libraries that are part of your + Linux distribution like e.g. <code class="literal">libc.so</code> or + <code class="literal">libstdc++.so</code>, installing the debug packages + for these libraries will make the output of DRD a lot more + detailed. + </p></li> +<li> +<p> + When using C++, do not send output from more than one thread to + <code class="literal">std::cout</code>. Doing so would not only + generate multiple data race reports, it could also result in + output from several threads getting mixed up. Either use + <code class="function">printf()</code> or do the following: + </p> +<div class="orderedlist"><ol type="1"> +<li><p>Derive a class from <code class="literal">std::ostreambuf</code> + and let that class send output line by line to + <code class="literal">stdout</code>. This will avoid that individual + lines of text produced by different threads get mixed + up.</p></li> +<li><p>Create one instance of <code class="literal">std::ostream</code> + for each thread. This makes stream formatting settings + thread-local. Pass a per-thread instance of the class + derived from <code class="literal">std::ostreambuf</code> to the + constructor of each instance. </p></li> +<li><p>Let each thread send its output to its own instance of + <code class="literal">std::ostream</code> instead of + <code class="literal">std::cout</code>.</p></li> +</ol></div> +<p> + </p> +</li> +</ul></div> +<p> +</p> +</div> +</div> +<div class="sect1" lang="en"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both"> +<a name="drd-manual.Pthreads"></a>8.3.Using the POSIX Threads API Effectively</h2></div></div></div> +<div class="sect2" lang="en"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="drd-manual.mutex-types"></a>8.3.1.Mutex types</h3></div></div></div> +<p> +The Single UNIX Specification version two defines the following four +mutex types (see also the documentation of <a href="http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_mutexattr_settype.html" target="_top"><code class="function">pthread_mutexattr_settype()</code></a>): +</p> +<div class="itemizedlist"><ul type="disc"> +<li><p> + <span class="emphasis"><em>normal</em></span>, which means that no error checking + is performed, and that the mutex is non-recursive. + </p></li> +<li><p> + <span class="emphasis"><em>error checking</em></span>, which means that the mutex + is non-recursive and that error checking is performed. + </p></li> +<li><p> + <span class="emphasis"><em>recursive</em></span>, which means that a mutex may be + locked recursively. + </p></li> +<li><p> + <span class="emphasis"><em>default</em></span>, which means that error checking + behavior is undefined, and that the behavior for recursive + locking is also undefined. Or: portable code must neither + trigger error conditions through the Pthreads API nor attempt to + lock a mutex of default type recursively. + </p></li> +</ul></div> +<p> +</p> +<p> +In complex applications it is not always clear from beforehand which +mutex will be locked recursively and which mutex will not be locked +recursively. Attempts lock a non-recursive mutex recursively will +result in race conditions that are very hard to find without a thread +checking tool. So either use the error checking mutex type and +consistently check the return value of Pthread API mutex calls, or use +the recursive mutex type. +</p> +</div> +<div class="sect2" lang="en"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="drd-manual.condvar"></a>8.3.2.Condition variables</h3></div></div></div> +<p> +A condition variable allows one thread to wake up one or more other +threads. Condition variables are often used to notify one or more +threads about state changes of shared data. Unfortunately it is very +easy to introduce race conditions by using condition variables as the +only means of state information propagation. A better approach is to +let threads poll for changes of a state variable that is protected by +a mutex, and to use condition variables only as a thread wakeup +mechanism. See also the source file +<code class="computeroutput">drd/tests/monitor_example.cpp</code> for an +example of how to implement this concept in C++. The monitor concept +used in this example is a well known and very useful concept -- see +also Wikipedia for more information about the <a href="http://en.wikipedia.org/wiki/Monitor_(synchronization)" target="_top">monitor</a> +concept. +</p> +</div> +<div class="sect2" lang="en"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="drd-manual.pctw"></a>8.3.3.pthread_cond_timedwait() and timeouts</h3></div></div></div> +<p> +Historically the function +<code class="function">pthread_cond_timedwait()</code> only allowed the +specification of an absolute timeout, that is a timeout independent of +the time when this function was called. However, almost every call to +this function expresses a relative timeout. This typically happens by +passing the sum of +<code class="computeroutput">clock_gettime(CLOCK_REALTIME)</code> and a +relative timeout as the third argument. This approach is incorrect +since forward or backward clock adjustments by e.g. ntpd will affect +the timeout. A more reliable approach is as follows: +</p> +<div class="itemizedlist"><ul type="disc"> +<li><p> + When initializing a condition variable through + pthread_cond_init(), specify that the timeout of + pthread_cond_timedwait() will use the clock + <code class="literal">CLOCK_MONOTONIC</code> instead of + <code class="literal">CLOCK_REALTIME</code>. You can do this via + <code class="computeroutput">pthread_condattr_setclock(..., + CLOCK_MONOTONIC)</code>. + </p></li> +<li><p> + When calling <code class="function">pthread_cond_timedwait()</code>, pass + the sum of + <code class="computeroutput">clock_gettime(CLOCK_MONOTONIC)</code> + and a relative timeout as the third argument. + </p></li> +</ul></div> +<p> +See also +<code class="computeroutput">drd/tests/monitor_example.cpp</code> for an +example. +</p> +</div> +<div class="sect2" lang="en"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="drd-manual.naming-threads"></a>8.3.4.Assigning names to threads</h3></div></div></div> +<p> +Many applications log information about changes in internal or +external state to a file. When analyzing log files of a multithreaded +application it can be very convenient to know which thread logged +which information. One possible approach is to identify threads in +logging output by including the result of +<code class="function">pthread_self()</code> in every log line. However, this approach +has two disadvantages: there is no direct relationship between these +values and the source code and these values can be different in each +run. A better approach is to assign a brief name to each thread and to +include the assigned thread name in each log line. One possible +approach for managing thread names is as follows: +</p> +<div class="itemizedlist"><ul type="disc"> +<li><p> + Allocate a key for the pointer to the thread name through + <code class="function">pthread_key_create()</code>. + </p></li> +<li><p> + Just after thread creation, set the thread name through + <code class="function">pthread_setspecific()</code>. + </p></li> +<li><p> + In the code that generates the logging information, query the thread + name by calling <code class="function">pthread_getspecific()</code>. + </p></li> +</ul></div> +<p> + +</p> +</div> +</div> +<div class="sect1" lang="en"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both"> +<a name="drd-manual.limitations"></a>8.4.Limitations</h2></div></div></div> +<p>DRD currently has the following limitations:</p> +<div class="itemizedlist"><ul type="disc"> +<li><p> + DRD has only been tested on the Linux operating system, and not + on any of the other operating systems supported by + Valgrind. + </p></li> +<li><p> + Of the two POSIX threads implementations for Linux, only the + NPTL (Native POSIX Thread Library) is supported. The older + LinuxThreads library is not supported. + </p></li> +<li><p> + DRD, just like memcheck, will refuse to start on Linux + distributions where all symbol information has been removed from + ld.so. This is a.o. the case for the PPC editions of openSUSE + and Gentoo. You will have to install the glibc debuginfo package + on these platforms before you can use DRD. See also openSUSE bug + <a href="http://bugzilla.novell.com/show_bug.cgi?id=396197" target="_top"> + 396197</a> and Gentoo bug <a href="http://bugs.gentoo.org/214065" target="_top">214065</a>. + </p></li> +<li><p> + When DRD prints a report about a data race detected on a stack + variable in a parallel section of an OpenMP program, the report + will contain no information about the context of the data race + location (<code class="computeroutput">Allocation context: + unknown</code>). It's not yet clear whether this + behavior is caused by Valgrind or by gcc. + </p></li> +<li><p> + When address tracing is enabled, no information on atomic stores + will be displayed. This functionality is easy to add + however. Please contact the Valgrind authors if you would like + to see this functionality enabled. + </p></li> +<li><p> + If you compile the DRD source code yourself, you need gcc 3.0 or + later. Gcc 2.95 is not supported. + </p></li> +</ul></div> +</div> +<div class="sect1" lang="en"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both"> +<a name="drd-manual.feedback"></a>8.5.Feedback</h2></div></div></div> +<p> +If you have any comments, suggestions, feedback or bug reports about +DRD, feel free to either post a message on the Valgrind users mailing +list or to file a bug report. See also <a href="http://www.valgrind.org/" target="_top">http://www.valgrind.org/</a> for more information. +</p> +</div> +</div> +<div> +<br><table class="nav" width="100%" cellspacing="3" cellpadding="2" border="0" summary="Navigation footer"> +<tr> +<td rowspan="2" width="40%" align="left"> +<a accesskey="p" href="hg-manual.html"><<7.Helgrind: a thread error detector</a></td> +<td width="20%" align="center"><a accesskey="u" href="manual.html">Up</a></td> +<td rowspan="2" width="40%" align="right"><a accesskey="n" href="ms-manual.html">9.Massif: a heap profiler>></a> +</td> +</tr> +<tr><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td></tr> +</table> +</div> +</body> +</html> Added: trunk/docs/manual/pc-manual.html =================================================================== --- trunk/docs/manual/pc-manual.html (rev 0) +++ trunk/docs/manual/pc-manual.html 2009-01-03 20:46:17 UTC (rev 371) @@ -0,0 +1,418 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> +<title>10.Ptrcheck: an (experimental) pointer checking tool</title> +<link rel="stylesheet" href="vg_basic.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.69.1"> +<link rel="start" href="index.html" title="Valgrind Documentation"> +<link rel="up" href="manual.html" title="Valgrind User Manual"> +<link rel="prev" href="ms-manual.html" title="9.Massif: a heap profiler"> +<link rel="next" href="nl-manual.html" title='11.Nulgrind: the "null" tool'> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<div><table class="nav" width="100%" cellspacing="3" cellpadding="3" border="0" summary="Navigation header"><tr> +<td width="22px" align="center" valign="middle"><a accesskey="p" href="ms-manual.html"><img src="images/prev.png" width="18" height="21" border="0" alt="Prev"></a></td> +<td width="25px" align="center" valign="middle"><a accesskey="u" href="manual.html"><img src="images/up.png" width="21" height="18" border="0" alt="Up"></a></td> +<td width="31px" align="center" valign="middle"><a accesskey="h" href="index.html"><img src="images/home.png" width="27" height="20" border="0" alt="Up"></a></td> +<th align="center" valign="middle">Valgrind User Manual</th> +<td width="22px" align="center" valign="middle"><a accesskey="n" href="nl-manual.html"><img src="images/next.pn... [truncated message content] |