1 /* -----------------------------------------------------------------------------
3 * (c) The GHC Team 2006-2009
5 * Debug and performance tracing
7 * ---------------------------------------------------------------------------*/
18 #include "eventlog/EventLog.h"
23 // debugging flags, set with +RTS -D<something>
29 int DEBUG_block_alloc;
46 static Mutex trace_utx;
49 static rtsBool eventlog_enabled;
51 /* ---------------------------------------------------------------------------
52 Starting up / shuttting down the tracing facilities
53 --------------------------------------------------------------------------- */
55 void initTracing (void)
58 initMutex(&trace_utx);
62 #define DEBUG_FLAG(name, class) \
63 class = RtsFlags.DebugFlags.name ? 1 : 0;
65 DEBUG_FLAG(scheduler, DEBUG_sched);
67 DEBUG_FLAG(interpreter, DEBUG_interp);
68 DEBUG_FLAG(weak, DEBUG_weak);
69 DEBUG_FLAG(gccafs, DEBUG_gccafs);
70 DEBUG_FLAG(gc, DEBUG_gc);
71 DEBUG_FLAG(block_alloc, DEBUG_block_alloc);
72 DEBUG_FLAG(sanity, DEBUG_sanity);
73 DEBUG_FLAG(stable, DEBUG_stable);
74 DEBUG_FLAG(stm, DEBUG_stm);
75 DEBUG_FLAG(prof, DEBUG_prof);
76 DEBUG_FLAG(linker, DEBUG_linker);
77 DEBUG_FLAG(squeeze, DEBUG_squeeze);
78 DEBUG_FLAG(hpc, DEBUG_hpc);
79 DEBUG_FLAG(sparks, DEBUG_sparks);
82 // -Ds turns on scheduler tracing too
84 RtsFlags.TraceFlags.scheduler ||
85 RtsFlags.DebugFlags.scheduler;
87 eventlog_enabled = RtsFlags.TraceFlags.tracing == TRACE_EVENTLOG;
89 if (eventlog_enabled) {
94 void endTracing (void)
96 if (eventlog_enabled) {
101 void freeTracing (void)
103 if (eventlog_enabled) {
108 /* ---------------------------------------------------------------------------
109 Emitting trace messages/events
110 --------------------------------------------------------------------------- */
113 static void tracePreface (void)
116 debugBelch("%12lx: ", (unsigned long)osThreadId());
118 if (RtsFlags.TraceFlags.timestamp) {
119 debugBelch("%9" FMT_Word64 ": ", stat_getElapsedTime());
125 static char *thread_stop_reasons[] = {
126 [HeapOverflow] = "heap overflow",
127 [StackOverflow] = "stack overflow",
128 [ThreadYielding] = "yielding",
129 [ThreadBlocked] = "blocked",
130 [ThreadFinished] = "finished",
131 [THREAD_SUSPENDED_FOREIGN_CALL] = "suspended while making a foreign call"
136 static void traceSchedEvent_stderr (Capability *cap, EventTypeNum tag,
138 StgWord64 other STG_UNUSED)
140 ACQUIRE_LOCK(&trace_utx);
144 case EVENT_CREATE_THREAD: // (cap, thread)
145 debugBelch("cap %d: created thread %lu\n",
146 cap->no, (lnat)tso->id);
148 case EVENT_RUN_THREAD: // (cap, thread)
149 debugBelch("cap %d: running thread %lu (%s)\n",
150 cap->no, (lnat)tso->id, what_next_strs[tso->what_next]);
152 case EVENT_THREAD_RUNNABLE: // (cap, thread)
153 debugBelch("cap %d: thread %lu appended to run queue\n",
154 cap->no, (lnat)tso->id);
156 case EVENT_RUN_SPARK: // (cap, thread)
157 debugBelch("cap %d: thread %lu running a spark\n",
158 cap->no, (lnat)tso->id);
160 case EVENT_CREATE_SPARK_THREAD: // (cap, spark_thread)
161 debugBelch("cap %d: creating spark thread %lu\n",
162 cap->no, (long)other);
164 case EVENT_MIGRATE_THREAD: // (cap, thread, new_cap)
165 debugBelch("cap %d: thread %lu migrating to cap %d\n",
166 cap->no, (lnat)tso->id, (int)other);
168 case EVENT_STEAL_SPARK: // (cap, thread, victim_cap)
169 debugBelch("cap %d: thread %lu stealing a spark from cap %d\n",
170 cap->no, (lnat)tso->id, (int)other);
172 case EVENT_THREAD_WAKEUP: // (cap, thread, other_cap)
173 debugBelch("cap %d: waking up thread %lu on cap %d\n",
174 cap->no, (lnat)tso->id, (int)other);
177 case EVENT_STOP_THREAD: // (cap, thread, status)
178 debugBelch("cap %d: thread %lu stopped (%s)\n",
179 cap->no, (lnat)tso->id, thread_stop_reasons[other]);
181 case EVENT_SHUTDOWN: // (cap)
182 debugBelch("cap %d: shutting down\n", cap->no);
184 case EVENT_REQUEST_SEQ_GC: // (cap)
185 debugBelch("cap %d: requesting sequential GC\n", cap->no);
187 case EVENT_REQUEST_PAR_GC: // (cap)
188 debugBelch("cap %d: requesting parallel GC\n", cap->no);
190 case EVENT_GC_START: // (cap)
191 debugBelch("cap %d: starting GC\n", cap->no);
193 case EVENT_GC_END: // (cap)
194 debugBelch("cap %d: finished GC\n", cap->no);
197 debugBelch("cap %2d: thread %lu: event %d\n\n",
198 cap->no, (lnat)tso->id, tag);
202 RELEASE_LOCK(&trace_utx);
206 void traceSchedEvent_ (Capability *cap, EventTypeNum tag,
207 StgTSO *tso, StgWord64 other)
210 if (RtsFlags.TraceFlags.tracing == TRACE_STDERR) {
211 traceSchedEvent_stderr(cap, tag, tso, other);
215 postSchedEvent(cap,tag,tso ? tso->id : 0,other);
220 static void traceCap_stderr(Capability *cap, char *msg, va_list ap)
222 ACQUIRE_LOCK(&trace_utx);
225 debugBelch("cap %2d: ", cap->no);
229 RELEASE_LOCK(&trace_utx);
233 void traceCap_(Capability *cap, char *msg, ...)
239 if (RtsFlags.TraceFlags.tracing == TRACE_STDERR) {
240 traceCap_stderr(cap, msg, ap);
244 postCapMsg(cap, msg, ap);
251 static void trace_stderr(char *msg, va_list ap)
253 ACQUIRE_LOCK(&trace_utx);
259 RELEASE_LOCK(&trace_utx);
263 void trace_(char *msg, ...)
269 if (RtsFlags.TraceFlags.tracing == TRACE_STDERR) {
270 trace_stderr(msg, ap);
280 void traceUserMsg(Capability *cap, char *msg)
283 if (RtsFlags.TraceFlags.tracing == TRACE_STDERR) {
284 traceCap_stderr(cap, msg, NULL);
288 if (eventlog_enabled) {
289 postUserMsg(cap, msg);
294 void traceThreadStatus_ (StgTSO *tso USED_IF_DEBUG)
297 if (RtsFlags.TraceFlags.tracing == TRACE_STDERR) {
298 printThreadStatus(tso);
302 /* nothing - no event for this one yet */
308 void traceBegin (const char *str, ...)
313 ACQUIRE_LOCK(&trace_utx);
322 RELEASE_LOCK(&trace_utx);