arch,cpu,mem: Replace the mmmapped IPR mechanism with local accesses.
[gem5.git] / src / base / debug.cc
1 /*
2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include "base/debug.hh"
30
31 #include <sys/types.h>
32 #include <unistd.h>
33
34 #include <algorithm>
35 #include <csignal>
36
37 #include "base/cprintf.hh"
38 #include "base/logging.hh"
39
40 using namespace std;
41
42 namespace Debug {
43
44 //
45 // This function will cause the process to signal itself with a
46 // SIGTRAP which is ignored if not in gdb, but will cause the debugger
47 // to break if in gdb.
48 //
49 void
50 breakpoint()
51 {
52 #ifndef NDEBUG
53 kill(getpid(), SIGTRAP);
54 #else
55 cprintf("Debug::breakpoint suppressed, compiled with NDEBUG\n");
56 #endif
57 }
58
59 //
60 // Flags for debugging purposes. Primarily for trace.hh
61 //
62 int allFlagsVersion = 0;
63 FlagsMap &
64 allFlags()
65 {
66 static FlagsMap flags;
67 return flags;
68 }
69
70 bool SimpleFlag::_active = false;
71
72 Flag *
73 findFlag(const std::string &name)
74 {
75 FlagsMap::iterator i = allFlags().find(name);
76 if (i == allFlags().end())
77 return NULL;
78 return i->second;
79 }
80
81 Flag::Flag(const char *name, const char *desc)
82 : _name(name), _desc(desc)
83 {
84 pair<FlagsMap::iterator, bool> result =
85 allFlags().insert(make_pair(name, this));
86
87 if (!result.second)
88 panic("Flag %s already defined!", name);
89
90 ++allFlagsVersion;
91 }
92
93 Flag::~Flag()
94 {
95 // should find and remove flag.
96 }
97
98 void
99 SimpleFlag::enableAll()
100 {
101 _active = true;
102 for (auto& i : allFlags())
103 i.second->sync();
104 }
105
106 void
107 SimpleFlag::disableAll()
108 {
109 _active = false;
110 for (auto& i : allFlags())
111 i.second->sync();
112 }
113
114 void
115 CompoundFlag::enable()
116 {
117 for (auto& k : _kids)
118 k->enable();
119 }
120
121 void
122 CompoundFlag::disable()
123 {
124 for (auto& k : _kids)
125 k->disable();
126 }
127
128 struct AllFlags : public Flag
129 {
130 AllFlags()
131 : Flag("All", "All Flags")
132 {}
133
134 void
135 enable()
136 {
137 FlagsMap::iterator i = allFlags().begin();
138 FlagsMap::iterator end = allFlags().end();
139 for (; i != end; ++i)
140 if (i->second != this)
141 i->second->enable();
142 }
143
144 void
145 disable()
146 {
147 FlagsMap::iterator i = allFlags().begin();
148 FlagsMap::iterator end = allFlags().end();
149 for (; i != end; ++i)
150 if (i->second != this)
151 i->second->disable();
152 }
153 };
154
155 AllFlags theAllFlags;
156 Flag *const All = &theAllFlags;
157
158 bool
159 changeFlag(const char *s, bool value)
160 {
161 Flag *f = findFlag(s);
162 if (!f)
163 return false;
164
165 if (value)
166 f->enable();
167 else
168 f->disable();
169
170 return true;
171 }
172
173 } // namespace Debug
174
175 // add a set of functions that can easily be invoked from gdb
176 void
177 setDebugFlag(const char *string)
178 {
179 Debug::changeFlag(string, true);
180 }
181
182 void
183 clearDebugFlag(const char *string)
184 {
185 Debug::changeFlag(string, false);
186 }
187
188 void
189 dumpDebugFlags()
190 {
191 using namespace Debug;
192 FlagsMap::iterator i = allFlags().begin();
193 FlagsMap::iterator end = allFlags().end();
194 for (; i != end; ++i) {
195 SimpleFlag *f = dynamic_cast<SimpleFlag *>(i->second);
196 if (f && f->status())
197 cprintf("%s\n", f->name());
198 }
199 }