Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 362 lines (298 sloc) 9.432 kb
f22644b @makelinux ctracer.h cleanup
authored
1 /*
2 Tracing utility for C
3
4 implemented in include-file only
5
6 Copyright (C) 2012 Constantine Shulyupin http://www.makelinux.net/
7
8 Dual BSD/GPL License
9 */
10
9bef4eb @makelinux +checkpatch
authored
11 #if 0
12 /* Optional configuration flags: */
13 #define TRACE_TIME
14 #define TRACE_MALLOC
15 #define TRACE_LINUX_MEMORY_ON
16 #endif
f22644b @makelinux ctracer.h cleanup
authored
17 /*
9bd51e9 @makelinux +ioctl
authored
18 VI command to include label _entry to each function start for tracing
f22644b @makelinux ctracer.h cleanup
authored
19 :%s/) *\n{ *$/)\r{\t_entry:;/
20 */
21
224a501 @makelinux +ctracer.h
authored
22 #ifndef __ASSEMBLY__
23
f22644b @makelinux ctracer.h cleanup
authored
24 #ifndef CTRACER_H_INCLUDED
25 #define CTRACER_H_INCLUDED
9bd51e9 @makelinux +ioctl
authored
26 extern __thread int ret;
224a501 @makelinux +ctracer.h
authored
27
9d1a964 @makelinux cleanup
authored
28 #define multistatement(ms) ms /*trick to bypass checkpatch.pl error */
9bef4eb @makelinux +checkpatch
authored
29 #define _entry multistatement(trllog(); goto _entry; _entry)
30 /*
31 #define _entry _trace_enter_exit_(); trln(); goto _entry_second; _entry_second
32 #define _entry once(trl()); goto _entry; _entry
33 #define return trlm("} "); return
34 */
224a501 @makelinux +ctracer.h
authored
35
9bef4eb @makelinux +checkpatch
authored
36 #define do_statement(a) do { a } while (0)
224a501 @makelinux +ctracer.h
authored
37
9d1a964 @makelinux cleanup
authored
38 /*
39 trace variables: integer, hex, string, pointer, float, time value, with and w/o new line
40 macro with '_' doesn't prints new line
41 notation:
42 tr = trace
43 v<letter> = printf Variable in specified format (d, x, f, s, etc)
44 */
45
46 #define trla(fmt, args...) tracef("%s:%i %s "fmt, __file__, __LINE__, __func__, ## args)
47 #define trv(t, v) tracef(#v" = %"t EOL, v)
48 #define trv_(t, v) tracef(#v" = %"t" ", v)
6c4ad71 @makelinux +multiple char device with Device Model
authored
49 #define trvd(d) trv("d", (int)d)
9d1a964 @makelinux cleanup
authored
50 #define trvd_(d) trv_("d", d)
51 #define trvx_(x) tracef(#x" = 0x%x ", (int)x)
52 #define trvx(x) tracef(#x" = 0x%x"EOL, (int)x)
53 #define trvlx(x) tracef(#x" = %#llx"EOL, (int)x)
54 #define trvX(x) tracef(#x" = %#X"EOL, (int)x)
55 #define trvf(f) tracef(#f" = %f"EOL, f)
56 #define trvf_(f) tracef(#f" = %f ", f)
57 #define trvtv_(tv) tracef(#tv" = %u.%06u ", (unsigned int)tv.tv_sec, (unsigned int)tv.tv_usec)
58 #define trvtv(tv) tracef(#tv" = %u.%06u"EOL, (unsigned int)tv.tv_sec, (unsigned int)tv.tv_usec)
59 #define trvs(s) tracef(#s" = \"%s\""EOL, s)
60 #define trvs_(s) tracef(#s" = \"%s\" ", s)
61 #define trvp(p) tracef(#p" = %08x"EOL, (unsigned)p)
62 #define trvp_(p) tracef(#p" = %08x ", (unsigned)p)
63 #define trvdn(d, n) {int i; tracef("%s", #d"[]="); for (i = 0; i < n; i++) tracef("%d:%d,", i, (*((int *)d+i))); tracef(EOL); }
64 #define trvxn(d, n) {int i; tracef("%s", #d"[]="); for (i = 0; i < n; i++) tracef("%04x,", (*((int *)d+i))); tracef(EOL); }
65 #define trvdr(record) trvdn(&record, sizeof(record)/sizeof(int));
66 #define trvxr(record) trvxn(&record, sizeof(record)/sizeof(int));
67
68 /* trvdnz - TRace Digital Variable, if Not Zero */
69 #define trvdnz(d) { if (d) tracef(#d" = %d"EOL, (int)d); }
70 #define trace(a) do { trla("calling %s {\n", #a); a; tracef("} done\n"); } while (0)
71
72 /* trlm - TRace Location, with Message */
73 #define trlm(m) tracef(SOL"%s:%i %s %s"EOL, __file__, __LINE__, __func__, m)
74 #define trlm_(m) tracef(SOL"%s:%i %s %s ", __file__, __LINE__, __func__, m)
75 #define trl() do { trace_time(); trlm(""); } while (0)
76 #define trl_() tracef(SOL"%s:%i %s ", __file__, __LINE__, __func__)
77 #define trln() tracef(EOL)
78
79 #define trl_in() do_statement(trace_time(); trlm("{");)
80 #define trl_out() do_statement(trace_time(); trlm("}");)
81
82 #define trace_mem(P, N) \
83 IFTRACE({ int i = 0; tracef("%s=", #P); for (; i < (int)(N) ; i++) \
84 { if (i && (!(i % 16))) tracef("%i:", i); \
85 tracef("%02x ", 0xFF & *((char *)((void *)(P))+i)); \
86 if (!((i+1) % 4)) \
87 tracef(" "); \
88 if (!((i+1) % 16)) \
89 tracef(EOL); \
90 }; tracef(EOL); })
91
92 #define trace_mem_int_list(P, N) \
93 IFTRACE({ int i = 0; for (; i < (int)(N); i += sizeof(int)) \
94 { tracef("%i, ", *(int *)((void *)(P)+i)); \
95 }; })
96
97 #define trace_mem_int(P, N) \
98 IFTRACE({ int i = 0; for (; i < (int)(N) ; i += sizeof(int)) \
99 { if (i && (!(i % 16))) tracef("%i:", i); \
100 tracef("%x ", *(int *)((void *)(P)+i)); \
101 if (!((i+1) % 64)) \
102 tracef(EOL); \
103 }; tracef(EOL); })
104
9bd51e9 @makelinux +ioctl
authored
105 #define trace_ioctl(nr) tracef("ioctl=(%c%c %c #%i %i)\n", \
9bef4eb @makelinux +checkpatch
authored
106 (_IOC_READ & _IOC_DIR(nr)) ? 'r' : ' ', (_IOC_WRITE & _IOC_DIR(nr)) ? 'w' : ' ', \
224a501 @makelinux +ctracer.h
authored
107 _IOC_TYPE(nr), _IOC_NR(nr), _IOC_SIZE(nr))
108
9bef4eb @makelinux +checkpatch
authored
109 #define trace_ioctl_(nr) tracef("ioctl=(%i %i %i %i)", _IOC_DIR(nr), _IOC_TYPE(nr), _IOC_NR(nr), _IOC_SIZE(nr))
224a501 @makelinux +ctracer.h
authored
110
9d1a964 @makelinux cleanup
authored
111 #define chkz(a) \
112 (p = a,\
113 ((!p) ? tracef("%s %i %s FAIL %i = %s\n", __FILE__, __LINE__, __func__, p, #a) : 0),\
114 p)
115
116 #define chkn(a) \
117 (ret = a,\
118 ((ret < 0) ? tracef("%s:%i %s FAIL\n\t%i=%s\n", __FILE__, __LINE__, __func__, ret, #a)\
119 : 0), ret)
120
121 #define chkne(a) \
122 (/* tracef("calling %s\n",#a), */ \
123 ret = a,\
124 ((ret < 0) ? tracef("%s:%i %s FAIL errno = %i \"%s\" %i = %s\n", __FILE__, __LINE__, __func__, errno, strerror(errno), ret, #a)\
125 : 0), ret)
126
127 #define chkn2(a) \
128 (ret = a,\
129 ((ret < 0) ? tracef("%s %i %s FAIL %i = %s\n", __FILE__, __LINE__, __func__, ret, #a)\
130 : tracef("%s %i %s %i = %s\n", __FILE__, __LINE__, __func__, ret, #a)),\
131 ret)
132
133 #define once(exp) do_statement( \
134 static int _passed; if (!_passed) {exp; }; _passed = 1;)
224a501 @makelinux +ctracer.h
authored
135
136
9bef4eb @makelinux +checkpatch
authored
137 #ifdef CTRACER_OFF /* force no tracing */
9d1a964 @makelinux cleanup
authored
138 #undef CTRACER_ON
224a501 @makelinux +ctracer.h
authored
139 #endif
140
9d1a964 @makelinux cleanup
authored
141 #ifdef CTRACER_ON
142 #define IFTRACE(x) x
224a501 @makelinux +ctracer.h
authored
143
144 #ifdef __KERNEL__
145 #undef TRACE_TIME
146
147 #ifdef TRACE_LINUX_MEMORY_ON
148 #include <linux/mmzone.h>
149
150 extern int free_pages_prev;
9bef4eb @makelinux +checkpatch
authored
151 #define trace_linux_mem() do { \
224a501 @makelinux +ctracer.h
authored
152 extern zone_t *zone_table[MAX_NR_ZONES*MAX_NR_NODES]; \
153 int mem_change = zone_table[0]->free_pages - free_pages_prev; \
9bef4eb @makelinux +checkpatch
authored
154 if (mem_change) { \
155 trl_(); trvi_(mem_change); trvi(zone_table[0]->free_pages); } \
156 free_pages_prev = zone_table[0]->free_pages; \
157 } while (0)
224a501 @makelinux +ctracer.h
authored
158 #endif
159
160 #define SOL KERN_DEBUG
161 #define tracef(fmt, args...) printk(fmt, ##args)
162
9bef4eb @makelinux +checkpatch
authored
163 #else /* !__KERNEL__ */
9d1a964 @makelinux cleanup
authored
164 /* CTRACER_ON and not __KERNEL__ */
224a501 @makelinux +ctracer.h
authored
165 #include <stdio.h>
166
9bef4eb @makelinux +checkpatch
authored
167 #define tracef(args...) fprintf(stderr, ##args)
224a501 @makelinux +ctracer.h
authored
168
9bef4eb @makelinux +checkpatch
authored
169 #if 0
170 #include <signal.h>
171 #define BP {trl(); kill(0, SIGTRAP); }
172 #define BP kill(0, SIGTRAP)
173 #endif
224a501 @makelinux +ctracer.h
authored
174
175 #ifndef tracef
176 #define tracef printf
177 #endif
9bef4eb @makelinux +checkpatch
authored
178 #endif /* !__KERNEL__ */
179
180 #ifndef _hweight32
181 static inline unsigned int _hweight32(unsigned int w)
182 { /* from kernel */
183 w -= (w >> 1) & 0x55555555;
184 w = (w & 0x33333333) + ((w >> 2) & 0x33333333);
185 w = (w + (w >> 4)) & 0x0f0f0f0f;
186 return (w * 0x01010101) >> 24;
187 }
224a501 @makelinux +ctracer.h
authored
188
9bef4eb @makelinux +checkpatch
authored
189 #define _hweight32 _hweight32
224a501 @makelinux +ctracer.h
authored
190 #endif
9bef4eb @makelinux +checkpatch
authored
191 #define trllog(args ...) \
224a501 @makelinux +ctracer.h
authored
192 do { \
9bef4eb @makelinux +checkpatch
authored
193 static int num; \
194 if (_hweight32(num) < 2) { \
195 trla("#%d\n", (int)num); \
196 } num++; \
224a501 @makelinux +ctracer.h
authored
197 } while (0)
198
9bef4eb @makelinux +checkpatch
authored
199 #define trlnum(n, args ...) \
224a501 @makelinux +ctracer.h
authored
200 do { \
9bef4eb @makelinux +checkpatch
authored
201 static int num; \
202 if (num < n) { \
203 trl_(); \
204 tracef("#0x%x", (int)num); \
205 args; \
206 trln(); \
207 } num++; \
224a501 @makelinux +ctracer.h
authored
208 } while (0)
209
9bef4eb @makelinux +checkpatch
authored
210 #define trleach(n, args ...) \
224a501 @makelinux +ctracer.h
authored
211 do { \
9bef4eb @makelinux +checkpatch
authored
212 static int num; \
213 if (!(num % n)) { \
214 trl_(); \
215 trvi_(num); \
216 args; \
217 trln(); \
218 } num++; \
224a501 @makelinux +ctracer.h
authored
219 } while (0)
220
9d1a964 @makelinux cleanup
authored
221 #else /* !CTRACER_ON */
9bef4eb @makelinux +checkpatch
authored
222 #define trllog(args ...)
224a501 @makelinux +ctracer.h
authored
223
9d1a964 @makelinux cleanup
authored
224 #define empty_statement() do { } while (0)
225 static inline int empty_function(void)
226 {
227 return 0;
228 }
229
230 #define IFTRACE(x) empty_statement()
224a501 @makelinux +ctracer.h
authored
231 #define trace_linux_mem() empty_statement()
232 #define tracef(fmt, args...) empty_function()
233 #define stack_trace() empty_statement()
234
9bef4eb @makelinux +checkpatch
authored
235 #endif /* _TARCE */
224a501 @makelinux +ctracer.h
authored
236
237 #ifndef SOL
238 #define SOL ""
239 #endif
9d1a964 @makelinux cleanup
authored
240 #define EOL "\n" /* for console */
224a501 @makelinux +ctracer.h
authored
241
09533cb @makelinux reordered
authored
242 #ifdef MODULE
9bef4eb @makelinux +checkpatch
authored
243 /* omit full absolute path for modules */
6825c67 @makelinux small fixes, + static
authored
244 #define ctracer_cut_path(fn) (fn[0] != '/' ? fn : (strrchr(fn, '/') + 1))
245 #define __file__ ctracer_cut_path(__FILE__)
09533cb @makelinux reordered
authored
246 #else
247 #define __file__ __FILE__
248 #endif
249
9d1a964 @makelinux cleanup
authored
250 #ifdef TRACE_MALLOC
251 static int malloc_count;
252 static void *malloc_trace;
253 #endif
224a501 @makelinux +ctracer.h
authored
254 #ifdef TRACE_MALLOC
255
256 #define malloc(s) \
9bef4eb @makelinux +checkpatch
authored
257 (trla("malloc #%i %p %i\n", ++malloc_count, malloc_trace = malloc(s), s),\
224a501 @makelinux +ctracer.h
authored
258 malloc_trace)
259
9bef4eb @makelinux +checkpatch
authored
260 #define free(p) { free(p); trla("free #%i %p\n", malloc_count--, (void *)p); }
224a501 @makelinux +ctracer.h
authored
261
262 #define strdup(s) \
9bef4eb @makelinux +checkpatch
authored
263 (trla("strdup #%i %p\n", ++malloc_count, malloc_trace = (void *)strdup(s)),\
264 (char *)malloc_trace)
224a501 @makelinux +ctracer.h
authored
265
266 #endif
267
268 #ifdef TRACE_TIME
269
270 #include <time.h>
271 #include <sys/time.h>
272
273 #ifndef trace_time_defined
274 #define trace_time_defined
275
276 void trace_time();
277 /*
278 extern double time_prev_f;
279 void static inline trace_time()
280 {
281 time_t time_cur;
282 double time_cur_f;
283 time(&time_cur);
284 struct timeval tv;
285 struct timezone tz;
286 struct tm* time_tm;
287 gettimeofday(&tv, &tz);
288 time_tm = localtime(&time_cur);
289 time_cur = tv.tv_sec;
290 time_cur_f = 0.000001 * tv.tv_usec + time_cur;
291 double passed = time_cur_f - time_prev_f;
9bef4eb @makelinux +checkpatch
authored
292 if (passed > 0.001)
224a501 @makelinux +ctracer.h
authored
293 {
294 tracef("time=%04d-%02d-%02d %02d:%02d:%02d %02d +%1.4f s\n",
295 time_tm->tm_year+1900, time_tm->tm_mon+1, time_tm->tm_mday,
9bef4eb @makelinux +checkpatch
authored
296 time_tm->tm_hour, time_tm->tm_min, time_tm->tm_sec, (int)tv.tv_usec,
224a501 @makelinux +ctracer.h
authored
297 passed);
298 time_prev_f = time_cur_f;
299 }
300 }
301 */
302 #endif
303
304 #else
305 #define trace_time() empty_statement()
306 #endif
307
308 #ifdef __GLIBC__XX
309 #include <execinfo.h>
310 #include <stdio.h>
311 #include <stdlib.h>
312
313 #ifdef stack_trace
314 #undef stack_trace
315 #endif
316 #ifndef stack_trace_difined
317 #define stack_trace_difined
9bef4eb @makelinux +checkpatch
authored
318 /* only once */
224a501 @makelinux +ctracer.h
authored
319 static inline void stack_trace(void)
320 {
321 void *array[5];
322 size_t size;
323 char **strings;
324 size_t i;
9bd51e9 @makelinux +ioctl
authored
325 size = backtrace(array, sizeof(array) / sizeof(array[0]));
326 strings = backtrace_symbols(array, size);
224a501 @makelinux +ctracer.h
authored
327 tracef("Stack:\n");
328
9bd51e9 @makelinux +ioctl
authored
329 for (i = 0; i < size; i++) {
330 if (!array[i])
331 break;
332 tracef("%i %p %s\n", i, array[i], strings[i]);
224a501 @makelinux +ctracer.h
authored
333 }
9bd51e9 @makelinux +ioctl
authored
334 free(strings);
224a501 @makelinux +ctracer.h
authored
335 }
336 #endif
9bef4eb @makelinux +checkpatch
authored
337 #endif /* __GLIBC__ */
224a501 @makelinux +ctracer.h
authored
338
339 #include <linux/kernel.h>
9bef4eb @makelinux +checkpatch
authored
340 /* see also nr_free_pages */
341 #define freeram() { \
342 static unsigned int last; struct sysinfo i; si_meminfo(&i); trl_(); \
224a501 @makelinux +ctracer.h
authored
343 int d = last-i.freeram; int used = i.totalram-i.freeram; \
9bef4eb @makelinux +checkpatch
authored
344 trvi_(i.freeram); trvi_(used); trvi(d); \
224a501 @makelinux +ctracer.h
authored
345 last = i.freeram; }
346
9bd51e9 @makelinux +ioctl
authored
347 static inline void _func_exit(void *l)
224a501 @makelinux +ctracer.h
authored
348 {
9bd51e9 @makelinux +ioctl
authored
349 char **loc = (char **)l;
350 if (loc)
351 tracef("%s }\n", *loc);
224a501 @makelinux +ctracer.h
authored
352 }
353
9bef4eb @makelinux +checkpatch
authored
354 #define _trace_enter_exit_() char const *_location __attribute__ ((cleanup(_func_exit))) = __func__; \
355 tracef("%s { ", _location);
224a501 @makelinux +ctracer.h
authored
356
9d1a964 @makelinux cleanup
authored
357
358
9bef4eb @makelinux +checkpatch
authored
359 /*__END_DECLS */
360 #endif /* CTRACER_H_INCLUDED */
361 #endif /* __ASSEMBLY__ */
Something went wrong with that request. Please try again.