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