Home | History | Annotate | Download | only in drd
      1 /* -*- mode: C; c-basic-offset: 3; indent-tabs-mode: nil; -*- */
      2 /*
      3   This file is part of drd, a thread error detector.
      4 
      5   Copyright (C) 2006-2011 Bart Van Assche <bvanassche (at) acm.org>.
      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 
     36 Bool DRD_(g_any_address_traced) = False;
     37 
     38 
     39 /* Local variables. */
     40 
     41 static struct bitmap* DRD_(s_suppressed);
     42 static struct bitmap* DRD_(s_traced);
     43 static Bool DRD_(s_trace_suppression);
     44 
     45 
     46 /* Function definitions. */
     47 
     48 void DRD_(suppression_set_trace)(const Bool trace_suppression)
     49 {
     50    DRD_(s_trace_suppression) = trace_suppression;
     51 }
     52 
     53 void DRD_(suppression_init)(void)
     54 {
     55    tl_assert(DRD_(s_suppressed) == 0);
     56    tl_assert(DRD_(s_traced)     == 0);
     57    DRD_(s_suppressed) = DRD_(bm_new)();
     58    DRD_(s_traced)     = DRD_(bm_new)();
     59    tl_assert(DRD_(s_suppressed));
     60    tl_assert(DRD_(s_traced));
     61 }
     62 
     63 void DRD_(start_suppression)(const Addr a1, const Addr a2,
     64                              const char* const reason)
     65 {
     66    if (DRD_(s_trace_suppression))
     67    {
     68       VG_(message)(Vg_DebugMsg, "start suppression of 0x%lx sz %ld (%s)\n",
     69                    a1, a2 - a1, reason);
     70    }
     71 
     72    tl_assert(a1 <= a2);
     73    DRD_(bm_access_range_store)(DRD_(s_suppressed), a1, a2);
     74 }
     75 
     76 void DRD_(finish_suppression)(const Addr a1, const Addr a2)
     77 {
     78    if (DRD_(s_trace_suppression))
     79    {
     80       VG_(message)(Vg_DebugMsg, "finish suppression of 0x%lx sz %ld\n",
     81                    a1, a2 - a1);
     82       VG_(get_and_pp_StackTrace)(VG_(get_running_tid)(), 12);
     83    }
     84 
     85    tl_assert(a1 <= a2);
     86    DRD_(bm_clear_store)(DRD_(s_suppressed), a1, a2);
     87 }
     88 
     89 /**
     90  * Return true if data race detection suppression has been requested for all
     91  * bytes in the range a1 .. a2 - 1 inclusive. Return false in case the range
     92  * is only partially suppressed or not suppressed at all.
     93  */
     94 Bool DRD_(is_suppressed)(const Addr a1, const Addr a2)
     95 {
     96    return DRD_(bm_has)(DRD_(s_suppressed), a1, a2, eStore);
     97 }
     98 
     99 /**
    100  * Return true if data race detection suppression has been requested for any
    101  * of the bytes in the range a1 .. a2 - 1 inclusive. Return false in case none
    102  * of the bytes in the specified range is suppressed.
    103  */
    104 Bool DRD_(is_any_suppressed)(const Addr a1, const Addr a2)
    105 {
    106    return DRD_(bm_has_any_store)(DRD_(s_suppressed), a1, a2);
    107 }
    108 
    109 void DRD_(mark_hbvar)(const Addr a1)
    110 {
    111    DRD_(bm_access_range_load)(DRD_(s_suppressed), a1, a1 + 1);
    112 }
    113 
    114 Bool DRD_(range_contains_suppression_or_hbvar)(const Addr a1, const Addr a2)
    115 {
    116    return DRD_(bm_has_any_access)(DRD_(s_suppressed), a1, a2);
    117 }
    118 
    119 void DRD_(start_tracing_address_range)(const Addr a1, const Addr a2)
    120 {
    121    tl_assert(a1 <= a2);
    122 
    123    DRD_(bm_access_range_load)(DRD_(s_traced), a1, a2);
    124    if (! DRD_(g_any_address_traced))
    125    {
    126       DRD_(g_any_address_traced) = True;
    127    }
    128 }
    129 
    130 void DRD_(stop_tracing_address_range)(const Addr a1, const Addr a2)
    131 {
    132    tl_assert(a1 <= a2);
    133 
    134    DRD_(bm_clear_load)(DRD_(s_traced), a1, a2);
    135    if (DRD_(g_any_address_traced))
    136    {
    137       DRD_(g_any_address_traced)
    138          = DRD_(bm_has_any_load)(DRD_(s_traced), 0, ~(Addr)0);
    139    }
    140 }
    141 
    142 Bool DRD_(is_any_traced)(const Addr a1, const Addr a2)
    143 {
    144    return DRD_(bm_has_any_load)(DRD_(s_traced), a1, a2);
    145 }
    146 
    147 void DRD_(suppression_stop_using_mem)(const Addr a1, const Addr a2)
    148 {
    149    if (DRD_(s_trace_suppression))
    150    {
    151       Addr b;
    152       for (b = a1; b < a2; b++)
    153       {
    154          if (DRD_(bm_has_1)(DRD_(s_suppressed), b, eStore))
    155          {
    156             VG_(message)(Vg_DebugMsg,
    157                          "stop_using_mem(0x%lx, %ld) finish suppression of"
    158                          " 0x%lx\n", a1, a2 - a1, b);
    159          }
    160       }
    161    }
    162    tl_assert(a1);
    163    tl_assert(a1 <= a2);
    164    DRD_(bm_clear)(DRD_(s_suppressed), a1, a2);
    165    DRD_(bm_clear)(DRD_(s_traced), a1, a2);
    166 }
    167