output.c revision 8cc1b9d456c8f41e3a8cc0d3ec0d77eb779cb7bb
1#if HAVE_CONFIG_H 2#include "config.h" 3#endif 4 5#include <stdio.h> 6#include <stdarg.h> 7#include <string.h> 8#include <time.h> 9#include <sys/time.h> 10#include <unistd.h> 11 12#include "ltrace.h" 13#include "options.h" 14#include "output.h" 15 16#if HAVE_LIBIBERTY 17#include "demangle.h" 18#endif 19 20static pid_t current_pid = 0; 21static int current_depth = 0; 22static int current_column = 0; 23 24static void 25output_indent(struct process * proc) { 26 current_column += fprintf(output, "%*s", opt_n * proc->callstack_depth, ""); 27} 28 29static void 30begin_of_line(enum tof type, struct process * proc) { 31 current_column = 0; 32 if (!proc) { 33 return; 34 } 35 if ((output!=stderr) && (opt_p || opt_f)) { 36 current_column += fprintf(output, "%u ", proc->pid); 37 } else if (list_of_processes->next) { 38 current_column += fprintf(output, "[pid %u] ", proc->pid); 39 } 40 if (opt_r) { 41 struct timeval tv; 42 struct timezone tz; 43 static struct timeval old_tv={0,0}; 44 struct timeval diff; 45 46 gettimeofday(&tv, &tz); 47 48 if (old_tv.tv_sec==0 && old_tv.tv_usec==0) { 49 old_tv.tv_sec=tv.tv_sec; 50 old_tv.tv_usec=tv.tv_usec; 51 } 52 diff.tv_sec = tv.tv_sec - old_tv.tv_sec; 53 if (tv.tv_usec >= old_tv.tv_usec) { 54 diff.tv_usec = tv.tv_usec - old_tv.tv_usec; 55 } else { 56 diff.tv_sec++; 57 diff.tv_usec = 1000000 + tv.tv_usec - old_tv.tv_usec; 58 } 59 old_tv.tv_sec = tv.tv_sec; 60 old_tv.tv_usec = tv.tv_usec; 61 current_column += fprintf(output, "%3lu.%06d ", 62 diff.tv_sec, (int)diff.tv_usec); 63 } 64 if (opt_t) { 65 struct timeval tv; 66 struct timezone tz; 67 68 gettimeofday(&tv, &tz); 69 if (opt_t>2) { 70 current_column += fprintf(output, "%lu.%06d ", 71 tv.tv_sec, (int)tv.tv_usec); 72 } else if (opt_t>1) { 73 struct tm * tmp = localtime(&tv.tv_sec); 74 current_column += fprintf(output, "%02d:%02d:%02d.%06d ", 75 tmp->tm_hour, tmp->tm_min, tmp->tm_sec, (int)tv.tv_usec); 76 } else { 77 struct tm * tmp = localtime(&tv.tv_sec); 78 current_column += fprintf(output, "%02d:%02d:%02d ", 79 tmp->tm_hour, tmp->tm_min, tmp->tm_sec); 80 } 81 } 82 if (opt_i) { 83 if (type==LT_TOF_FUNCTION) { 84 current_column += fprintf(output, "[%08x] ", 85 (unsigned)proc->return_addr); 86 } else { 87 current_column += fprintf(output, "[%08x] ", 88 (unsigned)proc->instruction_pointer); 89 } 90 } 91 if (opt_n > 0 && type!=LT_TOF_NONE) { 92 output_indent(proc); 93 } 94} 95 96static struct function * 97name2func(char * name) { 98 struct function * tmp; 99 const char * str1, * str2; 100 101 tmp = list_of_functions; 102 while(tmp) { 103#if HAVE_LIBIBERTY 104 str1 = opt_C ? my_demangle(tmp->name) : tmp->name; 105 str2 = opt_C ? my_demangle(name) : name; 106#else 107 str1 = tmp->name; 108 str2 = name; 109#endif 110 if (!strcmp(str1, str2)) { 111 112 return tmp; 113 } 114 tmp = tmp->next; 115 } 116 return NULL; 117} 118 119void 120output_line(struct process * proc, char *fmt, ...) { 121 va_list args; 122 123 if (current_pid) { 124 fprintf(output, " <unfinished ...>\n"); 125 } 126 current_pid=0; 127 if (!fmt) { 128 return; 129 } 130 begin_of_line(LT_TOF_NONE, proc); 131 132 va_start(args, fmt); 133 vfprintf(output, fmt, args); 134 fprintf(output, "\n"); 135 va_end(args); 136 current_column=0; 137} 138 139static void 140tabto(int col) { 141 if (current_column < col) { 142 fprintf(output, "%*s", col-current_column, ""); 143 } 144} 145 146void 147output_left(enum tof type, struct process * proc, char * function_name) { 148 struct function * func; 149 150 if (current_pid) { 151 fprintf(output, " <unfinished ...>\n"); 152 current_pid=0; 153 current_column=0; 154 } 155 current_pid = proc->pid; 156 current_depth = proc->callstack_depth; 157 proc->type_being_displayed = type; 158 begin_of_line(type, proc); 159#if HAVE_LIBIBERTY 160 current_column += fprintf(output, "%s(", opt_C ? my_demangle(function_name): function_name); 161#else 162 current_column += fprintf(output, "%s(", function_name); 163#endif 164 165 func = name2func(function_name); 166 if (!func) { 167 int i; 168 for(i=0; i<4; i++) { 169 current_column += display_arg(type, proc, i, ARGTYPE_UNKNOWN); 170 current_column += fprintf(output, ", "); 171 } 172 current_column += display_arg(type, proc, 4, ARGTYPE_UNKNOWN); 173 return; 174 } else { 175 int i; 176 for(i=0; i< func->num_params - func->params_right - 1; i++) { 177 current_column += display_arg(type, proc, i, func->arg_types[i]); 178 current_column += fprintf(output, ", "); 179 } 180 if (func->num_params>func->params_right) { 181 current_column += display_arg(type, proc, i, func->arg_types[i]); 182 if (func->params_right) { 183 current_column += fprintf(output, ", "); 184 } 185 } 186 } 187} 188 189void 190output_right(enum tof type, struct process * proc, char * function_name) { 191 struct function * func = name2func(function_name); 192 193 if ((current_pid && current_pid!=proc->pid) || 194 current_depth != proc->callstack_depth) { 195 fprintf(output, " <unfinished ...>\n"); 196 current_pid = 0; 197 } 198 if (current_pid != proc->pid) { 199 begin_of_line(type, proc); 200#if HAVE_LIBIBERTY 201 current_column += fprintf(output, "<... %s resumed> ", opt_C ? my_demangle(function_name) : function_name); 202#else 203 current_column += fprintf(output, "<... %s resumed> ", function_name); 204#endif 205 } 206 207 if (!func) { 208 current_column += fprintf(output, ") "); 209 tabto(opt_a); 210 fprintf(output, "= "); 211 display_arg(type, proc, -1, ARGTYPE_UNKNOWN); 212 fprintf(output, "\n"); 213 } else { 214 int i; 215 for(i=func->num_params-func->params_right; i<func->num_params-1; i++) { 216 current_column += display_arg(type, proc, i, func->arg_types[i]); 217 current_column += fprintf(output, ", "); 218 } 219 if (func->params_right) { 220 current_column += display_arg(type, proc, i, func->arg_types[i]); 221 } 222 current_column += fprintf(output, ") "); 223 tabto(opt_a); 224 fprintf(output, "= "); 225 if (func->return_type == ARGTYPE_VOID) { 226 fprintf(output, "<void>"); 227 } else { 228 display_arg(type, proc, -1, func->return_type); 229 } 230 fprintf(output, "\n"); 231 } 232 current_pid=0; 233 current_column=0; 234} 235