ftmemsim-valgrind/helgrind/hg_addrdescr.c
Philippe Waroquiers ef4e827246 Patch adding (or showing the proper/not confusing) helgrind thread nr for block
and stack address description.

* A race condition on an allocated block shows the stacktrace, but
  does not show the thread # that allocated the block.
  This patch adds the output of the thread # that allocated the block.

*  The patch also fixes the confusion that might appear between
  the core threadid and the helgrind thread nr in Stack address description:
  A printed stack addrinfo was containing a thread id, while all other helgrind
  messages are using (supposed to use) an 'helgrind thread #' which
  is used in the thread announcement.

    Basically, the idea is to let a tool set a "tool specific thread nr'
    in an addrinfo.
    The pretty printing of the addrinfo is then by preference showing this
    thread nr (if it was set, i.e. different of 0).
    Currently, only helgrind uses this addrinfo tnr.

    Note: in xml mode, the output is matching the protocol description.
    I.e., GUI should not be impacted by this change, if they properly implement
    the xml protocol.


* Also, make the output produced by m_addrinfo consistent:
  The  message 'block was alloc'd at'  is changed to be like all other
  output : one character indent, and starting with an uppercase



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14175
2014-07-18 00:03:58 +00:00

121 lines
3.9 KiB
C

/*--------------------------------------------------------------------*/
/*--- Address Description. ---*/
/*--- hg_addrdescr.c ---*/
/*--------------------------------------------------------------------*/
/*
This file is part of Helgrind, a Valgrind tool for detecting errors
in threaded programs.
Copyright (C) 2007-2012 OpenWorks Ltd
info@open-works.co.uk
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA.
The GNU General Public License is contained in the file COPYING.
*/
#include "pub_tool_basics.h"
#include "pub_tool_libcbase.h"
#include "pub_tool_libcprint.h"
#include "pub_tool_libcassert.h"
#include "pub_tool_wordfm.h"
#include "pub_tool_xarray.h"
#include "pub_tool_execontext.h"
#include "pub_tool_debuginfo.h"
#include "pub_tool_threadstate.h"
#include "pub_tool_addrinfo.h"
#include "hg_basics.h"
#include "hg_wordset.h"
#include "hg_lock_n_thread.h"
#include "hg_addrdescr.h" /* self */
void HG_(describe_addr) ( Addr a, /*OUT*/AddrInfo* ai )
{
tl_assert(ai->tag == Addr_Undescribed);
/* hctxt/tnr/haddr/hszB describe the addr if it is a heap block. */
ExeContext* hctxt;
UInt tnr;
Addr haddr;
SizeT hszB;
/* First, see if it's in any heap block. Unfortunately this
means a linear search through all allocated heap blocks. The
assertion says that if it's detected as a heap block, then we
must have an allocation context for it, since all heap blocks
should have an allocation context. */
Bool is_heapblock
= HG_(mm_find_containing_block)(
&hctxt,
&tnr,
&haddr,
&hszB,
a
);
if (is_heapblock) {
tl_assert(is_heapblock == (hctxt != NULL));
ai->tag = Addr_Block;
ai->Addr.Block.block_kind = Block_Mallocd;
ai->Addr.Block.block_desc = "block";
ai->Addr.Block.block_szB = hszB;
ai->Addr.Block.rwoffset = (Word)(a) - (Word)(haddr);
ai->Addr.Block.allocated_at = hctxt;
VG_(initThreadInfo) (&ai->Addr.Block.alloc_tinfo);
ai->Addr.Block.alloc_tinfo.tnr = tnr;
ai->Addr.Block.freed_at = VG_(null_ExeContext)();;
} else {
/* No block found. Search a non-heap block description. */
VG_(describe_addr) (a, ai);
/* In case ai contains a tid, set tnr to the corresponding helgrind
thread number. */
if (ai->tag == Addr_Stack) {
Thread* thr = get_admin_threads();
tl_assert(ai->Addr.Stack.tinfo.tid);
while (thr) {
if (thr->coretid == ai->Addr.Stack.tinfo.tid) {
ai->Addr.Stack.tinfo.tnr = thr->errmsg_index;
break;
}
thr = thr->admin;
}
}
}
}
Bool HG_(get_and_pp_addrdescr) (Addr addr)
{
Bool ret;
AddrInfo glai;
glai.tag = Addr_Undescribed;
HG_(describe_addr) (addr, &glai);
VG_(pp_addrinfo) (addr, &glai);
ret = glai.tag != Addr_Unknown;
VG_(clear_addrinfo) (&glai);
return ret;
}
/*--------------------------------------------------------------------*/
/*--- end hg_addrdescr.c ---*/
/*--------------------------------------------------------------------*/