Remove stackanalysis_printf from Dyninst; it's a DataflowAPI debug method.
[dyninst.git] / dyninstAPI / src / debug.C
1 /*
2  * Copyright (c) 1996-2009 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31
32 // $Id: debug.C,v 1.6 2008/02/23 02:09:05 jaw Exp $
33
34 #include <stdio.h>
35 #include <stdarg.h>
36 #include <assert.h>
37 #include <string>
38 #include "common/h/Pair.h"
39 #include "common/h/Vector.h"
40 #include "util.h"
41 #include "BPatch.h"
42 #include "dyninstAPI/src/debug.h"
43 #include "EventHandler.h"
44
45 // Make a lock.
46
47 eventLock *debugPrintLock = NULL;
48
49 void BPatch_reportError(int errLevel, int num, const char *str) {
50     BPatch::reportError((BPatchErrorLevel) errLevel, num, str);
51 }
52
53 void
54 dyninst_log_perror(const char* msg) {
55     sprintf(errorLine, "%s: %s\n", msg, strerror(errno));
56     logLine(errorLine);
57     // fprintf(stderr, "%s", log_buffer);
58 }
59 void showInfoCallback(std::string msg)
60 {
61     BPatch::reportError(BPatchWarning, 0, msg.c_str());
62 }
63
64 char errorLine[1024];
65
66 void showErrorCallback(int num, std::string msg)
67 {
68     BPatch::reportError(BPatchSerious, num, msg.c_str());
69 }
70
71 void logLine(const char *line)
72 {
73     BPatch::reportError(BPatchWarning, 0, line);
74 }
75
76 // The unused parameter is used by Paradyn's version of this function.
77 void statusLine(const char *line, bool /* unused */ )
78 {
79     BPatch::reportError(BPatchInfo, 0, line);
80 }
81
82 //  bpfatal, bpsevere, bpwarn, and bpinfo are intended as drop-in 
83 //  replacements for printf.
84 #define ERR_BUF_SIZE 2048 // egad -- 1024 is not large enough
85
86 int bpfatal(const char *format, ...)
87 {
88   if (NULL == format) return -1;
89
90   char errbuf[ERR_BUF_SIZE];
91
92   va_list va;
93   va_start(va, format);
94 #if defined (i386_unknown_nt4_0)
95   _vsnprintf(errbuf, ERR_BUF_SIZE,format, va);
96 #else
97   vsnprintf(errbuf, ERR_BUF_SIZE,format, va);
98 #endif
99   va_end(va);
100
101   BPatch::reportError(BPatchFatal, 0, errbuf);
102
103   return 0;
104 }
105
106
107 int bpfatal_lf(const char *__file__, unsigned int __line__, const char *format, ...)
108 {
109   fprintf(stderr, "%s[%d]\n", __FILE__, __LINE__);
110   if (NULL == format) return -1;
111
112   char errbuf[ERR_BUF_SIZE];
113
114   fprintf(stderr, "%s[%d]\n", __FILE__, __LINE__);
115   int header_len = sprintf(errbuf, "[%s]%s[%d]: ", getThreadStr(getExecThreadID()), __file__, __line__);
116
117   fprintf(stderr, "%s[%d]\n", __FILE__, __LINE__);
118   va_list va;
119   va_start(va, format);
120   VSNPRINTF(errbuf + header_len, ERR_BUF_SIZE,format, va);
121   va_end(va);
122
123   fprintf(stderr, "%s[%d]\n", __FILE__, __LINE__);
124   BPatch::reportError(BPatchFatal, 0, errbuf);
125
126   fprintf(stderr, "%s[%d]\n", __FILE__, __LINE__);
127   return 0;
128 }
129
130 int bperr(const char *format, ...)
131 {
132   if (NULL == format) return -1;
133
134   char errbuf[ERR_BUF_SIZE];
135
136   va_list va;
137   va_start(va, format);
138 #if defined (i386_unknown_nt4_0)
139   int errbuflen = _vsnprintf(errbuf, ERR_BUF_SIZE, format, va);
140 #else
141   int errbuflen = vsnprintf(errbuf, ERR_BUF_SIZE, format, va);
142 #endif
143   va_end(va);
144
145   char syserr[128];
146   if (errno) {
147 #if defined (i386_unknown_nt4_0)
148     int syserrlen = _snprintf(syserr, 128," [%d: %s]", errno, strerror(errno));
149 #else
150     int syserrlen = snprintf(syserr, 128," [%d: %s]", errno, strerror(errno));
151 #endif
152     /* reset errno so that future calls to this function don't report same error */
153     errno = 0; 
154
155     if ((errbuflen + syserrlen) < ERR_BUF_SIZE)
156       strcat(errbuf, syserr);
157     else {
158       BPatch::reportError(BPatchSerious, 0, errbuf);
159       BPatch::reportError(BPatchSerious, 0, syserr);
160       return 0;
161     }
162   }
163   BPatch::reportError(BPatchSerious, 0, errbuf);
164
165   return 0;
166 }
167
168 int bpwarn(const char *format, ...)
169 {
170   if (NULL == format) return -1;
171
172   char errbuf[ERR_BUF_SIZE];
173
174   va_list va;
175   va_start(va, format);
176 #if defined (i386_unknown_nt4_0)
177   _vsnprintf(errbuf, ERR_BUF_SIZE,format, va);
178 #else
179   vsnprintf(errbuf, ERR_BUF_SIZE,format, va);
180 #endif
181   va_end(va);
182
183   BPatch::reportError(BPatchWarning, 0, errbuf);
184
185   return 0;
186 }
187
188 int bpinfo(const char *format, ...)
189 {
190   if (NULL == format) return -1;
191
192   char errbuf[ERR_BUF_SIZE];
193
194   va_list va;
195   va_start(va, format);
196 #if defined (i386_unknown_nt4_0)
197   _vsnprintf(errbuf, ERR_BUF_SIZE, format, va);
198 #else
199   vsnprintf(errbuf, ERR_BUF_SIZE, format, va);
200 #endif
201   va_end(va);
202
203   BPatch::reportError(BPatchInfo, 0, errbuf);
204
205   return 0;
206 }
207
208
209 // Internal debugging
210
211 int dyn_debug_malware = 0;
212 int dyn_debug_signal = 0;
213 int dyn_debug_infrpc = 0;
214 int dyn_debug_startup = 0;
215 int dyn_debug_parsing = 0;
216 int dyn_debug_forkexec = 0;
217 int dyn_debug_proccontrol = 0;
218 int dyn_debug_stackwalk = 0;
219 int dyn_debug_dbi = 0;
220 int dyn_debug_inst = 0;
221 int dyn_debug_reloc = 0;
222 int dyn_debug_dyn_unw = 0;
223 int dyn_debug_dyn_dbi = 0;
224 int dyn_debug_mutex = 0;
225 int dyn_debug_mailbox = 0;
226 int dyn_debug_async = 0;
227 int dyn_debug_dwarf = 0;
228 int dyn_debug_thread = 0;
229 int dyn_debug_rtlib = 0;
230 int dyn_debug_catchup = 0;
231 int dyn_debug_bpatch = 0;
232 int dyn_debug_regalloc = 0;
233 int dyn_debug_ast = 0;
234 int dyn_debug_write = 0;
235 int dyn_debug_liveness = 0;
236 int dyn_debug_infmalloc = 0;
237 int dyn_debug_crash = 0;
238 char *dyn_debug_crash_debugger = NULL;
239 int dyn_debug_relocation = 0;
240
241 static char *dyn_debug_write_filename = NULL;
242 static FILE *dyn_debug_write_file = NULL;
243
244 bool init_debug() {
245   char *p;
246   if ( (p=getenv("DYNINST_DEBUG_MALWARE"))) {
247     fprintf(stderr, "Enabling DyninstAPI malware debug\n");
248     dyn_debug_malware = 1;
249   }
250   if ( (p=getenv("DYNINST_DEBUG_SIGNAL"))) {
251     fprintf(stderr, "Enabling DyninstAPI signal debug\n");
252     dyn_debug_signal = 1;
253   }
254   if ( (p=getenv("DYNINST_DEBUG_INFRPC"))) {
255     fprintf(stderr, "Enabling DyninstAPI inferior RPC debug\n");
256     dyn_debug_infrpc = 1;
257   }
258   if ( (p=getenv("DYNINST_DEBUG_INFERIORRPC"))) {
259     fprintf(stderr, "Enabling DyninstAPI inferior RPC debug\n");
260     dyn_debug_infrpc = 1;
261   }
262   if ( (p=getenv("DYNINST_DEBUG_STARTUP"))) {
263     fprintf(stderr, "Enabling DyninstAPI startup debug\n");
264     dyn_debug_startup = 1;
265   }
266   if ( (p=getenv("DYNINST_DEBUG_PARSING"))) {
267           if(p[0] != '0') {
268                 fprintf(stderr, "Enabling DyninstAPI parsing debug\n");
269             dyn_debug_parsing = 1;
270           }
271   }
272   if ( (p=getenv("DYNINST_DEBUG_PARSE"))) {
273           if(p[0] != '0') {
274                 fprintf(stderr, "Enabling DyninstAPI parsing debug\n");
275             dyn_debug_parsing = 1;
276           }
277   }
278   if ( (p=getenv("DYNINST_DEBUG_FORKEXEC"))) {
279     fprintf(stderr, "Enabling DyninstAPI forkexec debug\n");
280     dyn_debug_forkexec = 1;
281   }
282   if ( (p=getenv("DYNINST_DEBUG_PROCCONTROL"))) {
283     fprintf(stderr, "Enabling DyninstAPI process control debug\n");
284     dyn_debug_proccontrol = 1;
285   }
286   if ( (p=getenv("DYNINST_DEBUG_STACKWALK"))) {
287     fprintf(stderr, "Enabling DyninstAPI stack walking debug\n");
288     dyn_debug_stackwalk = 1;
289   }
290   if ( (p=getenv("DYNINST_DEBUG_INST"))) {
291     fprintf(stderr, "Enabling DyninstAPI inst debug\n");
292     dyn_debug_inst = 1;
293   }
294   if ( (p=getenv("DYNINST_DEBUG_RELOC"))) {
295     fprintf(stderr, "Enabling DyninstAPI relocation debug\n");
296     dyn_debug_reloc = 1;
297   }
298   if ( (p=getenv("DYNINST_DEBUG_RELOCATION"))) {
299     fprintf(stderr, "Enabling DyninstAPI relocation debug\n");
300     dyn_debug_reloc = 1;
301   }
302   if ( (p=getenv("DYNINST_DEBUG_DYN_UNW"))) {
303     fprintf(stderr, "Enabling DyninstAPI dynamic unwind debug\n");
304     dyn_debug_dyn_unw = 1;
305     }
306   if ( (p=getenv("DYNINST_DEBUG_DBI"))) {
307     fprintf(stderr, "Enabling DyninstAPI debugger interface debug\n");
308     dyn_debug_dyn_dbi = 1;
309     }
310   if ( (p=getenv("DYNINST_DEBUG_MUTEX"))) {
311     fprintf(stderr, "Enabling DyninstAPI mutex debug\n");
312     dyn_debug_mutex = 1;
313     }
314   if ( (p=getenv("DYNINST_DEBUG_MAILBOX"))) {
315     fprintf(stderr, "Enabling DyninstAPI callbacks debug\n");
316     dyn_debug_mailbox= 1;
317     }
318   if ( (p=getenv("DYNINST_DEBUG_DWARF"))) {
319     fprintf(stderr, "Enabling DyninstAPI dwarf debug\n");
320     dyn_debug_dwarf= 1;
321     }
322   if ( (p=getenv("DYNINST_DEBUG_ASYNC"))) {
323     fprintf(stderr, "Enabling DyninstAPI async debug\n");
324     dyn_debug_async= 1;
325     }
326   if ( (p=getenv("DYNINST_DEBUG_THREAD"))) {
327       fprintf(stderr, "Enabling DyninstAPI thread debug\n");
328       dyn_debug_thread = 1;
329   }
330   if ( (p=getenv("DYNINST_DEBUG_RTLIB"))) {
331       fprintf(stderr, "Enabling DyninstAPI RTlib debug\n");
332       dyn_debug_rtlib = 1;
333   }
334   if ( (p=getenv("DYNINST_DEBUG_CATCHUP"))) {
335       fprintf(stderr, "Enabling DyninstAPI catchup debug\n");
336       dyn_debug_catchup = 1;
337   }
338   if ( (p=getenv("DYNINST_DEBUG_BPATCH"))) {
339       fprintf(stderr, "Enabling DyninstAPI bpatch debug\n");
340       dyn_debug_bpatch = 1;
341   }
342   if ( (p=getenv("DYNINST_DEBUG_REGALLOC"))) {
343       fprintf(stderr, "Enabling DyninstAPI register allocation debug\n");
344       dyn_debug_regalloc = 1;
345   }
346   if ( (p=getenv("DYNINST_DEBUG_AST"))) {
347       fprintf(stderr, "Enabling DyninstAPI ast debug\n");
348       dyn_debug_ast = 1;
349   }
350   if ( (p=getenv("DYNINST_DEBUG_WRITE"))) {
351     fprintf(stderr, "Enabling DyninstAPI process write debugging\n");
352     dyn_debug_write = 1;
353     dyn_debug_write_filename = p;
354   }
355   if ( (p=getenv("DYNINST_DEBUG_LIVENESS"))) {
356     fprintf(stderr, "Enabling DyninstAPI liveness debugging\n");
357     dyn_debug_liveness = 1;
358   }
359   if ( (p=getenv("DYNINST_DEBUG_INFMALLOC")) ||
360        (p=getenv("DYNINST_DEBUG_INFERIORMALLOC"))) {
361     fprintf(stderr, "Enabling DyninstAPI inferior malloc debugging\n");
362     dyn_debug_infmalloc = 1;
363   }
364   if ((p=getenv("DYNINST_DEBUG_CRASH"))) {
365      fprintf(stderr, "Enable DyninstAPI crash debugging\n");
366      dyn_debug_crash = 1;
367      dyn_debug_crash_debugger = p;
368   }
369   if ((p=getenv("DYNINST_DEBUG_RELOCATION"))) {
370     fprintf(stderr, "Enabling DyninstAPI relocation debugging\n");
371     dyn_debug_relocation = 1;
372   }
373
374   debugPrintLock = new eventLock();
375
376   return true;
377 }
378
379 int mal_printf(const char *format, ...)
380 {
381   if (!dyn_debug_malware) return 0;
382   if (NULL == format) return -1;
383
384   debugPrintLock->_Lock(FILE__, __LINE__);
385
386   va_list va;
387   va_start(va, format);
388   int ret = vfprintf(stderr, format, va);
389   va_end(va);
390
391   debugPrintLock->_Unlock(FILE__, __LINE__);
392
393   return ret;
394 }
395
396 int signal_printf_int(const char *format, ...)
397 {
398   if (!dyn_debug_signal) return 0;
399   if (NULL == format) return -1;
400
401   debugPrintLock->_Lock(FILE__, __LINE__);
402
403   fprintf(stderr, "[%s]", getThreadStr(getExecThreadID()));
404   va_list va;
405   va_start(va, format);
406   int ret = vfprintf(stderr, format, va);
407   va_end(va);
408
409   debugPrintLock->_Unlock(FILE__, __LINE__);
410
411   return ret;
412 }
413
414 int inferiorrpc_printf_int(const char *format, ...)
415 {
416   if (!dyn_debug_infrpc) return 0;
417   if (NULL == format) return -1;
418
419   debugPrintLock->_Lock(FILE__, __LINE__);
420
421   fprintf(stderr, "[%s]", getThreadStr(getExecThreadID()));
422   va_list va;
423   va_start(va, format);
424   int ret = vfprintf(stderr, format, va);
425   va_end(va);
426
427   debugPrintLock->_Unlock(FILE__, __LINE__);
428
429   return ret;
430 }
431
432 int startup_printf_int(const char *format, ...)
433 {
434   if (!dyn_debug_startup) return 0;
435   if (NULL == format) return -1;
436
437   debugPrintLock->_Lock(FILE__, __LINE__);
438
439   fprintf(stderr, "[%s]", getThreadStr(getExecThreadID()));
440   va_list va;
441   va_start(va, format);
442   int ret = vfprintf(stderr, format, va);
443   va_end(va);
444
445   debugPrintLock->_Unlock(FILE__, __LINE__);
446
447   return ret;
448 }
449
450 int parsing_printf_int(const char *format, ...)
451 {
452   if (!dyn_debug_parsing) return 0;
453   if (NULL == format) return -1;
454
455   debugPrintLock->_Lock(FILE__, __LINE__);
456
457   //fprintf(stderr, "[%s]", getThreadStr(getExecThreadID()));
458   va_list va;
459   va_start(va, format);
460
461   int ret = vfprintf(stderr, format, va);
462
463   va_end(va);
464
465   debugPrintLock->_Unlock(FILE__, __LINE__);
466
467   return ret;
468 }
469
470 int forkexec_printf_int(const char *format, ...)
471 {
472   if (!dyn_debug_forkexec) return 0;
473   if (NULL == format) return -1;
474
475   debugPrintLock->_Lock(FILE__, __LINE__);
476
477   fprintf(stderr, "[%s]", getThreadStr(getExecThreadID()));
478   va_list va;
479   va_start(va, format);
480   int ret = vfprintf(stderr, format, va);
481   va_end(va);
482
483   debugPrintLock->_Unlock(FILE__, __LINE__);
484
485   return ret;
486 }
487
488 int proccontrol_printf_int(const char *format, ...)
489 {
490   if (!dyn_debug_proccontrol) return 0;
491   if (NULL == format) return -1;
492
493   debugPrintLock->_Lock(FILE__, __LINE__);
494
495   fprintf(stderr, "[%s]", getThreadStr(getExecThreadID()));
496   va_list va;
497   va_start(va, format);
498   int ret = vfprintf(stderr, format, va);
499   va_end(va);
500
501   debugPrintLock->_Unlock(FILE__, __LINE__);
502
503   return ret;
504 }
505
506 int stackwalk_printf_int(const char *format, ...)
507 {
508   if (!dyn_debug_stackwalk) return 0;
509   if (NULL == format) return -1;
510
511   debugPrintLock->_Lock(FILE__, __LINE__);
512
513   fprintf(stderr, "[%s]", getThreadStr(getExecThreadID()));
514   va_list va;
515   va_start(va, format);
516   int ret = vfprintf(stderr, format, va);
517   va_end(va);
518
519   debugPrintLock->_Unlock(FILE__, __LINE__);
520
521   return ret;
522 }
523
524
525
526 int inst_printf_int(const char *format, ...)
527 {
528   if (!dyn_debug_inst) return 0;
529   if (NULL == format) return -1;
530
531   debugPrintLock->_Lock(FILE__, __LINE__);
532
533   fprintf(stderr, "[%s]", getThreadStr(getExecThreadID()));
534   va_list va;
535   va_start(va, format);
536   int ret = vfprintf(stderr, format, va);
537   va_end(va);
538
539   debugPrintLock->_Unlock(FILE__, __LINE__);
540
541   return ret;
542 }
543
544 int reloc_printf_int(const char *format, ...)
545 {
546   if (!dyn_debug_reloc) return 0;
547   if (NULL == format) return -1;
548
549   debugPrintLock->_Lock(FILE__, __LINE__);
550   
551   fprintf(stderr, "[%s]", getThreadStr(getExecThreadID()));
552   va_list va;
553   va_start(va, format);
554   int ret = vfprintf(stderr, format, va);
555   va_end(va);
556
557   debugPrintLock->_Unlock(FILE__, __LINE__);
558
559   return ret;
560 }
561
562 int dyn_unw_printf_int(const char *format, ...)
563 {
564   if (!dyn_debug_dyn_unw ) return 0;
565   if (NULL == format) return -1;
566
567   debugPrintLock->_Lock(FILE__, __LINE__);
568   
569   fprintf(stderr, "[%s]", getThreadStr(getExecThreadID()));
570   va_list va;
571   va_start(va, format);
572   int ret = vfprintf(stderr, format, va);
573   va_end(va);
574
575   debugPrintLock->_Unlock(FILE__, __LINE__);
576
577   return ret;
578 }
579
580 int dbi_printf_int(const char *format, ...)
581 {
582   if (!dyn_debug_dyn_dbi ) return 0;
583   if (NULL == format) return -1;
584
585   debugPrintLock->_Lock(FILE__, __LINE__);
586   
587   fprintf(stderr, "[%s]", getThreadStr(getExecThreadID()));
588   va_list va;
589   va_start(va, format);
590   int ret = vfprintf(stderr, format, va);
591   va_end(va);
592
593   debugPrintLock->_Unlock(FILE__, __LINE__);
594
595   return ret;
596 }
597
598 int mutex_printf_int(const char *format, ...)
599 {
600   if (!dyn_debug_mutex ) return 0;
601   if (NULL == format) return -1;
602
603   debugPrintLock->_Lock(FILE__, __LINE__);
604   
605   fprintf(stderr, "[%s]", getThreadStr(getExecThreadID()));
606   va_list va;
607   va_start(va, format);
608   int ret = vfprintf(stderr, format, va);
609   va_end(va);
610
611   debugPrintLock->_Unlock(FILE__, __LINE__);
612
613   return ret;
614 }
615
616 int mailbox_printf_int(const char *format, ...)
617 {
618   if (!dyn_debug_mailbox ) return 0;
619   if (NULL == format) return -1;
620
621   debugPrintLock->_Lock(FILE__, __LINE__);
622   
623   fprintf(stderr, "[%s]", getThreadStr(getExecThreadID()));
624   va_list va;
625   va_start(va, format);
626   int ret = vfprintf(stderr, format, va);
627   va_end(va);
628
629   debugPrintLock->_Unlock(FILE__, __LINE__);
630
631   return ret;
632 }
633
634 int async_printf_int(const char *format, ...)
635 {
636   if (!dyn_debug_async ) return 0;
637   if (NULL == format) return -1;
638
639   debugPrintLock->_Lock(FILE__, __LINE__);
640   
641   fprintf(stderr, "[%s]", getThreadStr(getExecThreadID()));
642   va_list va;
643   va_start(va, format);
644   int ret = vfprintf(stderr, format, va);
645   va_end(va);
646
647   debugPrintLock->_Unlock(FILE__, __LINE__);
648
649   return ret;
650 }
651
652 int dwarf_printf_int(const char *format, ...)
653 {
654   if (!dyn_debug_dwarf ) return 0;
655   if (NULL == format) return -1;
656
657   debugPrintLock->_Lock(FILE__, __LINE__);
658   
659   fprintf(stderr, "(dwarf) [thread %s]: ", getThreadStr(getExecThreadID()));
660   va_list va;
661   va_start(va, format);
662   int ret = vfprintf(stderr, format, va);
663   va_end(va);
664
665   debugPrintLock->_Unlock(FILE__, __LINE__);
666
667   return ret;
668 }
669
670
671 int thread_printf_int(const char *format, ...)
672 {
673   if (!dyn_debug_thread) return 0;
674   if (NULL == format) return -1;
675
676   debugPrintLock->_Lock(FILE__, __LINE__);
677   
678   fprintf(stderr, "[%s]: ", getThreadStr(getExecThreadID()));
679   va_list va;
680   va_start(va, format);
681   int ret = vfprintf(stderr, format, va);
682   va_end(va);
683
684   debugPrintLock->_Unlock(FILE__, __LINE__);
685
686   return ret;
687 }
688
689
690 int catchup_printf_int(const char *format, ...)
691 {
692
693     if (!dyn_debug_catchup) return 0;
694     if (NULL == format) return -1;
695     
696     debugPrintLock->_Lock(FILE__, __LINE__);
697     
698     fprintf(stderr, "[%s]: ", getThreadStr(getExecThreadID()));
699     va_list va;
700     va_start(va, format);
701     int ret = vfprintf(stderr, format, va);
702     va_end(va);
703     
704     debugPrintLock->_Unlock(FILE__, __LINE__);
705     
706     return ret;
707 }
708
709 int bpatch_printf(const char *format, ...)
710 {
711   if (!dyn_debug_bpatch) return 0;
712   if (NULL == format) return -1;
713
714   debugPrintLock->_Lock(FILE__, __LINE__);
715   
716   fprintf(stderr, "[%s]: ", getThreadStr(getExecThreadID()));
717   va_list va;
718   va_start(va, format);
719   int ret = vfprintf(stderr, format, va);
720   va_end(va);
721
722   debugPrintLock->_Unlock(FILE__, __LINE__);
723
724   return ret;
725 }
726
727 int regalloc_printf_int(const char *format, ...)
728 {
729   if (!dyn_debug_regalloc) return 0;
730   if (NULL == format) return -1;
731
732   debugPrintLock->_Lock(FILE__, __LINE__);
733   
734   fprintf(stderr, "[%s]: ", getThreadStr(getExecThreadID()));
735   va_list va;
736   va_start(va, format);
737   int ret = vfprintf(stderr, format, va);
738   va_end(va);
739
740   debugPrintLock->_Unlock(FILE__, __LINE__);
741
742   return ret;
743 }
744
745 int ast_printf_int(const char *format, ...)
746 {
747   if (!dyn_debug_ast) return 0;
748   if (NULL == format) return -1;
749
750   debugPrintLock->_Lock(FILE__, __LINE__);
751   
752   fprintf(stderr, "[%s]: ", getThreadStr(getExecThreadID()));
753   va_list va;
754   va_start(va, format);
755   int ret = vfprintf(stderr, format, va);
756   va_end(va);
757
758   debugPrintLock->_Unlock(FILE__, __LINE__);
759
760   return ret;
761 }
762
763 int write_printf_int(const char *format, ...)
764 {
765   if (!dyn_debug_write) return 0;
766   if (NULL == format) return -1;
767
768   debugPrintLock->_Lock(FILE__, __LINE__);
769   
770   if (!dyn_debug_write_file) {
771     if (dyn_debug_write_filename && strlen(dyn_debug_write_filename)) {
772       dyn_debug_write_file = fopen(dyn_debug_write_filename, "w");
773     }
774     if (!dyn_debug_write_file) {
775       dyn_debug_write_file = stderr;
776     }
777   }
778
779   va_list va;
780   va_start(va, format);
781   int ret = vfprintf(dyn_debug_write_file, format, va);
782   va_end(va);
783   fflush(dyn_debug_write_file);
784   
785   debugPrintLock->_Unlock(FILE__, __LINE__);
786
787   return ret;
788 }
789
790 int liveness_printf_int(const char *format, ...)
791 {
792   if (!dyn_debug_liveness) return 0;
793   if (NULL == format) return -1;
794
795   debugPrintLock->_Lock(FILE__, __LINE__);
796   
797   fprintf(stderr, "[%s]: ", getThreadStr(getExecThreadID()));
798   va_list va;
799   va_start(va, format);
800   int ret = vfprintf(stderr, format, va);
801   va_end(va);
802
803   debugPrintLock->_Unlock(FILE__, __LINE__);
804
805   return ret;
806 }
807
808 int infmalloc_printf_int(const char *format, ...)
809 {
810   if (!dyn_debug_infmalloc) return 0;
811   if (NULL == format) return -1;
812
813   debugPrintLock->_Lock(FILE__, __LINE__);
814   
815   fprintf(stderr, "[%s]: ", getThreadStr(getExecThreadID()));
816   va_list va;
817   va_start(va, format);
818   int ret = vfprintf(stderr, format, va);
819   va_end(va);
820
821   debugPrintLock->_Unlock(FILE__, __LINE__);
822
823   return ret;
824 }
825
826
827 StatContainer stats_instru;
828 StatContainer stats_ptrace;
829 StatContainer stats_parse;
830 StatContainer stats_codegen;
831
832 TimeStatistic running_time;
833
834 bool have_stats = 0;
835
836 bool init_stats() {
837     char *p;
838     running_time.start();
839
840     if ((p = getenv("DYNINST_STATS_INST"))) {
841         fprintf(stderr, "Enabling DyninstAPI instrumentation statistics\n");
842         stats_instru.add(INST_GENERATE_TIMER, TimerStat);
843         stats_instru.add(INST_INSTALL_TIMER, TimerStat);
844         stats_instru.add(INST_LINK_TIMER, TimerStat);
845         stats_instru.add(INST_REMOVE_TIMER, TimerStat);
846         stats_instru.add(INST_GENERATE_COUNTER, CountStat);
847         stats_instru.add(INST_INSTALL_COUNTER, CountStat);
848         stats_instru.add(INST_LINK_COUNTER, CountStat);
849         stats_instru.add(INST_REMOVE_COUNTER, CountStat);
850         have_stats = true;
851     }
852     
853
854     if ((p = getenv("DYNINST_STATS_PTRACE"))) {
855         fprintf(stderr, "Enabling DyninstAPI ptrace statistics\n");
856         stats_ptrace.add(PTRACE_WRITE_TIMER, TimerStat);
857         stats_ptrace.add(PTRACE_READ_TIMER, TimerStat);
858
859         stats_ptrace.add(PTRACE_WRITE_COUNTER, CountStat);
860         stats_ptrace.add(PTRACE_READ_COUNTER, CountStat);
861
862         stats_ptrace.add(PTRACE_WRITE_AMOUNT, CountStat);
863         stats_ptrace.add(PTRACE_READ_AMOUNT, CountStat);
864         have_stats = true;
865     }
866     
867     if ((p = getenv("DYNINST_STATS_PARSING"))) {
868         fprintf(stderr, "Enabling DyninstAPI parsing statistics\n");
869         stats_parse.add(PARSE_SYMTAB_TIMER, TimerStat);
870         stats_parse.add(PARSE_ANALYZE_TIMER, TimerStat);
871         have_stats = true;
872     }
873
874     if ((p = getenv("DYNINST_STATS_CODEGEN"))) {
875         fprintf(stderr, "Enabling DyninstAPI code generation statistics\n");
876
877         stats_codegen.add(CODEGEN_AST_TIMER, TimerStat);
878         stats_codegen.add(CODEGEN_AST_COUNTER, CountStat);
879         stats_codegen.add(CODEGEN_REGISTER_TIMER, TimerStat);
880         stats_codegen.add(CODEGEN_LIVENESS_TIMER, TimerStat);
881         have_stats = true;
882     }
883     return have_stats;
884 }
885
886 bool print_stats() {
887     char *p;
888
889     running_time.stop();
890     if (have_stats) 
891         fprintf(stderr, "Running time: %f sec (user), %f sec (system), %f sec (wall)\n",
892                 running_time.usecs(),
893                 running_time.ssecs(),
894                 running_time.wsecs());
895     running_time.start();
896
897     if ((p = getenv("DYNINST_STATS_INST"))) {
898         fprintf(stderr, "Printing DyninstAPI instrumentation statistics\n");
899         fprintf(stderr, "  Generation: %ld calls, %f sec (user), %f sec (system), %f sec (wall)\n",
900                 stats_instru[INST_GENERATE_COUNTER]->value(),
901                 stats_instru[INST_GENERATE_TIMER]->usecs(),
902                 stats_instru[INST_GENERATE_TIMER]->ssecs(),
903                 stats_instru[INST_GENERATE_TIMER]->wsecs());
904         fprintf(stderr, "  Installation: %ld calls, %f sec (user), %f sec (system), %f sec (wall)\n",
905                 stats_instru[INST_INSTALL_COUNTER]->value(),
906                 stats_instru[INST_INSTALL_TIMER]->usecs(),
907                 stats_instru[INST_INSTALL_TIMER]->ssecs(),
908                 stats_instru[INST_INSTALL_TIMER]->wsecs());
909         fprintf(stderr, "  Linking: %ld calls, %f sec (user), %f sec (system), %f sec (wall)\n",
910                 stats_instru[INST_LINK_COUNTER]->value(),
911                 stats_instru[INST_LINK_TIMER]->usecs(),
912                 stats_instru[INST_LINK_TIMER]->ssecs(),
913                 stats_instru[INST_LINK_TIMER]->wsecs());
914         fprintf(stderr, "  Removal: %ld calls, %f sec (user), %f sec (system), %f sec (wall)\n",
915                 stats_instru[INST_REMOVE_COUNTER]->value(),
916                 stats_instru[INST_REMOVE_TIMER]->usecs(),
917                 stats_instru[INST_REMOVE_TIMER]->ssecs(),
918                 stats_instru[INST_REMOVE_TIMER]->wsecs());
919     }
920
921     if ((p = getenv("DYNINST_STATS_PTRACE"))) {
922         fprintf(stderr, "Printing DyninstAPI ptrace statistics\n");
923         fprintf(stderr, "  Write: %ld calls, %ld bytes, %f sec (user), %f sec (system), %f sec (wall)\n",
924                 stats_ptrace[PTRACE_WRITE_COUNTER]->value(),
925                 stats_ptrace[PTRACE_WRITE_AMOUNT]->value(),
926                 stats_ptrace[PTRACE_WRITE_TIMER]->usecs(),
927                 stats_ptrace[PTRACE_WRITE_TIMER]->ssecs(),
928                 stats_ptrace[PTRACE_WRITE_TIMER]->wsecs());
929
930         fprintf(stderr, "  Read: %ld calls, %ld bytes, %f sec (user), %f sec (system), %f sec (wall)\n",
931                 stats_ptrace[PTRACE_READ_COUNTER]->value(),
932                 stats_ptrace[PTRACE_READ_AMOUNT]->value(),
933                 stats_ptrace[PTRACE_READ_TIMER]->usecs(),
934                 stats_ptrace[PTRACE_READ_TIMER]->ssecs(),
935                 stats_ptrace[PTRACE_READ_TIMER]->wsecs());
936     }
937
938     if ((p = getenv("DYNINST_STATS_PARSING"))) {
939         fprintf(stderr, "Printing DyninstAPI parsing statistics\n");
940         fprintf(stderr, "  Symtab parsing:  %f sec (user), %f sec (system), %f sec (wall)\n",
941                 stats_parse[PARSE_SYMTAB_TIMER]->usecs(),
942                 stats_parse[PARSE_SYMTAB_TIMER]->ssecs(),
943                 stats_parse[PARSE_SYMTAB_TIMER]->wsecs());
944         fprintf(stderr, "  Analysis:  %f sec (user), %f sec (system), %f sec (wall)\n",
945                 stats_parse[PARSE_ANALYZE_TIMER]->usecs(),
946                 stats_parse[PARSE_ANALYZE_TIMER]->ssecs(),
947                 stats_parse[PARSE_ANALYZE_TIMER]->wsecs());
948     }
949
950     if ((p = getenv("DYNINST_STATS_CODEGEN"))) {
951         fprintf(stderr, "Printing DyninstAPI code generation statistics\n");
952         fprintf(stderr, "  AST generation: %ld calls, %f sec (user), %f sec (system), %f sec (wall)\n",
953                 stats_codegen[CODEGEN_AST_COUNTER]->value(),
954                 stats_codegen[CODEGEN_AST_TIMER]->usecs(),
955                 stats_codegen[CODEGEN_AST_TIMER]->ssecs(),
956                 stats_codegen[CODEGEN_AST_TIMER]->wsecs());
957
958         fprintf(stderr, "  Register allocation: %f sec (user), %f sec (system), %f sec (wall)\n",
959                 stats_codegen[CODEGEN_REGISTER_TIMER]->usecs(),
960                 stats_codegen[CODEGEN_REGISTER_TIMER]->ssecs(),
961                 stats_codegen[CODEGEN_REGISTER_TIMER]->wsecs());
962         
963         fprintf(stderr, "  Liveness analysis: %f sec (user), %f sec (system), %f sec (wall)\n",
964                 stats_codegen[CODEGEN_LIVENESS_TIMER]->usecs(),
965                 stats_codegen[CODEGEN_LIVENESS_TIMER]->ssecs(),
966                 stats_codegen[CODEGEN_LIVENESS_TIMER]->wsecs());
967     }
968     return true;
969 }
970