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