Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/*
2
 * Print functions for system call tracing.
3
 */
4
#include "u.h"
5
#include "../port/lib.h"
6
#include "mem.h"
7
#include "dat.h"
8
#include "fns.h"
9
 
10
#include "/sys/src/libc/9syscall/sys.h"
11
 
12
// WE ARE OVERRUNNING SOMEHOW
13
static void
14
fmtrwdata(Fmt* f, char* a, int n, char* suffix)
15
{
16
	int i;
17
	char *t;
18
 
19
	if(a == nil){
20
		fmtprint(f, "0x0%s", suffix);
21
		return;
22
	}
23
	validaddr((ulong)a, n, 0);
24
	t = smalloc(n+1);
25
	for(i = 0; i < n; i++)
26
		if(a[i] > 0x20 && a[i] < 0x7f)	/* printable ascii? */
27
			t[i] = a[i];
28
		else
29
			t[i] = '.';
30
 
31
	fmtprint(f, " %#p/\"%s\"%s", a, t, suffix);
32
	free(t);
33
}
34
 
35
static void
36
fmtuserstring(Fmt* f, char* a, char* suffix)
37
{
38
	int n;
39
	char *t;
40
 
41
	if(a == nil){
42
		fmtprint(f, "0/\"\"%s", suffix);
43
		return;
44
	}
45
	validaddr((ulong)a, 1, 0);
46
	n = ((char*)vmemchr(a, 0, 0x7fffffff) - a) + 1;
47
	t = smalloc(n+1);
48
	memmove(t, a, n);
49
	t[n] = 0;
50
	fmtprint(f, "%#p/\"%s\"%s", a, t, suffix);
51
	free(t);
52
}
53
 
54
void
55
syscallfmt(int syscallno, ulong pc, va_list list)
56
{
57
	long l;
58
	Fmt fmt;
59
	void *v;
60
	vlong vl;
61
	uintptr p;
62
	int i[2], len;
63
	char *a, **argv;
64
 
65
	fmtstrinit(&fmt);
66
	fmtprint(&fmt, "%uld %s ", up->pid, up->text);
67
 
68
	if(syscallno > nsyscall)
69
		fmtprint(&fmt, " %d ", syscallno);
70
	else
71
		fmtprint(&fmt, "%s ", sysctab[syscallno]?
72
			sysctab[syscallno]: "huh?");
73
 
74
	fmtprint(&fmt, "%ulx ", pc);
75
	if(up->syscalltrace != nil)
76
		free(up->syscalltrace);
77
 
78
	switch(syscallno){
79
	case SYSR1:
80
		p = va_arg(list, uintptr);
81
		fmtprint(&fmt, "%#p", p);
82
		break;
83
	case _ERRSTR:					/* deprecated */
84
	case CHDIR:
85
	case EXITS:
86
	case REMOVE:
87
		a = va_arg(list, char*);
88
		fmtuserstring(&fmt, a, "");
89
		break;
90
	case BIND:
91
		a = va_arg(list, char*);
92
		fmtuserstring(&fmt, a, " ");
93
		a = va_arg(list, char*);
94
		fmtuserstring(&fmt, a, " ");
95
		i[0] = va_arg(list, int);
96
		fmtprint(&fmt, "%#ux",  i[0]);
97
		break;
98
	case CLOSE:
99
	case NOTED:
100
		i[0] = va_arg(list, int);
101
		fmtprint(&fmt, "%d", i[0]);
102
		break;
103
	case DUP:
104
		i[0] = va_arg(list, int);
105
		i[1] = va_arg(list, int);
106
		fmtprint(&fmt, "%d %d", i[0], i[1]);
107
		break;
108
	case ALARM:
109
		l = va_arg(list, unsigned long);
110
		fmtprint(&fmt, "%#lud ", l);
111
		break;
112
	case EXEC:
113
		a = va_arg(list, char*);
114
		fmtuserstring(&fmt, a, "");
115
		argv = va_arg(list, char**);
116
		validalign(PTR2UINT(argv), sizeof(char*));
117
		for(;;){
118
			validaddr((ulong)argv, sizeof(char**), 0);
119
			a = *(char **)argv;
120
			if(a == nil)
121
				break;
122
			fmtprint(&fmt, " ");
123
			fmtuserstring(&fmt, a, "");
124
			argv++;
125
		}
126
		break;
127
	case _FSESSION:					/* deprecated */
128
	case _FSTAT:					/* deprecated */
129
	case _FWSTAT:					/* obsolete */
130
		i[0] = va_arg(list, int);
131
		a = va_arg(list, char*);
132
		fmtprint(&fmt, "%d %#p", i[0], a);
133
		break;
134
	case FAUTH:
135
		i[0] = va_arg(list, int);
136
		a = va_arg(list, char*);
137
		fmtprint(&fmt, "%d", i[0]);
138
		fmtuserstring(&fmt, a, "");
139
		break;
140
	case SEGBRK:
141
	case RENDEZVOUS:
142
		v = va_arg(list, void*);
143
		fmtprint(&fmt, "%#p ", v);
144
		v = va_arg(list, void*);
145
		fmtprint(&fmt, "%#p", v);
146
		break;
147
	case _MOUNT:					/* deprecated */
148
		i[0] = va_arg(list, int);
149
		fmtprint(&fmt, "%d ", i[0]);
150
		a = va_arg(list, char*);
151
		fmtuserstring(&fmt, a, " ");
152
		i[0] = va_arg(list, int);
153
		fmtprint(&fmt, "%#ux ", i[0]);
154
		a = va_arg(list, char*);
155
		fmtuserstring(&fmt, a, "");
156
		break;
157
	case OPEN:
158
		a = va_arg(list, char*);
159
		fmtuserstring(&fmt, a, " ");
160
		i[0] = va_arg(list, int);
161
		fmtprint(&fmt, "%#ux", i[0]);
162
		break;
163
	case OSEEK:					/* deprecated */
164
		i[0] = va_arg(list, int);
165
		l = va_arg(list, long);
166
		i[1] = va_arg(list, int);
167
		fmtprint(&fmt, "%d %ld %d", i[0], l, i[1]);
168
		break;
169
	case SLEEP:
170
		l = va_arg(list, long);
171
		fmtprint(&fmt, "%ld", l);
172
		break;
173
	case _STAT:					/* obsolete */
174
	case _WSTAT:					/* obsolete */
175
		a = va_arg(list, char*);
176
		fmtuserstring(&fmt, a, " ");
177
		a = va_arg(list, char*);
178
		fmtprint(&fmt, "%#p", a);
179
		break;
180
	case RFORK:
181
		i[0] = va_arg(list, int);
182
		fmtprint(&fmt, "%#ux", i[0]);
183
		break;
184
	case PIPE:
185
	case BRK_:
186
		v = va_arg(list, int*);
187
		fmtprint(&fmt, "%#p", v);
188
		break;
189
	case CREATE:
190
		a = va_arg(list, char*);
191
		fmtuserstring(&fmt, a, " ");
192
		i[0] = va_arg(list, int);
193
		i[1] = va_arg(list, int);
194
		fmtprint(&fmt, "%#ux %#ux", i[0], i[1]);
195
		break;
196
	case FD2PATH:
197
	case FSTAT:
198
	case FWSTAT:
199
		i[0] = va_arg(list, int);
200
		a = va_arg(list, char*);
201
		l = va_arg(list, unsigned long);
202
		fmtprint(&fmt, "%d %#p %lud", i[0], a, l);
203
		break;
204
	case NOTIFY:
205
	case SEGDETACH:
206
	case _WAIT:					/* deprecated */
207
		v = va_arg(list, void*);
208
		fmtprint(&fmt, "%#p", v);
209
		break;
210
	case SEGATTACH:
211
		i[0] = va_arg(list, int);
212
		fmtprint(&fmt, "%d ", i[0]);
213
		a = va_arg(list, char*);
214
		fmtuserstring(&fmt, a, " ");
215
		/*FALLTHROUGH*/
216
	case SEGFREE:
217
	case SEGFLUSH:
218
		v = va_arg(list, void*);
219
		l = va_arg(list, unsigned long);
220
		fmtprint(&fmt, "%#p %lud", v, l);
221
		break;
222
	case UNMOUNT:
223
		a = va_arg(list, char*);
224
		fmtuserstring(&fmt, a, " ");
225
		a = va_arg(list, char*);
226
		fmtuserstring(&fmt, a, "");
227
		break;
228
	case SEMACQUIRE:
229
	case SEMRELEASE:
230
		v = va_arg(list, int*);
231
		i[0] = va_arg(list, int);
232
		fmtprint(&fmt, "%#p %d", v, i[0]);
233
		break;
234
	case TSEMACQUIRE:
235
		v = va_arg(list, long*);
236
		l = va_arg(list, ulong);
237
		fmtprint(&fmt, "%#p %ld", v, l);
238
		break;
239
	case SEEK:
240
		v = va_arg(list, vlong*);
241
		i[0] = va_arg(list, int);
242
		vl = va_arg(list, vlong);
243
		i[1] = va_arg(list, int);
244
		fmtprint(&fmt, "%#p %d %#llux %d", v, i[0], vl, i[1]);
245
		break;
246
	case FVERSION:
247
		i[0] = va_arg(list, int);
248
		i[1] = va_arg(list, int);
249
		fmtprint(&fmt, "%d %d ", i[0], i[1]);
250
		a = va_arg(list, char*);
251
		fmtuserstring(&fmt, a, " ");
252
		l = va_arg(list, unsigned long);
253
		fmtprint(&fmt, "%lud", l);
254
		break;
255
	case WSTAT:
256
	case STAT:
257
		a = va_arg(list, char*);
258
		fmtuserstring(&fmt, a, " ");
259
		/*FALLTHROUGH*/
260
	case ERRSTR:
261
	case AWAIT:
262
		a = va_arg(list, char*);
263
		l = va_arg(list, unsigned long);
264
		fmtprint(&fmt, "%#p %lud", a, l);
265
		break;
266
	case MOUNT:
267
		i[0] = va_arg(list, int);
268
		i[1] = va_arg(list, int);
269
		fmtprint(&fmt, "%d %d ", i[0], i[1]);
270
		a = va_arg(list, char*);
271
		fmtuserstring(&fmt, a, " ");
272
		i[0] = va_arg(list, int);
273
		fmtprint(&fmt, "%#ux ", i[0]);
274
		a = va_arg(list, char*);
275
		fmtuserstring(&fmt, a, "");
276
		break;
277
	case _READ:					/* deprecated */
278
	case PREAD:
279
		i[0] = va_arg(list, int);
280
		v = va_arg(list, void*);
281
		l = va_arg(list, long);
282
		fmtprint(&fmt, "%d %#p %ld", i[0], v, l);
283
		if(syscallno == PREAD){
284
			vl = va_arg(list, vlong);
285
			fmtprint(&fmt, " %lld", vl);
286
		}
287
		break;
288
	case _WRITE:					/* deprecated */
289
	case PWRITE:
290
		i[0] = va_arg(list, int);
291
		v = va_arg(list, void*);
292
		l = va_arg(list, long);
293
		fmtprint(&fmt, "%d ", i[0]);
294
		len = MIN(l, 64);
295
		fmtrwdata(&fmt, v, len, " ");
296
		fmtprint(&fmt, "%ld", l);
297
		if(syscallno == PWRITE){
298
			vl = va_arg(list, vlong);
299
			fmtprint(&fmt, " %lld", vl);
300
		}
301
		break;
302
	case NSEC:
303
		v = va_arg(list, vlong*);
304
		fmtprint(&fmt, "%#p", v);
305
		break;
306
	}
307
 
308
	up->syscalltrace = fmtstrflush(&fmt);
309
}
310
 
311
void
312
sysretfmt(int syscallno, va_list list, long ret, uvlong start, uvlong stop)
313
{
314
	long l;
315
	void* v;
316
	Fmt fmt;
317
	vlong vl;
318
	int i, len;
319
	char *a, *errstr;
320
 
321
	fmtstrinit(&fmt);
322
 
323
	if(up->syscalltrace)
324
		free(up->syscalltrace);
325
 
326
	errstr = "\"\"";
327
	switch(syscallno){
328
	default:
329
	case ALARM:
330
	case _WRITE:
331
	case PWRITE:
332
		if(ret == -1)
333
			errstr = up->syserrstr;
334
		fmtprint(&fmt, " = %ld", ret);
335
		break;
336
	case EXEC:
337
	case SEGBRK:
338
	case SEGATTACH:
339
	case RENDEZVOUS:
340
		if((void *)ret == (void*)-1)
341
			errstr = up->syserrstr;
342
		fmtprint(&fmt, " = %#p", (void *)ret);
343
		break;
344
	case AWAIT:
345
		a = va_arg(list, char*);
346
		l = va_arg(list, unsigned long);
347
		if(ret > 0){
348
			fmtuserstring(&fmt, a, " ");
349
			fmtprint(&fmt, "%lud = %ld", l, ret);
350
		}
351
		else{
352
			fmtprint(&fmt, "%#p/\"\" %lud = %ld", a, l, ret);
353
			errstr = up->syserrstr;
354
		}
355
		break;
356
	case _ERRSTR:
357
	case ERRSTR:
358
		a = va_arg(list, char*);
359
		if(syscallno == _ERRSTR)
360
			l = 64;
361
		else
362
			l = va_arg(list, unsigned long);
363
		if(ret > 0){
364
			fmtuserstring(&fmt, a, " ");
365
			fmtprint(&fmt, "%lud = %ld", l, ret);
366
		}
367
		else{
368
			fmtprint(&fmt, "\"\" %lud = %ld", l, ret);
369
			errstr = up->syserrstr;
370
		}
371
		break;
372
	case FD2PATH:
373
		i = va_arg(list, int);
374
		USED(i);
375
		a = va_arg(list, char*);
376
		l = va_arg(list, unsigned long);
377
		if(ret > 0){
378
			fmtuserstring(&fmt, a, " ");
379
			fmtprint(&fmt, "%lud = %ld", l, ret);
380
		}
381
		else{
382
			fmtprint(&fmt, "\"\" %lud = %ld", l, ret);
383
			errstr = up->syserrstr;
384
		}
385
		break;
386
	case _READ:
387
	case PREAD:
388
		i = va_arg(list, int);
389
		USED(i);
390
		v = va_arg(list, void*);
391
		l = va_arg(list, long);
392
		if(ret > 0){
393
			len = MIN(ret, 64);
394
			fmtrwdata(&fmt, v, len, "");
395
		}
396
		else{
397
			fmtprint(&fmt, "/\"\"");
398
			errstr = up->syserrstr;
399
		}
400
		fmtprint(&fmt, " %ld", l);
401
		if(syscallno == PREAD){
402
			vl = va_arg(list, vlong);
403
			fmtprint(&fmt, " %lld", vl);
404
		}
405
		fmtprint(&fmt, " = %ld", ret);
406
		break;
407
	case NSEC:
408
		fmtprint(&fmt, " = %ld", ret);		/* FoV */
409
		break;
410
	}
411
	fmtprint(&fmt, " %s %#llud %#llud\n", errstr, start, stop);
412
	up->syscalltrace = fmtstrflush(&fmt);
413
}