debug.cc revision 8232
15882Snate@binkert.org/* 25882Snate@binkert.org * Copyright (c) 2003-2005 The Regents of The University of Michigan 35882Snate@binkert.org * All rights reserved. 45882Snate@binkert.org * 55882Snate@binkert.org * Redistribution and use in source and binary forms, with or without 65882Snate@binkert.org * modification, are permitted provided that the following conditions are 75882Snate@binkert.org * met: redistributions of source code must retain the above copyright 85882Snate@binkert.org * notice, this list of conditions and the following disclaimer; 95882Snate@binkert.org * redistributions in binary form must reproduce the above copyright 105882Snate@binkert.org * notice, this list of conditions and the following disclaimer in the 115882Snate@binkert.org * documentation and/or other materials provided with the distribution; 125882Snate@binkert.org * neither the name of the copyright holders nor the names of its 135882Snate@binkert.org * contributors may be used to endorse or promote products derived from 145882Snate@binkert.org * this software without specific prior written permission. 155882Snate@binkert.org * 165882Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 175882Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 185882Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 195882Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 205882Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 215882Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 225882Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 235882Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245882Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255882Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 265882Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275882Snate@binkert.org * 285882Snate@binkert.org * Authors: Nathan Binkert 295882Snate@binkert.org */ 305882Snate@binkert.org 315882Snate@binkert.org#include <sys/types.h> 325882Snate@binkert.org#include <unistd.h> 335882Snate@binkert.org 348232Snate@binkert.org#include <algorithm> 358229Snate@binkert.org#include <csignal> 368232Snate@binkert.org#include <map> 378232Snate@binkert.org#include <vector> 388229Snate@binkert.org 395882Snate@binkert.org#include "base/cprintf.hh" 408232Snate@binkert.org#include "base/debug.hh" 418232Snate@binkert.org#include "base/misc.hh" 428232Snate@binkert.org 438232Snate@binkert.orgusing namespace std; 445882Snate@binkert.org 458231Snate@binkert.orgnamespace Debug { 468231Snate@binkert.org 478232Snate@binkert.org// 488232Snate@binkert.org// This function will cause the process to signal itself with a 498232Snate@binkert.org// SIGTRAP which is ignored if not in gdb, but will cause the debugger 508232Snate@binkert.org// to break if in gdb. 518232Snate@binkert.org// 525882Snate@binkert.orgvoid 538231Snate@binkert.orgbreakpoint() 545882Snate@binkert.org{ 555882Snate@binkert.org#ifndef NDEBUG 565882Snate@binkert.org kill(getpid(), SIGTRAP); 575882Snate@binkert.org#else 588231Snate@binkert.org cprintf("Debug::breakpoint suppressed, compiled with NDEBUG\n"); 595882Snate@binkert.org#endif 605882Snate@binkert.org} 618231Snate@binkert.org 628232Snate@binkert.org// 638232Snate@binkert.org// Flags for debugging purposes. Primarily for trace.hh 648232Snate@binkert.org// 658232Snate@binkert.orgtypedef std::map<string, Flag *> FlagsMap; 668232Snate@binkert.orgint allFlagsVersion = 0; 678232Snate@binkert.orgFlagsMap & 688232Snate@binkert.orgallFlags() 698232Snate@binkert.org{ 708232Snate@binkert.org static FlagsMap flags; 718232Snate@binkert.org return flags; 728232Snate@binkert.org} 738232Snate@binkert.org 748232Snate@binkert.orgFlag * 758232Snate@binkert.orgfindFlag(const std::string &name) 768232Snate@binkert.org{ 778232Snate@binkert.org FlagsMap::iterator i = allFlags().find(name); 788232Snate@binkert.org if (i == allFlags().end()) 798232Snate@binkert.org return NULL; 808232Snate@binkert.org return i->second; 818232Snate@binkert.org} 828232Snate@binkert.org 838232Snate@binkert.orgFlag::Flag(const char *name, const char *desc) 848232Snate@binkert.org : _name(name), _desc(desc) 858232Snate@binkert.org{ 868232Snate@binkert.org pair<FlagsMap::iterator, bool> result = 878232Snate@binkert.org allFlags().insert(make_pair(name, this)); 888232Snate@binkert.org 898232Snate@binkert.org if (!result.second) 908232Snate@binkert.org panic("Flag %s already defined!", name); 918232Snate@binkert.org 928232Snate@binkert.org ++allFlagsVersion; 938232Snate@binkert.org} 948232Snate@binkert.org 958232Snate@binkert.orgFlag::~Flag() 968232Snate@binkert.org{ 978232Snate@binkert.org // should find and remove flag. 988232Snate@binkert.org} 998232Snate@binkert.org 1008232Snate@binkert.orgvoid 1018232Snate@binkert.orgCompoundFlag::enable() 1028232Snate@binkert.org{ 1038232Snate@binkert.org SimpleFlag::enable(); 1048232Snate@binkert.org for_each(flags.begin(), flags.end(), mem_fun(&Flag::enable)); 1058232Snate@binkert.org} 1068232Snate@binkert.org 1078232Snate@binkert.orgvoid 1088232Snate@binkert.orgCompoundFlag::disable() 1098232Snate@binkert.org{ 1108232Snate@binkert.org SimpleFlag::disable(); 1118232Snate@binkert.org for_each(flags.begin(), flags.end(), mem_fun(&Flag::disable)); 1128232Snate@binkert.org} 1138232Snate@binkert.org 1148232Snate@binkert.orgstruct AllFlags : public Flag 1158232Snate@binkert.org{ 1168232Snate@binkert.org AllFlags() 1178232Snate@binkert.org : Flag("All", "All Flags") 1188232Snate@binkert.org {} 1198232Snate@binkert.org 1208232Snate@binkert.org void 1218232Snate@binkert.org enable() 1228232Snate@binkert.org { 1238232Snate@binkert.org FlagsMap::iterator i = allFlags().begin(); 1248232Snate@binkert.org FlagsMap::iterator end = allFlags().end(); 1258232Snate@binkert.org for (; i != end; ++i) 1268232Snate@binkert.org if (i->second != this) 1278232Snate@binkert.org i->second->enable(); 1288232Snate@binkert.org } 1298232Snate@binkert.org 1308232Snate@binkert.org void 1318232Snate@binkert.org disable() 1328232Snate@binkert.org { 1338232Snate@binkert.org FlagsMap::iterator i = allFlags().begin(); 1348232Snate@binkert.org FlagsMap::iterator end = allFlags().end(); 1358232Snate@binkert.org for (; i != end; ++i) 1368232Snate@binkert.org if (i->second != this) 1378232Snate@binkert.org i->second->enable(); 1388232Snate@binkert.org } 1398232Snate@binkert.org}; 1408232Snate@binkert.org 1418232Snate@binkert.orgAllFlags theAllFlags; 1428232Snate@binkert.orgFlag *const All = &theAllFlags; 1438232Snate@binkert.org 1448232Snate@binkert.orgbool 1458232Snate@binkert.orgchangeFlag(const char *s, bool value) 1468232Snate@binkert.org{ 1478232Snate@binkert.org Flag *f = findFlag(s); 1488232Snate@binkert.org if (!f) 1498232Snate@binkert.org return false; 1508232Snate@binkert.org 1518232Snate@binkert.org if (value) 1528232Snate@binkert.org f->enable(); 1538232Snate@binkert.org else 1548232Snate@binkert.org f->disable(); 1558232Snate@binkert.org 1568232Snate@binkert.org return true; 1578232Snate@binkert.org} 1588232Snate@binkert.org 1598231Snate@binkert.org} // namespace Debug 1608232Snate@binkert.org 1618232Snate@binkert.org// add a set of functions that can easily be invoked from gdb 1628232Snate@binkert.orgvoid 1638232Snate@binkert.orgsetDebugFlag(const char *string) 1648232Snate@binkert.org{ 1658232Snate@binkert.org Debug::changeFlag(string, true); 1668232Snate@binkert.org} 1678232Snate@binkert.org 1688232Snate@binkert.orgvoid 1698232Snate@binkert.orgclearDebugFlag(const char *string) 1708232Snate@binkert.org{ 1718232Snate@binkert.org Debug::changeFlag(string, false); 1728232Snate@binkert.org} 1738232Snate@binkert.org 1748232Snate@binkert.orgvoid 1758232Snate@binkert.orgdumpDebugFlags() 1768232Snate@binkert.org{ 1778232Snate@binkert.org using namespace Debug; 1788232Snate@binkert.org FlagsMap::iterator i = allFlags().begin(); 1798232Snate@binkert.org FlagsMap::iterator end = allFlags().end(); 1808232Snate@binkert.org for (; i != end; ++i) { 1818232Snate@binkert.org SimpleFlag *f = dynamic_cast<SimpleFlag *>(i->second); 1828232Snate@binkert.org if (f && f->status()) 1838232Snate@binkert.org cprintf("%s\n", f->name()); 1848232Snate@binkert.org } 1858232Snate@binkert.org} 186