]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/valgrind/src/valgrind-3.6.0-svn/helgrind/hg_errors.c
a1ece966df8ab6cca1054b9ed460d233225b3f76
[l4.git] / l4 / pkg / valgrind / src / valgrind-3.6.0-svn / helgrind / hg_errors.c
1
2 /*--------------------------------------------------------------------*/
3 /*--- Error management for Helgrind.                               ---*/
4 /*---                                                  hg_errors.c ---*/
5 /*--------------------------------------------------------------------*/
6
7 /*
8    This file is part of Helgrind, a Valgrind tool for detecting errors
9    in threaded programs.
10
11    Copyright (C) 2007-2010 OpenWorks Ltd
12       info@open-works.co.uk
13
14    This program is free software; you can redistribute it and/or
15    modify it under the terms of the GNU General Public License as
16    published by the Free Software Foundation; either version 2 of the
17    License, or (at your option) any later version.
18
19    This program is distributed in the hope that it will be useful, but
20    WITHOUT ANY WARRANTY; without even the implied warranty of
21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22    General Public License for more details.
23
24    You should have received a copy of the GNU General Public License
25    along with this program; if not, write to the Free Software
26    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27    02111-1307, USA.
28
29    The GNU General Public License is contained in the file COPYING.
30 */
31
32 #include "pub_tool_basics.h"
33 #include "pub_tool_libcbase.h"
34 #include "pub_tool_libcassert.h"
35 #include "pub_tool_libcprint.h"
36 #include "pub_tool_execontext.h"
37 #include "pub_tool_errormgr.h"
38 #include "pub_tool_wordfm.h"
39 #include "pub_tool_xarray.h"
40 #include "pub_tool_debuginfo.h"
41 #include "pub_tool_threadstate.h"
42 #include "pub_tool_options.h"     // VG_(clo_xml)
43
44 #include "hg_basics.h"
45 #include "hg_wordset.h"
46 #include "hg_lock_n_thread.h"
47 #include "libhb.h"
48 #include "hg_errors.h"            /* self */
49
50
51 /*----------------------------------------------------------------*/
52 /*--- Error management -- storage                              ---*/
53 /*----------------------------------------------------------------*/
54
55 /* maps (by value) strings to a copy of them in ARENA_TOOL */
56
57 static WordFM* string_table = NULL;
58
59 ULong HG_(stats__string_table_queries) = 0;
60
61 ULong HG_(stats__string_table_get_map_size) ( void ) {
62    return string_table ? (ULong)VG_(sizeFM)(string_table) : 0;
63 }
64
65 static Word string_table_cmp ( UWord s1, UWord s2 ) {
66    return (Word)VG_(strcmp)( (HChar*)s1, (HChar*)s2 );
67 }
68
69 static HChar* string_table_strdup ( HChar* str ) {
70    HChar* copy = NULL;
71    HG_(stats__string_table_queries)++;
72    if (!str)
73       str = "(null)";
74    if (!string_table) {
75       string_table = VG_(newFM)( HG_(zalloc), "hg.sts.1",
76                                  HG_(free), string_table_cmp );
77       tl_assert(string_table);
78    }
79    if (VG_(lookupFM)( string_table,
80                       NULL, (Word*)&copy, (Word)str )) {
81       tl_assert(copy);
82       if (0) VG_(printf)("string_table_strdup: %p -> %p\n", str, copy );
83       return copy;
84    } else {
85       copy = HG_(strdup)("hg.sts.2", str);
86       tl_assert(copy);
87       VG_(addToFM)( string_table, (Word)copy, (Word)copy );
88       return copy;
89    }
90 }
91
92 /* maps from Lock .unique fields to LockP*s */
93
94 static WordFM* map_LockN_to_P = NULL;
95
96 ULong HG_(stats__LockN_to_P_queries) = 0;
97
98 ULong HG_(stats__LockN_to_P_get_map_size) ( void ) {
99    return map_LockN_to_P ? (ULong)VG_(sizeFM)(map_LockN_to_P) : 0;
100 }
101
102 static Word lock_unique_cmp ( UWord lk1W, UWord lk2W )
103 {
104    Lock* lk1 = (Lock*)lk1W;
105    Lock* lk2 = (Lock*)lk2W;
106    tl_assert( HG_(is_sane_LockNorP)(lk1) );
107    tl_assert( HG_(is_sane_LockNorP)(lk2) );
108    if (lk1->unique < lk2->unique) return -1;
109    if (lk1->unique > lk2->unique) return 1;
110    return 0;
111 }
112
113 static Lock* mk_LockP_from_LockN ( Lock* lkn )
114 {
115    Lock* lkp = NULL;
116    HG_(stats__LockN_to_P_queries)++;
117    tl_assert( HG_(is_sane_LockN)(lkn) );
118    if (!map_LockN_to_P) {
119       map_LockN_to_P = VG_(newFM)( HG_(zalloc), "hg.mLPfLN.1",
120                                    HG_(free), lock_unique_cmp );
121       tl_assert(map_LockN_to_P);
122    }
123    if (!VG_(lookupFM)( map_LockN_to_P, NULL, (Word*)&lkp, (Word)lkn)) {
124       lkp = HG_(zalloc)( "hg.mLPfLN.2", sizeof(Lock) );
125       *lkp = *lkn;
126       lkp->admin = NULL;
127       lkp->magic = LockP_MAGIC;
128       /* Forget about the bag of lock holders - don't copy that.
129          Also, acquired_at should be NULL whenever heldBy is, and vice
130          versa.  Also forget about the associated libhb synch object. */
131       lkp->heldW  = False;
132       lkp->heldBy = NULL;
133       lkp->acquired_at = NULL;
134       lkp->hbso = NULL;
135       VG_(addToFM)( map_LockN_to_P, (Word)lkp, (Word)lkp );
136    }
137    tl_assert( HG_(is_sane_LockP)(lkp) );
138    return lkp;
139 }
140
141 /* Errors:
142
143       race: program counter
144             read or write
145             data size
146             previous state
147             current state
148
149       FIXME: how does state printing interact with lockset gc?
150       Are the locksets in prev/curr state always valid?
151       Ditto question for the threadsets
152           ThreadSets - probably are always valid if Threads
153           are never thrown away.
154           LockSets - could at least print the lockset elements that
155           correspond to actual locks at the time of printing.  Hmm.
156 */
157
158 /* Error kinds */
159 typedef
160    enum {
161       XE_Race=1101,      // race
162       XE_UnlockUnlocked, // unlocking a not-locked lock
163       XE_UnlockForeign,  // unlocking a lock held by some other thread
164       XE_UnlockBogus,    // unlocking an address not known to be a lock
165       XE_PthAPIerror,    // error from the POSIX pthreads API
166       XE_LockOrder,      // lock order error
167       XE_Misc            // misc other error (w/ string to describe it)
168    }
169    XErrorTag;
170
171 /* Extra contexts for kinds */
172 typedef
173    struct  {
174       XErrorTag tag;
175       union {
176          struct {
177             Addr        data_addr;
178             Int         szB;
179             Bool        isWrite;
180             Thread*     thr;
181             /* descr1/2 provide a description of stack/global locs */
182             XArray*     descr1; /* XArray* of HChar */
183             XArray*     descr2; /* XArray* of HChar */
184             /* halloc/haddr/hszB describe the addr if it is a heap block. */
185             ExeContext* hctxt;
186             Addr        haddr;
187             SizeT       hszB;
188             /* h1_* and h2_* provide some description of a previously
189                observed access with which we are conflicting. */
190             Thread*     h1_ct; /* non-NULL means h1 info present */
191             ExeContext* h1_ct_mbsegstartEC;
192             ExeContext* h1_ct_mbsegendEC;
193             Thread*     h2_ct; /* non-NULL means h2 info present */
194             ExeContext* h2_ct_accEC;
195             Int         h2_ct_accSzB;
196             Bool        h2_ct_accIsW;
197          } Race;
198          struct {
199             Thread* thr;  /* doing the unlocking */
200             Lock*   lock; /* lock (that is already unlocked) */
201          } UnlockUnlocked;
202          struct {
203             Thread* thr;    /* doing the unlocking */
204             Thread* owner;  /* thread that actually holds the lock */
205             Lock*   lock;   /* lock (that is held by 'owner') */
206          } UnlockForeign;
207          struct {
208             Thread* thr;     /* doing the unlocking */
209             Addr    lock_ga; /* purported address of the lock */
210          } UnlockBogus;
211          struct {
212             Thread* thr; 
213             HChar*  fnname; /* persistent, in tool-arena */
214             Word    err;    /* pth error code */
215             HChar*  errstr; /* persistent, in tool-arena */
216          } PthAPIerror;
217          struct {
218             Thread*     thr;
219             Addr        before_ga; /* always locked first in prog. history */
220             Addr        after_ga;
221             ExeContext* before_ec;
222             ExeContext* after_ec;
223          } LockOrder;
224          struct {
225             Thread* thr;
226             HChar*  errstr; /* persistent, in tool-arena */
227          } Misc;
228       } XE;
229    }
230    XError;
231
232 static void init_XError ( XError* xe ) {
233    VG_(memset)(xe, 0, sizeof(*xe) );
234    xe->tag = XE_Race-1; /* bogus */
235 }
236
237
238 /* Extensions of suppressions */
239 typedef
240    enum {
241       XS_Race=1201, /* race */
242       XS_FreeMemLock,
243       XS_UnlockUnlocked,
244       XS_UnlockForeign,
245       XS_UnlockBogus,
246       XS_PthAPIerror,
247       XS_LockOrder,
248       XS_Misc
249    }
250    XSuppTag;
251
252
253 /* Updates the copy with address info if necessary. */
254 UInt HG_(update_extra) ( Error* err )
255 {
256    XError* xe = (XError*)VG_(get_error_extra)(err);
257    tl_assert(xe);
258    //if (extra != NULL && Undescribed == extra->addrinfo.akind) {
259    //   describe_addr ( VG_(get_error_address)(err), &(extra->addrinfo) );
260    //}
261
262    if (xe->tag == XE_Race) {
263
264       /* See if we can come up with a source level description of the
265          raced-upon address.  This is potentially expensive, which is
266          why it's only done at the update_extra point, not when the
267          error is initially created. */
268       static Int xxx = 0;
269       xxx++;
270       if (0)
271          VG_(printf)("HG_(update_extra): "
272                      "%d conflicting-event queries\n", xxx);
273
274       tl_assert(!xe->XE.Race.hctxt);
275       tl_assert(!xe->XE.Race.descr1);
276       tl_assert(!xe->XE.Race.descr2);
277
278       /* First, see if it's in any heap block.  Unfortunately this
279          means a linear search through all allocated heap blocks.  The
280          assertion says that if it's detected as a heap block, then we
281          must have an allocation context for it, since all heap blocks
282          should have an allocation context. */
283       Bool is_heapblock
284          = HG_(mm_find_containing_block)( 
285               &xe->XE.Race.hctxt, &xe->XE.Race.haddr, &xe->XE.Race.hszB,
286               xe->XE.Race.data_addr
287            );
288       tl_assert(is_heapblock == (xe->XE.Race.hctxt != NULL));
289
290       if (!xe->XE.Race.hctxt) {
291          /* It's not in any heap block.  See if we can map it to a
292             stack or global symbol. */
293
294          xe->XE.Race.descr1
295             = VG_(newXA)( HG_(zalloc), "hg.update_extra.Race.descr1",
296                           HG_(free), sizeof(HChar) );
297          xe->XE.Race.descr2
298             = VG_(newXA)( HG_(zalloc), "hg.update_extra.Race.descr2",
299                           HG_(free), sizeof(HChar) );
300
301          (void) VG_(get_data_description)( xe->XE.Race.descr1,
302                                            xe->XE.Race.descr2,
303                                            xe->XE.Race.data_addr );
304
305          /* If there's nothing in descr1/2, free it.  Why is it safe to
306             to VG_(indexXA) at zero here?  Because
307             VG_(get_data_description) guarantees to zero terminate
308             descr1/2 regardless of the outcome of the call.  So there's
309             always at least one element in each XA after the call.
310          */
311          if (0 == VG_(strlen)( VG_(indexXA)( xe->XE.Race.descr1, 0 ))) {
312             VG_(deleteXA)( xe->XE.Race.descr1 );
313             xe->XE.Race.descr1 = NULL;
314          }
315          if (0 == VG_(strlen)( VG_(indexXA)( xe->XE.Race.descr2, 0 ))) {
316             VG_(deleteXA)( xe->XE.Race.descr2 );
317             xe->XE.Race.descr2 = NULL;
318          }
319       }
320
321       /* And poke around in the conflicting-event map, to see if we
322          can rustle up a plausible-looking conflicting memory access
323          to show. */
324       if (HG_(clo_history_level) >= 2) { 
325          Thr* thrp = NULL;
326          ExeContext* wherep = NULL;
327          Addr  acc_addr = xe->XE.Race.data_addr;
328          Int   acc_szB  = xe->XE.Race.szB;
329          Thr*  acc_thr  = xe->XE.Race.thr->hbthr;
330          Bool  acc_isW  = xe->XE.Race.isWrite;
331          SizeT conf_szB = 0;
332          Bool  conf_isW = False;
333          tl_assert(!xe->XE.Race.h2_ct_accEC);
334          tl_assert(!xe->XE.Race.h2_ct);
335          if (libhb_event_map_lookup(
336                 &wherep, &thrp, &conf_szB, &conf_isW,
337                 acc_thr, acc_addr, acc_szB, acc_isW )) {
338             Thread* threadp;
339             tl_assert(wherep);
340             tl_assert(thrp);
341             threadp = libhb_get_Thr_opaque( thrp );
342             tl_assert(threadp);
343             xe->XE.Race.h2_ct_accEC  = wherep;
344             xe->XE.Race.h2_ct        = threadp;
345             xe->XE.Race.h2_ct_accSzB = (Int)conf_szB;
346             xe->XE.Race.h2_ct_accIsW = conf_isW;
347         }
348       }
349
350       // both NULL or both non-NULL
351       tl_assert( (!!xe->XE.Race.h2_ct) == (!!xe->XE.Race.h2_ct_accEC) );
352    }
353
354    return sizeof(XError);
355 }
356
357 void HG_(record_error_Race) ( Thread* thr, 
358                               Addr data_addr, Int szB, Bool isWrite,
359                               Thread* h1_ct,
360                               ExeContext* h1_ct_segstart,
361                               ExeContext* h1_ct_mbsegendEC )
362 {
363    XError xe;
364    tl_assert( HG_(is_sane_Thread)(thr) );
365
366 #  if defined(VGO_linux)
367    /* Skip any races on locations apparently in GOTPLT sections.  This
368       is said to be caused by ld.so poking PLT table entries (or
369       whatever) when it writes the resolved address of a dynamically
370       linked routine, into the table (or whatever) when it is called
371       for the first time. */
372    {
373      VgSectKind sect = VG_(DebugInfo_sect_kind)( NULL, 0, data_addr );
374      if (0) VG_(printf)("XXXXXXXXX RACE on %#lx %s\n",
375                         data_addr, VG_(pp_SectKind)(sect));
376      /* SectPLT is required on ???-linux */
377      if (sect == Vg_SectGOTPLT) return;
378      /* SectPLT is required on ppc32/64-linux */
379      if (sect == Vg_SectPLT) return;
380    }
381 #  endif
382
383    init_XError(&xe);
384    xe.tag = XE_Race;
385    xe.XE.Race.data_addr   = data_addr;
386    xe.XE.Race.szB         = szB;
387    xe.XE.Race.isWrite     = isWrite;
388    xe.XE.Race.thr         = thr;
389    tl_assert(isWrite == False || isWrite == True);
390    tl_assert(szB == 8 || szB == 4 || szB == 2 || szB == 1);
391    /* Skip on the detailed description of the raced-on address at this
392       point; it's expensive.  Leave it for the update_extra function
393       if we ever make it that far. */
394    tl_assert(xe.XE.Race.descr1 == NULL);
395    tl_assert(xe.XE.Race.descr2 == NULL);
396    // FIXME: tid vs thr
397    // Skip on any of the conflicting-access info at this point.
398    // It's expensive to obtain, and this error is more likely than
399    // not to be discarded.  We'll fill these fields in in 
400    // HG_(update_extra) just above, assuming the error ever makes
401    // it that far (unlikely).
402    xe.XE.Race.h2_ct_accSzB = 0;
403    xe.XE.Race.h2_ct_accIsW = False;
404    xe.XE.Race.h2_ct_accEC  = NULL;
405    xe.XE.Race.h2_ct        = NULL;
406    tl_assert( HG_(is_sane_ThreadId)(thr->coretid) );
407    tl_assert( thr->coretid != VG_INVALID_THREADID );
408
409    xe.XE.Race.h1_ct              = h1_ct;
410    xe.XE.Race.h1_ct_mbsegstartEC = h1_ct_segstart;
411    xe.XE.Race.h1_ct_mbsegendEC   = h1_ct_mbsegendEC;
412
413    VG_(maybe_record_error)( thr->coretid,
414                             XE_Race, data_addr, NULL, &xe );
415 }
416
417 void HG_(record_error_UnlockUnlocked) ( Thread* thr, Lock* lk )
418 {
419    XError xe;
420    tl_assert( HG_(is_sane_Thread)(thr) );
421    tl_assert( HG_(is_sane_LockN)(lk) );
422    init_XError(&xe);
423    xe.tag = XE_UnlockUnlocked;
424    xe.XE.UnlockUnlocked.thr  = thr;
425    xe.XE.UnlockUnlocked.lock = mk_LockP_from_LockN(lk);
426    // FIXME: tid vs thr
427    tl_assert( HG_(is_sane_ThreadId)(thr->coretid) );
428    tl_assert( thr->coretid != VG_INVALID_THREADID );
429    VG_(maybe_record_error)( thr->coretid,
430                             XE_UnlockUnlocked, 0, NULL, &xe );
431 }
432
433 void HG_(record_error_UnlockForeign) ( Thread* thr,
434                                        Thread* owner, Lock* lk )
435 {
436    XError xe;
437    tl_assert( HG_(is_sane_Thread)(thr) );
438    tl_assert( HG_(is_sane_Thread)(owner) );
439    tl_assert( HG_(is_sane_LockN)(lk) );
440    init_XError(&xe);
441    xe.tag = XE_UnlockForeign;
442    xe.XE.UnlockForeign.thr   = thr;
443    xe.XE.UnlockForeign.owner = owner;
444    xe.XE.UnlockForeign.lock  = mk_LockP_from_LockN(lk);
445    // FIXME: tid vs thr
446    tl_assert( HG_(is_sane_ThreadId)(thr->coretid) );
447    tl_assert( thr->coretid != VG_INVALID_THREADID );
448    VG_(maybe_record_error)( thr->coretid,
449                             XE_UnlockForeign, 0, NULL, &xe );
450 }
451
452 void HG_(record_error_UnlockBogus) ( Thread* thr, Addr lock_ga )
453 {
454    XError xe;
455    tl_assert( HG_(is_sane_Thread)(thr) );
456    init_XError(&xe);
457    xe.tag = XE_UnlockBogus;
458    xe.XE.UnlockBogus.thr     = thr;
459    xe.XE.UnlockBogus.lock_ga = lock_ga;
460    // FIXME: tid vs thr
461    tl_assert( HG_(is_sane_ThreadId)(thr->coretid) );
462    tl_assert( thr->coretid != VG_INVALID_THREADID );
463    VG_(maybe_record_error)( thr->coretid,
464                             XE_UnlockBogus, 0, NULL, &xe );
465 }
466
467 void HG_(record_error_LockOrder)(
468         Thread* thr, Addr before_ga, Addr after_ga,
469         ExeContext* before_ec, ExeContext* after_ec 
470      )
471 {
472    XError xe;
473    tl_assert( HG_(is_sane_Thread)(thr) );
474    if (!HG_(clo_track_lockorders))
475       return;
476    init_XError(&xe);
477    xe.tag = XE_LockOrder;
478    xe.XE.LockOrder.thr       = thr;
479    xe.XE.LockOrder.before_ga = before_ga;
480    xe.XE.LockOrder.before_ec = before_ec;
481    xe.XE.LockOrder.after_ga  = after_ga;
482    xe.XE.LockOrder.after_ec  = after_ec;
483    // FIXME: tid vs thr
484    tl_assert( HG_(is_sane_ThreadId)(thr->coretid) );
485    tl_assert( thr->coretid != VG_INVALID_THREADID );
486    VG_(maybe_record_error)( thr->coretid,
487                             XE_LockOrder, 0, NULL, &xe );
488 }
489
490 void HG_(record_error_PthAPIerror) ( Thread* thr, HChar* fnname, 
491                                      Word err, HChar* errstr )
492 {
493    XError xe;
494    tl_assert( HG_(is_sane_Thread)(thr) );
495    tl_assert(fnname);
496    tl_assert(errstr);
497    init_XError(&xe);
498    xe.tag = XE_PthAPIerror;
499    xe.XE.PthAPIerror.thr    = thr;
500    xe.XE.PthAPIerror.fnname = string_table_strdup(fnname);
501    xe.XE.PthAPIerror.err    = err;
502    xe.XE.PthAPIerror.errstr = string_table_strdup(errstr);
503    // FIXME: tid vs thr
504    tl_assert( HG_(is_sane_ThreadId)(thr->coretid) );
505    tl_assert( thr->coretid != VG_INVALID_THREADID );
506    VG_(maybe_record_error)( thr->coretid,
507                             XE_PthAPIerror, 0, NULL, &xe );
508 }
509
510 void HG_(record_error_Misc) ( Thread* thr, HChar* errstr )
511 {
512    XError xe;
513    tl_assert( HG_(is_sane_Thread)(thr) );
514    tl_assert(errstr);
515    init_XError(&xe);
516    xe.tag = XE_Misc;
517    xe.XE.Misc.thr    = thr;
518    xe.XE.Misc.errstr = string_table_strdup(errstr);
519    // FIXME: tid vs thr
520    tl_assert( HG_(is_sane_ThreadId)(thr->coretid) );
521    tl_assert( thr->coretid != VG_INVALID_THREADID );
522    VG_(maybe_record_error)( thr->coretid,
523                             XE_Misc, 0, NULL, &xe );
524 }
525
526 Bool HG_(eq_Error) ( VgRes not_used, Error* e1, Error* e2 )
527 {
528    XError *xe1, *xe2;
529
530    tl_assert(VG_(get_error_kind)(e1) == VG_(get_error_kind)(e2));
531
532    xe1 = (XError*)VG_(get_error_extra)(e1);
533    xe2 = (XError*)VG_(get_error_extra)(e2);
534    tl_assert(xe1);
535    tl_assert(xe2);
536
537    switch (VG_(get_error_kind)(e1)) {
538       case XE_Race:
539          return xe1->XE.Race.szB == xe2->XE.Race.szB
540                 && xe1->XE.Race.isWrite == xe2->XE.Race.isWrite
541                 && (HG_(clo_cmp_race_err_addrs)
542                        ? xe1->XE.Race.data_addr == xe2->XE.Race.data_addr
543                        : True);
544       case XE_UnlockUnlocked:
545          return xe1->XE.UnlockUnlocked.thr == xe2->XE.UnlockUnlocked.thr
546                 && xe1->XE.UnlockUnlocked.lock == xe2->XE.UnlockUnlocked.lock;
547       case XE_UnlockForeign:
548          return xe1->XE.UnlockForeign.thr == xe2->XE.UnlockForeign.thr
549                 && xe1->XE.UnlockForeign.owner == xe2->XE.UnlockForeign.owner
550                 && xe1->XE.UnlockForeign.lock == xe2->XE.UnlockForeign.lock;
551       case XE_UnlockBogus:
552          return xe1->XE.UnlockBogus.thr == xe2->XE.UnlockBogus.thr
553                 && xe1->XE.UnlockBogus.lock_ga == xe2->XE.UnlockBogus.lock_ga;
554       case XE_PthAPIerror:
555          return xe1->XE.PthAPIerror.thr == xe2->XE.PthAPIerror.thr
556                 && 0==VG_(strcmp)(xe1->XE.PthAPIerror.fnname,
557                                   xe2->XE.PthAPIerror.fnname)
558                 && xe1->XE.PthAPIerror.err == xe2->XE.PthAPIerror.err;
559       case XE_LockOrder:
560          return xe1->XE.LockOrder.thr == xe2->XE.LockOrder.thr;
561       case XE_Misc:
562          return xe1->XE.Misc.thr == xe2->XE.Misc.thr
563                 && 0==VG_(strcmp)(xe1->XE.Misc.errstr, xe2->XE.Misc.errstr);
564       default:
565          tl_assert(0);
566    }
567
568    /*NOTREACHED*/
569    tl_assert(0);
570 }
571
572
573 /*----------------------------------------------------------------*/
574 /*--- Error management -- printing                             ---*/
575 /*----------------------------------------------------------------*/
576
577 /* Do a printf-style operation on either the XML or normal output
578    channel, depending on the setting of VG_(clo_xml).
579 */
580 static void emit_WRK ( HChar* format, va_list vargs )
581 {
582    if (VG_(clo_xml)) {
583       VG_(vprintf_xml)(format, vargs);
584    } else {
585       VG_(vmessage)(Vg_UserMsg, format, vargs);
586    }
587 }
588 static void emit ( HChar* format, ... ) PRINTF_CHECK(1, 2);
589 static void emit ( HChar* format, ... )
590 {
591    va_list vargs;
592    va_start(vargs, format);
593    emit_WRK(format, vargs);
594    va_end(vargs);
595 }
596 static void emit_no_f_c ( HChar* format, ... )
597 {
598    va_list vargs;
599    va_start(vargs, format);
600    emit_WRK(format, vargs);
601    va_end(vargs);
602 }
603
604
605 /* Announce (that is, print the point-of-creation) of 'thr'.  Only do
606    this once, as we only want to see these announcements once per
607    thread.  Returned Bool indicates whether or not an announcement was
608    made.
609 */
610 static Bool announce_one_thread ( Thread* thr ) 
611 {
612    tl_assert(HG_(is_sane_Thread)(thr));
613    tl_assert(thr->errmsg_index >= 1);
614    if (thr->announced)
615       return False;
616
617    if (VG_(clo_xml)) {
618
619       VG_(printf_xml)("<announcethread>\n");
620       VG_(printf_xml)("  <hthreadid>%d</hthreadid>\n", thr->errmsg_index);
621       if (thr->errmsg_index == 1) {
622          tl_assert(thr->created_at == NULL);
623          VG_(printf_xml)("  <isrootthread></isrootthread>\n");
624       } else {
625          tl_assert(thr->created_at != NULL);
626          VG_(pp_ExeContext)( thr->created_at );
627       }
628       VG_(printf_xml)("</announcethread>\n\n");
629
630    } else {
631
632       if (thr->errmsg_index == 1) {
633          tl_assert(thr->created_at == NULL);
634          VG_(message)(Vg_UserMsg, 
635                       "Thread #%d is the program's root thread\n",
636                        thr->errmsg_index);
637       } else {
638          tl_assert(thr->created_at != NULL);
639          VG_(message)(Vg_UserMsg, "Thread #%d was created\n",
640                                   thr->errmsg_index);
641          VG_(pp_ExeContext)( thr->created_at );
642       }
643       VG_(message)(Vg_UserMsg, "\n");
644
645    }
646
647    thr->announced = True;
648    return True;
649 }
650
651
652 /* This is the "this error is due to be printed shortly; so have a
653    look at it any print any preamble you want" function.  We use it to
654    announce any previously un-announced threads in the upcoming error
655    message.
656 */
657 void HG_(before_pp_Error) ( Error* err )
658 {
659    XError* xe;
660    tl_assert(err);
661    xe = (XError*)VG_(get_error_extra)(err);
662    tl_assert(xe);
663
664    switch (VG_(get_error_kind)(err)) {
665       case XE_Misc:
666          announce_one_thread( xe->XE.Misc.thr );
667          break;
668       case XE_LockOrder:
669          announce_one_thread( xe->XE.LockOrder.thr );
670          break;
671       case XE_PthAPIerror:
672          announce_one_thread( xe->XE.PthAPIerror.thr );
673          break;
674       case XE_UnlockBogus:
675          announce_one_thread( xe->XE.UnlockBogus.thr );
676          break;
677       case XE_UnlockForeign:
678          announce_one_thread( xe->XE.UnlockForeign.thr );
679          announce_one_thread( xe->XE.UnlockForeign.owner );
680          break;
681       case XE_UnlockUnlocked:
682          announce_one_thread( xe->XE.UnlockUnlocked.thr );
683          break;
684       case XE_Race:
685          announce_one_thread( xe->XE.Race.thr );
686          if (xe->XE.Race.h2_ct)
687             announce_one_thread( xe->XE.Race.h2_ct );
688          if (xe->XE.Race.h1_ct)
689             announce_one_thread( xe->XE.Race.h1_ct );
690          break;
691       default:
692          tl_assert(0);
693    }
694 }
695
696 void HG_(pp_Error) ( Error* err )
697 {
698    const Bool xml = VG_(clo_xml); /* a shorthand, that's all */
699
700    XError *xe = (XError*)VG_(get_error_extra)(err);
701    tl_assert(xe);
702
703    switch (VG_(get_error_kind)(err)) {
704
705    case XE_Misc: {
706       tl_assert( HG_(is_sane_Thread)( xe->XE.Misc.thr ) );
707
708       if (xml) {
709
710          emit( "  <kind>Misc</kind>\n");
711          emit( "  <xwhat>\n" );
712          emit( "    <text>Thread #%d: %s</text>\n",
713                (Int)xe->XE.Misc.thr->errmsg_index,
714                xe->XE.Misc.errstr );
715          emit( "    <hthreadid>%d</hthreadid>\n",
716                (Int)xe->XE.Misc.thr->errmsg_index );
717          emit( "  </xwhat>\n" );
718          VG_(pp_ExeContext)( VG_(get_error_where)(err) );
719
720       } else {
721
722          emit( "Thread #%d: %s\n",
723                (Int)xe->XE.Misc.thr->errmsg_index,
724                xe->XE.Misc.errstr );
725          VG_(pp_ExeContext)( VG_(get_error_where)(err) );
726
727       }
728       break;
729    }
730
731    case XE_LockOrder: {
732       tl_assert( HG_(is_sane_Thread)( xe->XE.LockOrder.thr ) );
733
734       if (xml) {
735
736          emit( "  <kind>LockOrder</kind>\n");
737          emit( "  <xwhat>\n" );
738          emit( "    <text>Thread #%d: lock order \"%p before %p\" "
739                     "violated</text>\n",
740                (Int)xe->XE.LockOrder.thr->errmsg_index,
741                (void*)xe->XE.LockOrder.before_ga,
742                (void*)xe->XE.LockOrder.after_ga );
743          emit( "    <hthreadid>%d</hthreadid>\n",
744                (Int)xe->XE.LockOrder.thr->errmsg_index );
745          emit( "  </xwhat>\n" );
746          VG_(pp_ExeContext)( VG_(get_error_where)(err) );
747          if (xe->XE.LockOrder.before_ec && xe->XE.LockOrder.after_ec) {
748             emit( "  <auxwhat>Required order was established by "
749                   "acquisition of lock at %p</auxwhat>\n",
750                   (void*)xe->XE.LockOrder.before_ga );
751             VG_(pp_ExeContext)( xe->XE.LockOrder.before_ec );
752             emit( "  <auxwhat>followed by a later acquisition "
753                   "of lock at %p</auxwhat>\n",
754                   (void*)xe->XE.LockOrder.after_ga );
755             VG_(pp_ExeContext)( xe->XE.LockOrder.after_ec );
756          }
757
758       } else {
759
760          emit( "Thread #%d: lock order \"%p before %p\" violated\n",
761                (Int)xe->XE.LockOrder.thr->errmsg_index,
762                (void*)xe->XE.LockOrder.before_ga,
763                (void*)xe->XE.LockOrder.after_ga );
764          VG_(pp_ExeContext)( VG_(get_error_where)(err) );
765          if (xe->XE.LockOrder.before_ec && xe->XE.LockOrder.after_ec) {
766             emit( "  Required order was established by "
767                   "acquisition of lock at %p\n",
768                   (void*)xe->XE.LockOrder.before_ga );
769             VG_(pp_ExeContext)( xe->XE.LockOrder.before_ec );
770             emit( "  followed by a later acquisition of lock at %p\n",
771                   (void*)xe->XE.LockOrder.after_ga );
772             VG_(pp_ExeContext)( xe->XE.LockOrder.after_ec );
773          }
774
775       }
776
777       break;
778    }
779
780    case XE_PthAPIerror: {
781       tl_assert( HG_(is_sane_Thread)( xe->XE.PthAPIerror.thr ) );
782
783       if (xml) {
784
785          emit( "  <kind>PthAPIerror</kind>\n");
786          emit( "  <xwhat>\n" );
787          emit_no_f_c(
788             "    <text>Thread #%d's call to %t failed</text>\n",
789             (Int)xe->XE.PthAPIerror.thr->errmsg_index,
790             xe->XE.PthAPIerror.fnname );
791          emit( "    <hthreadid>%d</hthreadid>\n",
792                (Int)xe->XE.PthAPIerror.thr->errmsg_index );
793          emit( "  </xwhat>\n" );
794          emit( "  <what>with error code %ld (%s)</what>\n",
795                xe->XE.PthAPIerror.err, xe->XE.PthAPIerror.errstr );
796          VG_(pp_ExeContext)( VG_(get_error_where)(err) );
797
798       } else {
799
800          emit_no_f_c( "Thread #%d's call to %t failed\n",
801                       (Int)xe->XE.PthAPIerror.thr->errmsg_index,
802                       xe->XE.PthAPIerror.fnname );
803          emit( "   with error code %ld (%s)\n",
804                xe->XE.PthAPIerror.err, xe->XE.PthAPIerror.errstr );
805          VG_(pp_ExeContext)( VG_(get_error_where)(err) );
806
807       }
808
809       break;
810    }
811
812    case XE_UnlockBogus: {
813       tl_assert( HG_(is_sane_Thread)( xe->XE.UnlockBogus.thr ) );
814
815       if (xml) {
816
817          emit( "  <kind>UnlockBogus</kind>\n");
818          emit( "  <xwhat>\n" );
819          emit( "    <text>Thread #%d unlocked an invalid "
820                     "lock at %p</text>\n",
821                (Int)xe->XE.UnlockBogus.thr->errmsg_index,
822                (void*)xe->XE.UnlockBogus.lock_ga );
823          emit( "    <hthreadid>%d</hthreadid>\n",
824                (Int)xe->XE.UnlockBogus.thr->errmsg_index );
825          emit( "  </xwhat>\n" );
826          VG_(pp_ExeContext)( VG_(get_error_where)(err) );
827
828       } else {
829
830          emit( "Thread #%d unlocked an invalid lock at %p\n",
831                (Int)xe->XE.UnlockBogus.thr->errmsg_index,
832                (void*)xe->XE.UnlockBogus.lock_ga );
833          VG_(pp_ExeContext)( VG_(get_error_where)(err) );
834
835       }
836
837       break;
838    }
839
840    case XE_UnlockForeign: {
841       tl_assert( HG_(is_sane_LockP)( xe->XE.UnlockForeign.lock ) );
842       tl_assert( HG_(is_sane_Thread)( xe->XE.UnlockForeign.owner ) );
843       tl_assert( HG_(is_sane_Thread)( xe->XE.UnlockForeign.thr ) );
844
845       if (xml) {
846
847          emit( "  <kind>UnlockForeign</kind>\n");
848          emit( "  <xwhat>\n" );
849          emit( "    <text>Thread #%d unlocked lock at %p "
850                     "currently held by thread #%d</text>\n",
851                (Int)xe->XE.UnlockForeign.thr->errmsg_index,
852                (void*)xe->XE.UnlockForeign.lock->guestaddr,
853                (Int)xe->XE.UnlockForeign.owner->errmsg_index );
854          emit( "    <hthreadid>%d</hthreadid>\n",
855                (Int)xe->XE.UnlockForeign.thr->errmsg_index );
856          emit( "    <hthreadid>%d</hthreadid>\n",
857                (Int)xe->XE.UnlockForeign.owner->errmsg_index );
858          emit( "  </xwhat>\n" );
859          VG_(pp_ExeContext)( VG_(get_error_where)(err) );
860
861          if (xe->XE.UnlockForeign.lock->appeared_at) {
862             emit( "  <auxwhat>Lock at %p was first observed</auxwhat>\n",
863                   (void*)xe->XE.UnlockForeign.lock->guestaddr );
864             VG_(pp_ExeContext)( xe->XE.UnlockForeign.lock->appeared_at );
865          }
866
867       } else {
868
869          emit( "Thread #%d unlocked lock at %p "
870                "currently held by thread #%d\n",
871                (Int)xe->XE.UnlockForeign.thr->errmsg_index,
872                (void*)xe->XE.UnlockForeign.lock->guestaddr,
873                (Int)xe->XE.UnlockForeign.owner->errmsg_index );
874          VG_(pp_ExeContext)( VG_(get_error_where)(err) );
875          if (xe->XE.UnlockForeign.lock->appeared_at) {
876             emit( "  Lock at %p was first observed\n",
877                   (void*)xe->XE.UnlockForeign.lock->guestaddr );
878             VG_(pp_ExeContext)( xe->XE.UnlockForeign.lock->appeared_at );
879          }
880
881       }
882
883       break;
884    }
885
886    case XE_UnlockUnlocked: {
887       tl_assert( HG_(is_sane_LockP)( xe->XE.UnlockUnlocked.lock ) );
888       tl_assert( HG_(is_sane_Thread)( xe->XE.UnlockUnlocked.thr ) );
889
890       if (xml) {
891
892          emit( "  <kind>UnlockUnlocked</kind>\n");
893          emit( "  <xwhat>\n" );
894          emit( "    <text>Thread #%d unlocked a "
895                     "not-locked lock at %p</text>\n",
896                (Int)xe->XE.UnlockUnlocked.thr->errmsg_index,
897                (void*)xe->XE.UnlockUnlocked.lock->guestaddr );
898          emit( "    <hthreadid>%d</hthreadid>\n",
899                (Int)xe->XE.UnlockUnlocked.thr->errmsg_index );
900          emit( "  </xwhat>\n" );
901          VG_(pp_ExeContext)( VG_(get_error_where)(err) );
902          if (xe->XE.UnlockUnlocked.lock->appeared_at) {
903             emit( "  <auxwhat>Lock at %p was first observed</auxwhat>\n",
904                   (void*)xe->XE.UnlockUnlocked.lock->guestaddr );
905             VG_(pp_ExeContext)( xe->XE.UnlockUnlocked.lock->appeared_at );
906          }
907
908       } else {
909
910          emit( "Thread #%d unlocked a not-locked lock at %p\n",
911                (Int)xe->XE.UnlockUnlocked.thr->errmsg_index,
912                (void*)xe->XE.UnlockUnlocked.lock->guestaddr );
913          VG_(pp_ExeContext)( VG_(get_error_where)(err) );
914          if (xe->XE.UnlockUnlocked.lock->appeared_at) {
915             emit( "  Lock at %p was first observed\n",
916                   (void*)xe->XE.UnlockUnlocked.lock->guestaddr );
917             VG_(pp_ExeContext)( xe->XE.UnlockUnlocked.lock->appeared_at );
918          }
919
920       }
921
922       break;
923    }
924
925    case XE_Race: {
926       Addr      err_ga;
927       HChar*    what;
928       Int       szB;
929       what      = xe->XE.Race.isWrite ? "write" : "read";
930       szB       = xe->XE.Race.szB;
931       err_ga = VG_(get_error_address)(err);
932
933       tl_assert( HG_(is_sane_Thread)( xe->XE.Race.thr ));
934       if (xe->XE.Race.h2_ct)
935          tl_assert( HG_(is_sane_Thread)( xe->XE.Race.h2_ct ));
936
937       if (xml) {
938
939          /* ------ XML ------ */
940          emit( "  <kind>Race</kind>\n" );
941          emit( "  <xwhat>\n" );
942          emit( "    <text>Possible data race during %s of size %d "
943                     "at %#lx by thread #%d</text>\n",
944               what, szB, err_ga, (Int)xe->XE.Race.thr->errmsg_index );
945          emit( "    <hthreadid>%d</hthreadid>\n",
946                (Int)xe->XE.Race.thr->errmsg_index );
947          emit( "  </xwhat>\n" );
948          VG_(pp_ExeContext)( VG_(get_error_where)(err) );
949
950          if (xe->XE.Race.h2_ct) {
951             tl_assert(xe->XE.Race.h2_ct_accEC); // assured by update_extra
952             emit( "  <xauxwhat>\n");
953             emit( "    <text>This conflicts with a previous %s of size %d "
954                             "by thread #%d</text>\n",
955                   xe->XE.Race.h2_ct_accIsW ? "write" : "read",
956                   xe->XE.Race.h2_ct_accSzB,
957                   xe->XE.Race.h2_ct->errmsg_index );
958             emit( "    <hthreadid>%d</hthreadid>\n", 
959                   xe->XE.Race.h2_ct->errmsg_index);
960             emit("  </xauxwhat>\n");
961             VG_(pp_ExeContext)( xe->XE.Race.h2_ct_accEC );
962          }
963
964          if (xe->XE.Race.h1_ct) {
965             emit( "  <xauxwhat>\n");
966             emit( "    <text>This conflicts with a previous access "
967                   "by thread #%d, after</text>\n",
968                   xe->XE.Race.h1_ct->errmsg_index );
969             emit( "    <hthreadid>%d</hthreadid>\n", 
970                   xe->XE.Race.h1_ct->errmsg_index );
971             emit("  </xauxwhat>\n");
972             if (xe->XE.Race.h1_ct_mbsegstartEC) {
973                VG_(pp_ExeContext)( xe->XE.Race.h1_ct_mbsegstartEC );
974             } else {
975                emit( "  <auxwhat>(the start of the thread)</auxwhat>\n" );
976             }
977             emit( "  <auxwhat>but before</auxwhat>\n" );
978             if (xe->XE.Race.h1_ct_mbsegendEC) {
979                VG_(pp_ExeContext)( xe->XE.Race.h1_ct_mbsegendEC );
980             } else {
981                emit( "  <auxwhat>(the end of the the thread)</auxwhat>\n" );
982             }
983          }
984
985       } else {
986
987          /* ------ Text ------ */
988          emit( "Possible data race during %s of size %d "
989                "at %#lx by thread #%d\n",
990                what, szB, err_ga, (Int)xe->XE.Race.thr->errmsg_index );
991          VG_(pp_ExeContext)( VG_(get_error_where)(err) );
992
993          if (xe->XE.Race.h2_ct) {
994             tl_assert(xe->XE.Race.h2_ct_accEC); // assured by update_extra
995             emit( " This conflicts with a previous %s of size %d "
996                   "by thread #%d\n",
997                   xe->XE.Race.h2_ct_accIsW ? "write" : "read",
998                   xe->XE.Race.h2_ct_accSzB,
999                   xe->XE.Race.h2_ct->errmsg_index );
1000             VG_(pp_ExeContext)( xe->XE.Race.h2_ct_accEC );
1001          }
1002
1003          if (xe->XE.Race.h1_ct) {
1004             emit( " This conflicts with a previous access by thread #%d, "
1005                   "after\n",
1006                   xe->XE.Race.h1_ct->errmsg_index );
1007             if (xe->XE.Race.h1_ct_mbsegstartEC) {
1008                VG_(pp_ExeContext)( xe->XE.Race.h1_ct_mbsegstartEC );
1009             } else {
1010                emit( "   (the start of the thread)\n" );
1011             }
1012             emit( " but before\n" );
1013             if (xe->XE.Race.h1_ct_mbsegendEC) {
1014                VG_(pp_ExeContext)( xe->XE.Race.h1_ct_mbsegendEC );
1015             } else {
1016                emit( "   (the end of the the thread)\n" );
1017             }
1018          }
1019
1020       }
1021
1022       /* If we have a description of the address in terms of a heap
1023          block, show it. */
1024       if (xe->XE.Race.hctxt) {
1025          SizeT delta = err_ga - xe->XE.Race.haddr;
1026          if (xml) {
1027             emit("  <auxwhat>Address %#lx is %ld bytes inside a block "
1028                  "of size %ld alloc'd</auxwhat>\n", err_ga, delta, 
1029                  xe->XE.Race.hszB);
1030             VG_(pp_ExeContext)( xe->XE.Race.hctxt );
1031          } else {
1032             emit(" Address %#lx is %ld bytes inside a block "
1033                  "of size %ld alloc'd\n", err_ga, delta, 
1034                  xe->XE.Race.hszB);
1035             VG_(pp_ExeContext)( xe->XE.Race.hctxt );
1036          }
1037       }
1038
1039       /* If we have a better description of the address, show it.
1040          Note that in XML mode, it will already by nicely wrapped up
1041          in tags, either <auxwhat> or <xauxwhat>, so we can just emit
1042          it verbatim. */
1043       if (xe->XE.Race.descr1)
1044          emit( "%s%s\n", xml ? "  " : " ",
1045                          (HChar*)VG_(indexXA)( xe->XE.Race.descr1, 0 ) );
1046       if (xe->XE.Race.descr2)
1047          emit( "%s%s\n", xml ? "  " : " ",
1048                          (HChar*)VG_(indexXA)( xe->XE.Race.descr2, 0 ) );
1049
1050       break; /* case XE_Race */
1051    } /* case XE_Race */
1052
1053    default:
1054       tl_assert(0);
1055    } /* switch (VG_(get_error_kind)(err)) */
1056 }
1057
1058 Char* HG_(get_error_name) ( Error* err )
1059 {
1060    switch (VG_(get_error_kind)(err)) {
1061       case XE_Race:           return "Race";
1062       case XE_UnlockUnlocked: return "UnlockUnlocked";
1063       case XE_UnlockForeign:  return "UnlockForeign";
1064       case XE_UnlockBogus:    return "UnlockBogus";
1065       case XE_PthAPIerror:    return "PthAPIerror";
1066       case XE_LockOrder:      return "LockOrder";
1067       case XE_Misc:           return "Misc";
1068       default: tl_assert(0); /* fill in missing case */
1069    }
1070 }
1071
1072 Bool HG_(recognised_suppression) ( Char* name, Supp *su )
1073 {
1074 #  define TRY(_name,_xskind)                   \
1075       if (0 == VG_(strcmp)(name, (_name))) {   \
1076          VG_(set_supp_kind)(su, (_xskind));    \
1077          return True;                          \
1078       }
1079    TRY("Race",           XS_Race);
1080    TRY("FreeMemLock",    XS_FreeMemLock);
1081    TRY("UnlockUnlocked", XS_UnlockUnlocked);
1082    TRY("UnlockForeign",  XS_UnlockForeign);
1083    TRY("UnlockBogus",    XS_UnlockBogus);
1084    TRY("PthAPIerror",    XS_PthAPIerror);
1085    TRY("LockOrder",      XS_LockOrder);
1086    TRY("Misc",           XS_Misc);
1087    return False;
1088 #  undef TRY
1089 }
1090
1091 Bool HG_(read_extra_suppression_info) ( Int fd, Char** bufpp, SizeT* nBufp,
1092                                         Supp* su )
1093 {
1094    /* do nothing -- no extra suppression info present.  Return True to
1095       indicate nothing bad happened. */
1096    return True;
1097 }
1098
1099 Bool HG_(error_matches_suppression) ( Error* err, Supp* su )
1100 {
1101    switch (VG_(get_supp_kind)(su)) {
1102    case XS_Race:           return VG_(get_error_kind)(err) == XE_Race;
1103    case XS_UnlockUnlocked: return VG_(get_error_kind)(err) == XE_UnlockUnlocked;
1104    case XS_UnlockForeign:  return VG_(get_error_kind)(err) == XE_UnlockForeign;
1105    case XS_UnlockBogus:    return VG_(get_error_kind)(err) == XE_UnlockBogus;
1106    case XS_PthAPIerror:    return VG_(get_error_kind)(err) == XE_PthAPIerror;
1107    case XS_LockOrder:      return VG_(get_error_kind)(err) == XE_LockOrder;
1108    case XS_Misc:           return VG_(get_error_kind)(err) == XE_Misc;
1109    //case XS_: return VG_(get_error_kind)(err) == XE_;
1110    default: tl_assert(0); /* fill in missing cases */
1111    }
1112 }
1113
1114 Bool HG_(get_extra_suppression_info) ( Error* err,
1115                                        /*OUT*/Char* buf, Int nBuf )
1116 {
1117    /* Do nothing */
1118    return False;
1119 }
1120
1121
1122 /*--------------------------------------------------------------------*/
1123 /*--- end                                              hg_errors.c ---*/
1124 /*--------------------------------------------------------------------*/