blob: 856f43c80e086a95433ce40ff77029a70b5611df [file] [log] [blame]
Juan Cespedesac3db291998-04-25 14:31:58 +02001#if HAVE_CONFIG_H
2#include "config.h"
3#endif
4
Juan Cespedes3268a161997-08-25 16:45:22 +02005#include <stdio.h>
Juan Cespedes5e4455b1997-08-24 01:48:26 +02006#include <stdarg.h>
Juan Cespedes5e0acdb1998-04-04 08:34:07 +02007#include <time.h>
8#include <sys/time.h>
9#include <unistd.h>
Juan Cespedes5e4455b1997-08-24 01:48:26 +020010
11#include "ltrace.h"
Juan Cespedes5e01f651998-03-08 22:31:44 +010012#include "options.h"
13#include "output.h"
Juan Cespedes5e4455b1997-08-24 01:48:26 +020014
Juan Cespedesac3db291998-04-25 14:31:58 +020015#if HAVE_LIBIBERTY
16#include "demangle.h"
17#endif
18
Juan Cespedes5e01f651998-03-08 22:31:44 +010019static pid_t current_pid = 0;
20static int current_column = 0;
Juan Cespedes5e4455b1997-08-24 01:48:26 +020021
Juan Cespedes5e01f651998-03-08 22:31:44 +010022static void begin_of_line(enum tof type, struct process * proc)
Juan Cespedes5e4455b1997-08-24 01:48:26 +020023{
Juan Cespedes5e01f651998-03-08 22:31:44 +010024 current_column = 0;
25 if (!proc) {
26 return;
Juan Cespedes5e4455b1997-08-24 01:48:26 +020027 }
Juan Cespedes273ea6d1998-03-14 23:02:40 +010028 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);
Juan Cespedes5e01f651998-03-08 22:31:44 +010032 }
Juan Cespedes5e0acdb1998-04-04 08:34:07 +020033 if (opt_t) {
34 struct timeval tv;
35 struct timezone tz;
36 struct tm * tmp;
37
38 gettimeofday(&tv, &tz);
39 tmp = localtime(&tv.tv_sec);
40 if (opt_t>2) {
41 current_column += fprintf(output, "%lu.%06d ",
42 tv.tv_sec, (int)tv.tv_usec);
43 } else if (opt_t>1) {
44 current_column += fprintf(output, "%02d:%02d:%02d.%06d ",
45 tmp->tm_hour, tmp->tm_min, tmp->tm_sec, (int)tv.tv_usec);
46 } else {
47 current_column += fprintf(output, "%02d:%02d:%02d ",
48 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
49 }
50 }
Juan Cespedes5e01f651998-03-08 22:31:44 +010051 if (opt_i) {
52 if (type==LT_TOF_FUNCTION) {
53 current_column += fprintf(output, "[%08x] ",
54 (unsigned)proc->return_addr);
55 } else {
56 current_column += fprintf(output, "[%08x] ",
57 (unsigned)proc->instruction_pointer);
58 }
59 }
Juan Cespedes5e4455b1997-08-24 01:48:26 +020060}
61
Juan Cespedes5e01f651998-03-08 22:31:44 +010062static struct function * name2func(char * name)
63{
64 struct function * tmp;
65
66 tmp = list_of_functions;
67 while(tmp) {
68 if (!strcmp(tmp->name, name)) {
69 return tmp;
70 }
71 tmp = tmp->next;
72 }
73 return NULL;
74}
75
76void output_line(struct process * proc, char *fmt, ...)
Juan Cespedes5e4455b1997-08-24 01:48:26 +020077{
78 va_list args;
79
Juan Cespedes5e01f651998-03-08 22:31:44 +010080 if (current_pid) {
81 fprintf(output, " <unfinished ...>\n");
82 }
Juan Cespedes28f60191998-04-12 00:04:39 +020083 current_pid=0;
84 if (!fmt) {
85 return;
86 }
Juan Cespedes5e01f651998-03-08 22:31:44 +010087 begin_of_line(LT_TOF_NONE, proc);
88
89 va_start(args, fmt);
90 vfprintf(output, fmt, args);
91 fprintf(output, "\n");
92 va_end(args);
Juan Cespedes5e01f651998-03-08 22:31:44 +010093 current_column=0;
94}
95
96static void tabto(int col)
97{
98 if (current_column < col) {
99 fprintf(output, "%*s", col-current_column, "");
100 }
101}
102
103void output_left(enum tof type, struct process * proc, char * function_name)
104{
105 struct function * func;
106
107 if (current_pid) {
Juan Cespedes81690ef1998-03-13 19:31:29 +0100108#if 0 /* FIXME: should I do this? */
Juan Cespedes5e01f651998-03-08 22:31:44 +0100109 if (current_pid == proc->pid
110 && proc->type_being_displayed == LT_TOF_FUNCTION
111 && proc->type_being_displayed == type) {
112 tabto(opt_a);
113 fprintf(output, "= ???\n");
114 } else
115#endif
116 fprintf(output, " <unfinished ...>\n");
117 current_pid=0;
118 current_column=0;
119 }
120 current_pid=proc->pid;
121 proc->type_being_displayed = type;
122 begin_of_line(type, proc);
Juan Cespedesac3db291998-04-25 14:31:58 +0200123#if HAVE_LIBIBERTY
124 current_column += fprintf(output, "%s(", my_demangle(function_name));
125#else
Juan Cespedes5e01f651998-03-08 22:31:44 +0100126 current_column += fprintf(output, "%s(", function_name);
Juan Cespedesac3db291998-04-25 14:31:58 +0200127#endif
Juan Cespedes5e01f651998-03-08 22:31:44 +0100128
129 func = name2func(function_name);
130 if (!func) {
131 int i;
132 for(i=0; i<4; i++) {
133 current_column += display_arg(type, proc, i, LT_PT_UNKNOWN);
134 current_column += fprintf(output, ", ");
135 }
136 current_column += display_arg(type, proc, 4, LT_PT_UNKNOWN);
137 return;
138 } else {
139 int i;
140 for(i=0; i< func->num_params - func->params_right - 1; i++) {
141 current_column += display_arg(type, proc, i, func->param_types[i]);
142 current_column += fprintf(output, ", ");
143 }
144 if (func->num_params>func->params_right) {
145 current_column += display_arg(type, proc, i, func->param_types[i]);
146 if (func->params_right) {
147 current_column += fprintf(output, ", ");
148 }
149 }
150 if (!func->params_right && func->return_type == LT_PT_VOID) {
151 current_column += fprintf(output, ") ");
152 tabto(opt_a);
153 fprintf(output, "= <void>\n");
154 current_pid = 0;
155 current_column = 0;
156 }
157 }
158}
159
160void output_right(enum tof type, struct process * proc, char * function_name)
161{
162 struct function * func = name2func(function_name);
163
164 if (func && func->params_right==0 && func->return_type == LT_PT_VOID) {
165 return;
166 }
167
168 if (current_pid && current_pid!=proc->pid) {
169 fprintf(output, " <unfinished ...>\n");
170 begin_of_line(type, proc);
171 current_column += fprintf(output, "<... %s resumed> ", function_name);
172 } else if (!current_pid) {
173 begin_of_line(type, proc);
174 current_column += fprintf(output, "<... %s resumed> ", function_name);
175 }
176
177 if (!func) {
178 current_column += fprintf(output, ") ");
179 tabto(opt_a);
180 fprintf(output, "= ");
181 display_arg(type, proc, -1, LT_PT_UNKNOWN);
Juan Cespedes3268a161997-08-25 16:45:22 +0200182 fprintf(output, "\n");
Juan Cespedes5e01f651998-03-08 22:31:44 +0100183 } else {
184 int i;
185 for(i=func->num_params-func->params_right; i<func->num_params-1; i++) {
186 current_column += display_arg(type, proc, i, func->param_types[i]);
187 current_column += fprintf(output, ", ");
188 }
189 if (func->params_right) {
190 current_column += display_arg(type, proc, i, func->param_types[i]);
191 }
192 current_column += fprintf(output, ") ");
193 tabto(opt_a);
194 fprintf(output, "= ");
195 if (func->return_type == LT_PT_VOID) {
196 fprintf(output, "<void>");
197 } else {
198 display_arg(type, proc, -1, func->return_type);
199 }
200 fprintf(output, "\n");
Juan Cespedes5e4455b1997-08-24 01:48:26 +0200201 }
Juan Cespedes5e01f651998-03-08 22:31:44 +0100202 current_pid=0;
203 current_column=0;
Juan Cespedesc40e64a1997-10-26 20:34:00 +0100204}