drd_suppression.c revision fe3de44204aec6d2dcb2a6d9f79b50415e403571
1/* -*- mode: C; c-basic-offset: 3; -*- */
2/*
3  This file is part of drd, a thread error detector.
4
5  Copyright (C) 2006-2009 Bart Van Assche <bart.vanassche@gmail.com>.
6
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of the
10  License, or (at your option) any later version.
11
12  This program is distributed in the hope that it will be useful, but
13  WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  General Public License for more details.
16
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20  02111-1307, USA.
21
22  The GNU General Public License is contained in the file COPYING.
23*/
24
25
26#include "drd_suppression.h"
27#include "pub_drd_bitmap.h"
28#include "pub_tool_libcassert.h"  // tl_assert()
29#include "pub_tool_stacktrace.h"  // VG_(get_and_pp_StackTrace)()
30#include "pub_tool_threadstate.h" // VG_(get_running_tid)()
31#include "pub_tool_libcprint.h"   // Vg_DebugMsg
32
33
34/* Global variables. */
35
36Bool DRD_(g_any_address_traced) = False;
37
38
39/* Local variables. */
40
41static struct bitmap* DRD_(s_suppressed);
42static Bool DRD_(s_trace_suppression);
43
44
45/* Function definitions. */
46
47void DRD_(suppression_set_trace)(const Bool trace_suppression)
48{
49   DRD_(s_trace_suppression) = trace_suppression;
50}
51
52void DRD_(suppression_init)(void)
53{
54   tl_assert(DRD_(s_suppressed) == 0);
55   DRD_(s_suppressed) = DRD_(bm_new)();
56   tl_assert(DRD_(s_suppressed));
57}
58
59void DRD_(start_suppression)(const Addr a1, const Addr a2,
60                             const char* const reason)
61{
62   if (DRD_(s_trace_suppression))
63   {
64      VG_(message)(Vg_DebugMsg, "start suppression of 0x%lx sz %ld (%s)\n",
65                   a1, a2 - a1, reason);
66   }
67
68   tl_assert(a1 < a2);
69   // tl_assert(! drd_is_any_suppressed(a1, a2));
70   DRD_(bm_access_range_store)(DRD_(s_suppressed), a1, a2);
71}
72
73void DRD_(finish_suppression)(const Addr a1, const Addr a2)
74{
75   if (DRD_(s_trace_suppression))
76   {
77      VG_(message)(Vg_DebugMsg, "finish suppression of 0x%lx sz %ld\n",
78                   a1, a2 - a1);
79      VG_(get_and_pp_StackTrace)(VG_(get_running_tid)(), 12);
80   }
81
82   tl_assert(a1 < a2);
83#if 0
84   if (! DRD_(is_suppressed)(a1, a2))
85   {
86      VG_(message)(Vg_DebugMsg, "?? [0x%lx,0x%lx[ not suppressed ??\n", a1, a2);
87      VG_(get_and_pp_StackTrace)(VG_(get_running_tid)(), 12);
88      tl_assert(False);
89   }
90#endif
91   DRD_(bm_clear_store)(DRD_(s_suppressed), a1, a2);
92}
93
94/**
95 * Return true if data race detection suppression has been requested for all
96 * bytes in the range a1 .. a2 - 1 inclusive. Return false in case the range
97 * is only partially suppressed or not suppressed at all.
98 */
99Bool DRD_(is_suppressed)(const Addr a1, const Addr a2)
100{
101   return DRD_(bm_has)(DRD_(s_suppressed), a1, a2, eStore);
102}
103
104/**
105 * Return true if data race detection suppression has been requested for any
106 * of the bytes in the range a1 .. a2 - 1 inclusive. Return false in case none
107 * of the bytes in the specified range is suppressed.
108 */
109Bool DRD_(is_any_suppressed)(const Addr a1, const Addr a2)
110{
111   return DRD_(bm_has_any_store)(DRD_(s_suppressed), a1, a2);
112}
113
114void DRD_(start_tracing_address_range)(const Addr a1, const Addr a2)
115{
116   tl_assert(a1 < a2);
117
118   DRD_(bm_access_range_load)(DRD_(s_suppressed), a1, a2);
119   if (! DRD_(g_any_address_traced))
120   {
121      DRD_(g_any_address_traced) = True;
122   }
123}
124
125void DRD_(stop_tracing_address_range)(const Addr a1, const Addr a2)
126{
127   tl_assert(a1 < a2);
128
129   DRD_(bm_clear_load)(DRD_(s_suppressed), a1, a2);
130   if (DRD_(g_any_address_traced))
131   {
132      DRD_(g_any_address_traced)
133         = DRD_(bm_has_any_load)(DRD_(s_suppressed), 0, ~(Addr)0);
134   }
135}
136
137Bool DRD_(is_any_traced)(const Addr a1, const Addr a2)
138{
139   return DRD_(bm_has_any_load)(DRD_(s_suppressed), a1, a2);
140}
141
142void DRD_(suppression_stop_using_mem)(const Addr a1, const Addr a2)
143{
144   if (DRD_(s_trace_suppression))
145   {
146      Addr b;
147      for (b = a1; b < a2; b++)
148      {
149         if (DRD_(bm_has_1)(DRD_(s_suppressed), b, eStore))
150         {
151            VG_(message)(Vg_DebugMsg,
152                         "stop_using_mem(0x%lx, %ld) finish suppression of"
153                         " 0x%lx\n", a1, a2 - a1, b);
154         }
155      }
156   }
157   tl_assert(a1);
158   tl_assert(a1 < a2);
159   DRD_(bm_clear)(DRD_(s_suppressed), a1, a2);
160}
161