2 * trace.c: Tracing facilities for the Mono Runtime.
5 * Paolo Molaro (lupus@ximian.com)
6 * Dietmar Maurer (dietmar@ximian.com)
8 * (C) 2002 Ximian, Inc.
16 #include <mono/metadata/debug-helpers.h>
19 static MonoTraceSpec trace_spec;
22 mono_trace_eval (MonoMethod *method)
24 MonoTraceSpec *s = mono_jit_trace_calls;
28 for (i = 0; i < trace_spec.len; i++){
29 MonoTraceOperation *op = &trace_spec.ops [i];
33 case MONO_TRACEOP_ALL:
35 case MONO_TRACEOP_PROGRAM:
36 if (method->klass->image == trace_spec.assembly->image)
38 case MONO_TRACEOP_METHOD:
39 if (mono_method_desc_match ((MonoMethodDesc *) op->data, method))
41 case MONO_TRACEOP_CLASS:
42 if (strcmp (method->klass->name_space, op->data) == 0)
43 if (strcmp (method->klass->name, op->data2) == 0)
46 case MONO_TRACEOP_ASSEMBLY:
47 if (strcmp (method->klass->image->assembly_name, op->data) == 0)
49 case MONO_TRACEOP_NAMESPACE:
50 if (strcmp (method->klass->name_space, op->data) == 0)
62 static int is_filenamechar (char p)
64 if (p >= 'A' && p <= 'Z')
66 if (p >= 'a' && p <= 'z')
68 if (p == '.' || p == ':')
76 static void get_string (void)
79 while (is_filenamechar (*input)){
84 value = g_malloc (input - start + 1);
85 strncpy (value, start, input-start);
86 value [input-start] = 0;
106 if (input [0] == 'M' && input [1] == ':'){
111 if (input [0] == 'N' && input [1] == ':'){
114 return TOKEN_NAMESPACE;
116 if (input [0] == 'T' && input [1] == ':'){
121 if (is_filenamechar (*input)){
123 if (strcmp (value, "all") == 0)
125 if (strcmp (value, "program") == 0)
126 return TOKEN_PROGRAM;
131 return TOKEN_EXCLUDE;
135 return TOKEN_SEPARATOR;
153 int token = get_token ();
154 if (token == TOKEN_EXCLUDE){
155 token = get_spec (last);
156 if (token == TOKEN_EXCLUDE){
157 fprintf (stderr, "Expecting an expression");
160 if (token == TOKEN_ERROR)
162 trace_spec.ops [(*last)-1].exclude = 1;
163 return TOKEN_SEPARATOR;
165 if (token == TOKEN_END || token == TOKEN_SEPARATOR || token == TOKEN_ERROR)
168 if (token == TOKEN_METHOD){
169 MonoMethodDesc *desc = mono_method_desc_new (value, TRUE);
171 fprintf (stderr, "Invalid method name: %s\n", value);
174 trace_spec.ops [*last].op = MONO_TRACEOP_METHOD;
175 trace_spec.ops [*last].data = desc;
176 } else if (token == TOKEN_ALL)
177 trace_spec.ops [*last].op = MONO_TRACEOP_ALL;
178 else if (token == TOKEN_PROGRAM)
179 trace_spec.ops [*last].op = MONO_TRACEOP_PROGRAM;
180 else if (token == TOKEN_NAMESPACE){
181 trace_spec.ops [*last].op = MONO_TRACEOP_NAMESPACE;
182 trace_spec.ops [*last].data = g_strdup (value);
183 } else if (token == TOKEN_CLASS){
184 char *p = strrchr (value, '.');
186 trace_spec.ops [*last].op = MONO_TRACEOP_CLASS;
187 trace_spec.ops [*last].data = g_strdup (value);
188 trace_spec.ops [*last].data2 = g_strdup (p);
189 } else if (token == TOKEN_STRING){
190 trace_spec.ops [*last].op = MONO_TRACEOP_ASSEMBLY;
191 trace_spec.ops [*last].data = g_strdup (value);
194 fprintf (stderr, "Syntax error in trace option specification\n");
198 return TOKEN_SEPARATOR;
201 static const char *xmap (int idx)
204 case MONO_TRACEOP_ALL: return "all";
205 case MONO_TRACEOP_PROGRAM: return "program";
206 case MONO_TRACEOP_METHOD: return "method";
207 case MONO_TRACEOP_ASSEMBLY: return "assembly";
208 case MONO_TRACEOP_CLASS: return "class";
214 mono_trace_parse_options (MonoAssembly *assembly, char *options)
222 trace_spec.assembly = assembly;
226 trace_spec.ops = g_new0 (MonoTraceOperation, 1);
227 trace_spec.ops [0].op = MONO_TRACEOP_ALL;
231 for (p = options; *p != 0; p++)
235 trace_spec.ops = g_new0 (MonoTraceOperation, size);
240 while ((token = (get_spec (&last_used))) != TOKEN_END){
241 if (token == TOKEN_ERROR)
243 if (token == TOKEN_SEPARATOR)
246 trace_spec.len = last_used;