1 2 /*--------------------------------------------------------------------*/ 3 /*--- Address Description. ---*/ 4 /*--- hg_addrdescr.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-2015 OpenWorks Ltd 12 info (at) 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 #include "pub_tool_basics.h" 32 #include "pub_tool_libcbase.h" 33 #include "pub_tool_libcprint.h" 34 #include "pub_tool_libcassert.h" 35 #include "pub_tool_wordfm.h" 36 #include "pub_tool_xarray.h" 37 #include "pub_tool_execontext.h" 38 #include "pub_tool_debuginfo.h" 39 #include "pub_tool_threadstate.h" 40 #include "pub_tool_aspacemgr.h" 41 #include "pub_tool_addrinfo.h" 42 43 #include "hg_basics.h" 44 #include "hg_wordset.h" 45 #include "hg_lock_n_thread.h" 46 #include "hg_addrdescr.h" /* self */ 47 48 void HG_(describe_addr) ( Addr a, /*OUT*/AddrInfo* ai ) 49 { 50 tl_assert(ai->tag == Addr_Undescribed); 51 52 /* hctxt/tnr/haddr/hszB describe the addr if it is a heap block. */ 53 ExeContext* hctxt; 54 UInt tnr; 55 Addr haddr; 56 SizeT hszB; 57 58 /* First, see if it's in any heap block. Unfortunately this 59 means a linear search through all allocated heap blocks. The 60 assertion says that if it's detected as a heap block, then we 61 must have an allocation context for it, since all heap blocks 62 should have an allocation context. */ 63 Bool is_heapblock 64 = HG_(mm_find_containing_block)( 65 &hctxt, 66 &tnr, 67 &haddr, 68 &hszB, 69 a 70 ); 71 if (is_heapblock) { 72 tl_assert(is_heapblock == (hctxt != NULL)); 73 ai->tag = Addr_Block; 74 ai->Addr.Block.block_kind = Block_Mallocd; 75 ai->Addr.Block.block_desc = "block"; 76 ai->Addr.Block.block_szB = hszB; 77 ai->Addr.Block.rwoffset = (Word)(a) - (Word)(haddr); 78 ai->Addr.Block.allocated_at = hctxt; 79 VG_(initThreadInfo) (&ai->Addr.Block.alloc_tinfo); 80 ai->Addr.Block.alloc_tinfo.tnr = tnr; 81 ai->Addr.Block.freed_at = VG_(null_ExeContext)();; 82 } else { 83 /* No block found. Search a non-heap block description. */ 84 VG_(describe_addr) (a, ai); 85 86 /* In case ai contains a tid, set tnr to the corresponding helgrind 87 thread number. */ 88 if (ai->tag == Addr_Stack) { 89 Thread* thr = get_admin_threads(); 90 91 tl_assert(ai->Addr.Stack.tinfo.tid); 92 while (thr) { 93 if (thr->coretid == ai->Addr.Stack.tinfo.tid) { 94 ai->Addr.Stack.tinfo.tnr = thr->errmsg_index; 95 break; 96 } 97 thr = thr->admin; 98 } 99 } 100 } 101 } 102 103 Bool HG_(get_and_pp_addrdescr) (Addr addr) 104 { 105 106 Bool ret; 107 AddrInfo glai; 108 109 glai.tag = Addr_Undescribed; 110 HG_(describe_addr) (addr, &glai); 111 VG_(pp_addrinfo) (addr, &glai); 112 ret = glai.tag != Addr_Unknown; 113 114 VG_(clear_addrinfo) (&glai); 115 116 return ret; 117 } 118 119 /*--------------------------------------------------------------------*/ 120 /*--- end hg_addrdescr.c ---*/ 121 /*--------------------------------------------------------------------*/ 122