misc: Standardize the way create() constructs SimObjects.
[gem5.git] / src / base / trace.cc
1 /*
2 * Copyright (c) 2014, 2019 ARM Limited
3 * All rights reserved
4 *
5 * Copyright (c) 2001-2006 The Regents of The University of Michigan
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met: redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer;
12 * redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution;
15 * neither the name of the copyright holders nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include "base/trace.hh"
33
34 #include <cctype>
35 #include <fstream>
36 #include <iostream>
37 #include <sstream>
38 #include <string>
39
40 #include "base/atomicio.hh"
41 #include "base/debug.hh"
42 #include "base/logging.hh"
43 #include "base/output.hh"
44 #include "base/str.hh"
45 #include "debug/FmtFlag.hh"
46 #include "debug/FmtStackTrace.hh"
47 #include "debug/FmtTicksOff.hh"
48 #include "sim/backtrace.hh"
49
50 const std::string &name()
51 {
52 static const std::string default_name("global");
53
54 return default_name;
55 }
56
57 namespace Trace
58 {
59
60 // This variable holds the output logger for debug information. Other
61 // than setting up/redirecting this logger, do *NOT* reference this
62 // directly
63
64 Logger *debug_logger = NULL;
65
66 Logger *
67 getDebugLogger()
68 {
69 /* Set a default logger to cerr when no other logger is set */
70 if (!debug_logger)
71 debug_logger = new OstreamLogger(std::cerr);
72
73 return debug_logger;
74 }
75
76 std::ostream &
77 output()
78 {
79 return getDebugLogger()->getOstream();
80 }
81
82 void
83 setDebugLogger(Logger *logger)
84 {
85 if (!logger)
86 warn("Trying to set debug logger to NULL\n");
87 else
88 debug_logger = logger;
89 }
90
91 void
92 enable()
93 {
94 Debug::Flag::globalEnable();
95 }
96
97 void
98 disable()
99 {
100 Debug::Flag::globalDisable();
101 }
102
103 ObjectMatch ignore;
104
105
106 void
107 Logger::dump(Tick when, const std::string &name,
108 const void *d, int len, const std::string &flag)
109 {
110 if (!name.empty() && ignore.match(name))
111 return;
112
113 const char *data = static_cast<const char *>(d);
114 int c, i, j;
115
116 for (i = 0; i < len; i += 16) {
117 std::ostringstream line;
118
119 ccprintf(line, "%08x ", i);
120 c = len - i;
121 if (c > 16) c = 16;
122
123 for (j = 0; j < c; j++) {
124 ccprintf(line, "%02x ", data[i + j] & 0xff);
125 if ((j & 0xf) == 7 && j > 0)
126 ccprintf(line, " ");
127 }
128
129 for (; j < 16; j++)
130 ccprintf(line, " ");
131 ccprintf(line, " ");
132
133 for (j = 0; j < c; j++) {
134 int ch = data[i + j] & 0x7f;
135 ccprintf(line, "%c", (char)(isprint(ch) ? ch : ' '));
136 }
137
138 ccprintf(line, "\n");
139 logMessage(when, name, flag, line.str());
140
141 if (c < 16)
142 break;
143 }
144 }
145
146 void
147 OstreamLogger::logMessage(Tick when, const std::string &name,
148 const std::string &flag, const std::string &message)
149 {
150 if (!name.empty() && ignore.match(name))
151 return;
152
153 if (!DTRACE(FmtTicksOff) && (when != MaxTick))
154 ccprintf(stream, "%7d: ", when);
155
156 if (DTRACE(FmtFlag) && !flag.empty())
157 stream << flag << ": ";
158
159 if (!name.empty())
160 stream << name << ": ";
161
162 stream << message;
163 stream.flush();
164
165 if (DTRACE(FmtStackTrace)) {
166 print_backtrace();
167 STATIC_ERR("\n");
168 }
169 }
170
171 } // namespace Trace