debug.cc revision 11153:20bbfe5b2b86
16145Snate@binkert.org/* 26145Snate@binkert.org * Copyright (c) 2003-2005 The Regents of The University of Michigan 36145Snate@binkert.org * All rights reserved. 46145Snate@binkert.org * 56145Snate@binkert.org * Redistribution and use in source and binary forms, with or without 66145Snate@binkert.org * modification, are permitted provided that the following conditions are 76145Snate@binkert.org * met: redistributions of source code must retain the above copyright 86145Snate@binkert.org * notice, this list of conditions and the following disclaimer; 96145Snate@binkert.org * redistributions in binary form must reproduce the above copyright 106145Snate@binkert.org * notice, this list of conditions and the following disclaimer in the 116145Snate@binkert.org * documentation and/or other materials provided with the distribution; 126145Snate@binkert.org * neither the name of the copyright holders nor the names of its 136145Snate@binkert.org * contributors may be used to endorse or promote products derived from 146145Snate@binkert.org * this software without specific prior written permission. 156145Snate@binkert.org * 166145Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176145Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186145Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196145Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206145Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216145Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226145Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236145Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246145Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256145Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266145Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276145Snate@binkert.org * 286145Snate@binkert.org * Authors: Nathan Binkert 297454Snate@binkert.org */ 307454Snate@binkert.org 318645Snilay@cs.wisc.edu#include <sys/types.h> 327454Snate@binkert.org#include <unistd.h> 337054Snate@binkert.org 347054Snate@binkert.org#include <algorithm> 357054Snate@binkert.org#include <csignal> 368259SBrad.Beckmann@amd.com 376154Snate@binkert.org#include "base/cprintf.hh" 386154Snate@binkert.org#include "base/debug.hh" 396145Snate@binkert.org#include "base/misc.hh" 407055Snate@binkert.org 417454Snate@binkert.orgusing namespace std; 427454Snate@binkert.org 437055Snate@binkert.orgnamespace Debug { 449274Snilay@cs.wisc.edu 456145Snate@binkert.org// 469274Snilay@cs.wisc.edu// This function will cause the process to signal itself with a 476145Snate@binkert.org// SIGTRAP which is ignored if not in gdb, but will cause the debugger 486145Snate@binkert.org// to break if in gdb. 496145Snate@binkert.org// 506145Snate@binkert.orgvoid 517054Snate@binkert.orgbreakpoint() 526145Snate@binkert.org{ 537054Snate@binkert.org#ifndef NDEBUG 547454Snate@binkert.org kill(getpid(), SIGTRAP); 556145Snate@binkert.org#else 567054Snate@binkert.org cprintf("Debug::breakpoint suppressed, compiled with NDEBUG\n"); 577454Snate@binkert.org#endif 586145Snate@binkert.org} 596145Snate@binkert.org 607054Snate@binkert.org// 619274Snilay@cs.wisc.edu// Flags for debugging purposes. Primarily for trace.hh 629274Snilay@cs.wisc.edu// 639274Snilay@cs.wisc.eduint allFlagsVersion = 0; 649274Snilay@cs.wisc.eduFlagsMap & 659274Snilay@cs.wisc.eduallFlags() 669274Snilay@cs.wisc.edu{ 679274Snilay@cs.wisc.edu static FlagsMap flags; 687454Snate@binkert.org return flags; 696145Snate@binkert.org} 707054Snate@binkert.org 716145Snate@binkert.orgbool SimpleFlag::_active = false; 726145Snate@binkert.org 737054Snate@binkert.orgFlag * 747454Snate@binkert.orgfindFlag(const std::string &name) 757054Snate@binkert.org{ 766145Snate@binkert.org FlagsMap::iterator i = allFlags().find(name); 777054Snate@binkert.org if (i == allFlags().end()) 789274Snilay@cs.wisc.edu return NULL; 799274Snilay@cs.wisc.edu return i->second; 809274Snilay@cs.wisc.edu} 817454Snate@binkert.org 826145Snate@binkert.orgFlag::Flag(const char *name, const char *desc) 837054Snate@binkert.org : _name(name), _desc(desc) 847454Snate@binkert.org{ 857054Snate@binkert.org pair<FlagsMap::iterator, bool> result = 867054Snate@binkert.org allFlags().insert(make_pair(name, this)); 877054Snate@binkert.org 887054Snate@binkert.org if (!result.second) 899274Snilay@cs.wisc.edu panic("Flag %s already defined!", name); 909274Snilay@cs.wisc.edu 917054Snate@binkert.org ++allFlagsVersion; 927454Snate@binkert.org} 937454Snate@binkert.org 949274Snilay@cs.wisc.eduFlag::~Flag() 956145Snate@binkert.org{ 967054Snate@binkert.org // should find and remove flag. 977054Snate@binkert.org} 986145Snate@binkert.org 997054Snate@binkert.orgvoid 1007054Snate@binkert.orgSimpleFlag::enableAll() 1016145Snate@binkert.org{ 1026145Snate@binkert.org _active = true; 1037054Snate@binkert.org for (auto& i : allFlags()) 1047054Snate@binkert.org i.second->sync(); 1056145Snate@binkert.org} 1067054Snate@binkert.org 1076145Snate@binkert.orgvoid 1086145Snate@binkert.orgSimpleFlag::disableAll() 1097054Snate@binkert.org{ 1107054Snate@binkert.org _active = false; 1116145Snate@binkert.org for (auto& i : allFlags()) 1127054Snate@binkert.org i.second->sync(); 1137054Snate@binkert.org} 1147054Snate@binkert.org 1157054Snate@binkert.orgvoid 1167054Snate@binkert.orgCompoundFlag::enable() 1176145Snate@binkert.org{ 1186145Snate@binkert.org for (auto& k : _kids) 1196145Snate@binkert.org k->enable(); 1207054Snate@binkert.org} 1217054Snate@binkert.org 1226145Snate@binkert.orgvoid 1237054Snate@binkert.orgCompoundFlag::disable() 1246145Snate@binkert.org{ 1256145Snate@binkert.org for (auto& k : _kids) 1267054Snate@binkert.org k->disable(); 1277054Snate@binkert.org} 1286145Snate@binkert.org 1297054Snate@binkert.orgstruct AllFlags : public Flag 1307054Snate@binkert.org{ 1316145Snate@binkert.org AllFlags() 1326145Snate@binkert.org : Flag("All", "All Flags") 1337454Snate@binkert.org {} 1347054Snate@binkert.org 1356145Snate@binkert.org void 1367054Snate@binkert.org enable() 1376145Snate@binkert.org { 1386145Snate@binkert.org FlagsMap::iterator i = allFlags().begin(); 1397054Snate@binkert.org FlagsMap::iterator end = allFlags().end(); 1407054Snate@binkert.org for (; i != end; ++i) 1416145Snate@binkert.org if (i->second != this) 1429274Snilay@cs.wisc.edu i->second->enable(); 1437054Snate@binkert.org } 1449274Snilay@cs.wisc.edu 1457054Snate@binkert.org void 1466145Snate@binkert.org disable() 1477054Snate@binkert.org { 1487054Snate@binkert.org FlagsMap::iterator i = allFlags().begin(); 1497054Snate@binkert.org FlagsMap::iterator end = allFlags().end(); 1506145Snate@binkert.org for (; i != end; ++i) 1517054Snate@binkert.org if (i->second != this) 1527054Snate@binkert.org i->second->disable(); 1537054Snate@binkert.org } 1547054Snate@binkert.org}; 1557054Snate@binkert.org 1567054Snate@binkert.orgAllFlags theAllFlags; 1576145Snate@binkert.orgFlag *const All = &theAllFlags; 1587054Snate@binkert.org 1597054Snate@binkert.orgbool 1606145Snate@binkert.orgchangeFlag(const char *s, bool value) 1617054Snate@binkert.org{ 1629274Snilay@cs.wisc.edu Flag *f = findFlag(s); 1637054Snate@binkert.org if (!f) 1647054Snate@binkert.org return false; 1657054Snate@binkert.org 1667054Snate@binkert.org if (value) 1677054Snate@binkert.org f->enable(); 1689274Snilay@cs.wisc.edu else 1697054Snate@binkert.org f->disable(); 1707054Snate@binkert.org 1717054Snate@binkert.org return true; 1727054Snate@binkert.org} 1737054Snate@binkert.org 1746145Snate@binkert.org} // namespace Debug 1757054Snate@binkert.org 1766145Snate@binkert.org// add a set of functions that can easily be invoked from gdb 1777054Snate@binkert.orgvoid 1787054Snate@binkert.orgsetDebugFlag(const char *string) 1797054Snate@binkert.org{ 1807054Snate@binkert.org Debug::changeFlag(string, true); 1817054Snate@binkert.org} 1827054Snate@binkert.org 1837454Snate@binkert.orgvoid 1847054Snate@binkert.orgclearDebugFlag(const char *string) 1857054Snate@binkert.org{ 1867054Snate@binkert.org Debug::changeFlag(string, false); 1877454Snate@binkert.org} 1887454Snate@binkert.org 1897054Snate@binkert.orgvoid 1907054Snate@binkert.orgdumpDebugFlags() 1917054Snate@binkert.org{ 1929274Snilay@cs.wisc.edu using namespace Debug; 1937054Snate@binkert.org FlagsMap::iterator i = allFlags().begin(); 1949274Snilay@cs.wisc.edu FlagsMap::iterator end = allFlags().end(); 1957454Snate@binkert.org for (; i != end; ++i) { 1967454Snate@binkert.org SimpleFlag *f = dynamic_cast<SimpleFlag *>(i->second); 1977454Snate@binkert.org if (f && f->status()) 1987054Snate@binkert.org cprintf("%s\n", f->name()); 1996145Snate@binkert.org } 2006145Snate@binkert.org} 2017054Snate@binkert.org