13 /* TODO FIXME XXX: include in common.h: */
14 extern struct timeval current_time_spent;
16 Dict *dict_opt_c = NULL;
18 static Process *current_proc = 0;
19 static int current_depth = 0;
20 static int current_column = 0;
23 output_indent(Process *proc) {
25 fprintf(options.output, "%*s", options.indent * proc->callstack_depth, "");
29 begin_of_line(enum tof type, Process *proc) {
34 if ((options.output != stderr) && (opt_p || options.follow)) {
35 current_column += fprintf(options.output, "%u ", proc->pid);
36 } else if (options.follow) {
37 current_column += fprintf(options.output, "[pid %u] ", proc->pid);
42 static struct timeval old_tv = { 0, 0 };
45 gettimeofday(&tv, &tz);
47 if (old_tv.tv_sec == 0 && old_tv.tv_usec == 0) {
48 old_tv.tv_sec = tv.tv_sec;
49 old_tv.tv_usec = tv.tv_usec;
51 diff.tv_sec = tv.tv_sec - old_tv.tv_sec;
52 if (tv.tv_usec >= old_tv.tv_usec) {
53 diff.tv_usec = tv.tv_usec - old_tv.tv_usec;
56 diff.tv_usec = 1000000 + tv.tv_usec - old_tv.tv_usec;
58 old_tv.tv_sec = tv.tv_sec;
59 old_tv.tv_usec = tv.tv_usec;
60 current_column += fprintf(options.output, "%3lu.%06d ",
61 diff.tv_sec, (int)diff.tv_usec);
67 gettimeofday(&tv, &tz);
69 current_column += fprintf(options.output, "%lu.%06d ",
70 tv.tv_sec, (int)tv.tv_usec);
71 } else if (opt_t > 1) {
72 struct tm *tmp = localtime(&tv.tv_sec);
74 fprintf(options.output, "%02d:%02d:%02d.%06d ",
75 tmp->tm_hour, tmp->tm_min, tmp->tm_sec,
78 struct tm *tmp = localtime(&tv.tv_sec);
79 current_column += fprintf(options.output, "%02d:%02d:%02d ",
80 tmp->tm_hour, tmp->tm_min,
85 if (type == LT_TOF_FUNCTION || type == LT_TOF_FUNCTIONR) {
86 current_column += fprintf(options.output, "[%p] ",
89 current_column += fprintf(options.output, "[%p] ",
90 proc->instruction_pointer);
93 if (options.indent > 0 && type != LT_TOF_NONE) {
99 name2func(char *name) {
101 const char *str1, *str2;
103 tmp = list_of_functions;
106 str1 = options.demangle ? my_demangle(tmp->name) : tmp->name;
107 str2 = options.demangle ? my_demangle(name) : name;
112 if (!strcmp(str1, str2)) {
122 output_line(Process *proc, char *fmt, ...) {
125 if (options.summary) {
129 if (current_proc->callstack[current_depth].return_addr) {
130 fprintf(options.output, " <unfinished ...>\n");
132 fprintf(options.output, " <no return ...>\n");
139 begin_of_line(LT_TOF_NONE, proc);
142 vfprintf(options.output, fmt, args);
143 fprintf(options.output, "\n");
150 if (current_column < col) {
151 fprintf(options.output, "%*s", col - current_column, "");
156 output_left(enum tof type, Process *proc, char *function_name) {
158 static arg_type_info *arg_unknown = NULL;
159 if (arg_unknown == NULL)
160 arg_unknown = lookup_prototype(ARGTYPE_UNKNOWN);
162 if (options.summary) {
166 fprintf(options.output, " <unfinished ...>\n");
171 current_depth = proc->callstack_depth;
172 proc->type_being_displayed = type;
173 begin_of_line(type, proc);
176 fprintf(options.output, "%s(",
177 options.demangle ? my_demangle(function_name) : function_name);
179 current_column += fprintf(options.output, "%s(", function_name);
182 func = name2func(function_name);
185 for (i = 0; i < 4; i++) {
187 display_arg(type, proc, i, arg_unknown);
188 current_column += fprintf(options.output, ", ");
190 current_column += display_arg(type, proc, 4, arg_unknown);
194 for (i = 0; i < func->num_params - func->params_right - 1; i++) {
196 display_arg(type, proc, i, func->arg_info[i]);
197 current_column += fprintf(options.output, ", ");
199 if (func->num_params > func->params_right) {
201 display_arg(type, proc, i, func->arg_info[i]);
202 if (func->params_right) {
203 current_column += fprintf(options.output, ", ");
206 if (func->params_right) {
207 save_register_args(type, proc);
213 output_right(enum tof type, Process *proc, char *function_name) {
214 Function *func = name2func(function_name);
215 static arg_type_info *arg_unknown = NULL;
216 if (arg_unknown == NULL)
217 arg_unknown = lookup_prototype(ARGTYPE_UNKNOWN);
219 if (options.summary) {
220 struct opt_c_struct *st;
223 dict_init(dict_key2hash_string,
224 dict_key_cmp_string);
226 st = dict_find_entry(dict_opt_c, function_name);
229 st = malloc(sizeof(struct opt_c_struct));
230 na = strdup(function_name);
236 st->tv.tv_sec = st->tv.tv_usec = 0;
237 dict_enter(dict_opt_c, na, st);
239 if (st->tv.tv_usec + current_time_spent.tv_usec > 1000000) {
240 st->tv.tv_usec += current_time_spent.tv_usec - 1000000;
243 st->tv.tv_usec += current_time_spent.tv_usec;
246 st->tv.tv_sec += current_time_spent.tv_sec;
248 // fprintf(options.output, "%s <%lu.%06d>\n", function_name,
249 // current_time_spent.tv_sec, (int)current_time_spent.tv_usec);
252 if (current_proc && (current_proc != proc ||
253 current_depth != proc->callstack_depth)) {
254 fprintf(options.output, " <unfinished ...>\n");
257 if (current_proc != proc) {
258 begin_of_line(type, proc);
261 fprintf(options.output, "<... %s resumed> ",
262 options.demangle ? my_demangle(function_name) : function_name);
265 fprintf(options.output, "<... %s resumed> ", function_name);
270 current_column += fprintf(options.output, ") ");
271 tabto(options.align - 1);
272 fprintf(options.output, "= ");
273 display_arg(type, proc, -1, arg_unknown);
276 for (i = func->num_params - func->params_right;
277 i < func->num_params - 1; i++) {
279 display_arg(type, proc, i, func->arg_info[i]);
280 current_column += fprintf(options.output, ", ");
282 if (func->params_right) {
284 display_arg(type, proc, i, func->arg_info[i]);
286 current_column += fprintf(options.output, ") ");
287 tabto(options.align - 1);
288 fprintf(options.output, "= ");
289 if (func->return_info->type == ARGTYPE_VOID) {
290 fprintf(options.output, "<void>");
292 display_arg(type, proc, -1, func->return_info);
296 fprintf(options.output, " <%lu.%06d>",
297 current_time_spent.tv_sec,
298 (int)current_time_spent.tv_usec);
300 fprintf(options.output, "\n");