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