show more relevant debug
[AROS.git] / rom / exec / exec_debug.c
blob74cc2432e7c4a3bef48dbda2b060e3d12d569eb7
1 /*
2 Copyright © 1995-2012, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Runtime debugging support
6 Lang: english
7 */
9 /*
10 * You can #define this in order to omit the whole code. Perhaps ROM-based systems
11 * will want to do this.
12 * However it's not advised to do so because this is a great aid in debugging
13 * on user's side.
15 #ifndef NO_RUNTIME_DEBUG
17 #include <exec/execbase.h>
18 #include <exec/rawfmt.h>
19 #include <proto/exec.h>
21 #include <ctype.h>
22 #include <string.h>
24 #include "exec_debug.h"
26 #if defined(__AROSEXEC_SMP__)
27 #include <aros/atomic.h>
28 #include <asm/cpu.h>
29 extern volatile ULONG safedebug;
30 #endif
32 const char * const ExecFlagNames[] =
34 "InitResident",
35 "InitCode",
36 "FindResident",
37 (char *)-1, /* Reserved bit */
38 "CreateLibrary",
39 "SetFunction",
40 "NewSetFunction",
41 "ChipRam",
42 "AddTask",
43 "RemTask",
44 "GetTaskAttr",
45 "SetTaskAttr",
46 "ExceptHandler",
47 "AddDosNode",
48 "PCI",
49 "RamLib",
50 (char *)-1, /* NoLogServer */
51 (char *)-1, /* NoLogWindow */
52 (char *)-1, /* LogFile */
53 (char *)-1, /* LogKPrintF */
54 (char *)-1, /* PermMemTrack */
55 "MemTrack",
56 (char *)-1, /* CyberGuardDelay */
57 "LogExtended",
58 "LoadSeg",
59 "UnloadSeg",
60 (char *)-1, /* PPCStart */
61 "CGXDebug",
62 "InvZeroPage",
63 (char *)-1, /* Reserved bit */
64 "Init",
65 NULL
68 void ExecLog(struct ExecBase *SysBase, ULONG flags, const char *format, ...)
70 va_list ap;
72 flags &= SysBase->ex_DebugFlags;
73 if (!flags)
74 return;
76 va_start(ap, format);
77 VLog(SysBase, flags, ExecFlagNames, format, ap);
78 va_end(ap);
82 * The following stuff is a candidate to become a public API.
83 * Currently i have no idea into what component to put it, so for now
84 * it's exec.library's private property.
85 * The main problem is that we need it very early, before debug.library
86 * and whatever else wakes up.
90 * Return a set of flags specified on the command line.
91 * Option format: <flag1>,<flags>,...,<flagN>
92 * Or: "<flag1> <flag2> ... <flagN>"
94 ULONG ParseFlags(char *opts, const char * const *FlagNames)
96 ULONG ret = 0;
97 char quoted = 0;
99 if (*opts == '"')
101 quoted = 1;
102 opts++;
105 while (isalpha(*opts))
107 char *p = opts + 1;
108 unsigned int i;
110 /* Find the end of the word */
111 while (isalpha(*p))
112 p++;
114 /* "ALL" means all flags */
115 if (!strnicmp(opts, "all", 3))
116 return -1;
118 /* Decode flag name */
119 for (i = 0; FlagNames[i]; i++)
121 const char *flagName = FlagNames[i];
123 if (flagName == (char *)-1)
124 continue;
126 if (!strnicmp(opts, flagName, strlen(flagName)))
128 ret |= (1UL << i);
129 break;
133 if (quoted)
135 /* Skip separator characters */
136 while (!isalpha(*p))
138 /* If we hit closing quotes or end of line, this is the end */
139 if (*p == '"')
140 return ret;
142 if (*p == 0)
143 return ret;
146 /* Next word is found */
147 opts = p;
149 else
151 /* If the string is not quoted, only single comma is allowed as a separator */
152 if (*p != ',')
153 break;
155 opts = p + 1;
159 return ret;
162 void VLog(struct ExecBase *SysBase, ULONG flags, const char * const *FlagNames, const char *format, va_list args)
164 unsigned int i;
166 #if defined(__AROSEXEC_SMP__)
167 if (safedebug & 1)
169 while (bit_test_and_set_long((ULONG*)&safedebug, 1)) { };
171 #endif
173 /* Prepend tag (if known) */
174 for (i = 0; FlagNames[i]; i++)
176 if (FlagNames[i] == (char *)-1)
177 continue;
179 if (flags & (1UL << i))
181 RawDoFmt("[EXEC] %s: ", (APTR)&FlagNames[i], (VOID_FUNC)RAWFMTFUNC_SERIAL, NULL);
182 break;
186 /* Output the message and append a newline (in order not to bother about it every time) */
187 VNewRawDoFmt(format, (VOID_FUNC)RAWFMTFUNC_SERIAL, NULL, args);
188 RawPutChar('\n');
189 #if defined(__AROSEXEC_SMP__)
190 if (safedebug & 1)
192 __AROS_ATOMIC_AND_L(safedebug, ~(1 << 1));
194 #endif
197 #endif