output.c revision e75fc3bfb167fb56c82a3af706b64335412639a8
1/*
2 * This file is part of ltrace.
3 * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc.
4 * Copyright (C) 2010 Joe Damato
5 * Copyright (C) 1997,1998,1999,2001,2002,2003,2004,2007,2008,2009 Juan Cespedes
6 * Copyright (C) 2006 Paul Gilliam
7 * Copyright (C) 2006 Ian Wienand
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA
23 */
24
25#include "config.h"
26
27#include <stdio.h>
28#include <stdlib.h>
29#include <stdarg.h>
30#include <string.h>
31#include <time.h>
32#include <sys/time.h>
33#include <unistd.h>
34#include <errno.h>
35#include <assert.h>
36
37#include "common.h"
38#include "proc.h"
39#include "library.h"
40#include "type.h"
41#include "value.h"
42#include "value_dict.h"
43#include "param.h"
44#include "fetch.h"
45#include "lens_default.h"
46
47/* TODO FIXME XXX: include in common.h: */
48extern struct timeval current_time_spent;
49
50Dict *dict_opt_c = NULL;
51
52static Process *current_proc = 0;
53static size_t current_depth = 0;
54static int current_column = 0;
55
56static void
57output_indent(struct Process *proc)
58{
59	int d = options.indent * (proc->callstack_depth - 1);
60	current_column += fprintf(options.output, "%*s", d, "");
61}
62
63static void
64begin_of_line(Process *proc, int is_func, int indent)
65{
66	current_column = 0;
67	if (!proc) {
68		return;
69	}
70	if ((options.output != stderr) && (opt_p || options.follow)) {
71		current_column += fprintf(options.output, "%u ", proc->pid);
72	} else if (options.follow) {
73		current_column += fprintf(options.output, "[pid %u] ", proc->pid);
74	}
75	if (opt_r) {
76		struct timeval tv;
77		struct timezone tz;
78		static struct timeval old_tv = { 0, 0 };
79		struct timeval diff;
80
81		gettimeofday(&tv, &tz);
82
83		if (old_tv.tv_sec == 0 && old_tv.tv_usec == 0) {
84			old_tv.tv_sec = tv.tv_sec;
85			old_tv.tv_usec = tv.tv_usec;
86		}
87		diff.tv_sec = tv.tv_sec - old_tv.tv_sec;
88		if (tv.tv_usec >= old_tv.tv_usec) {
89			diff.tv_usec = tv.tv_usec - old_tv.tv_usec;
90		} else {
91			diff.tv_sec--;
92			diff.tv_usec = 1000000 + tv.tv_usec - old_tv.tv_usec;
93		}
94		old_tv.tv_sec = tv.tv_sec;
95		old_tv.tv_usec = tv.tv_usec;
96		current_column += fprintf(options.output, "%3lu.%06d ",
97					  diff.tv_sec, (int)diff.tv_usec);
98	}
99	if (opt_t) {
100		struct timeval tv;
101		struct timezone tz;
102
103		gettimeofday(&tv, &tz);
104		if (opt_t > 2) {
105			current_column += fprintf(options.output, "%lu.%06d ",
106						  tv.tv_sec, (int)tv.tv_usec);
107		} else if (opt_t > 1) {
108			struct tm *tmp = localtime(&tv.tv_sec);
109			current_column +=
110			    fprintf(options.output, "%02d:%02d:%02d.%06d ",
111				    tmp->tm_hour, tmp->tm_min, tmp->tm_sec,
112				    (int)tv.tv_usec);
113		} else {
114			struct tm *tmp = localtime(&tv.tv_sec);
115			current_column += fprintf(options.output, "%02d:%02d:%02d ",
116						  tmp->tm_hour, tmp->tm_min,
117						  tmp->tm_sec);
118		}
119	}
120	if (opt_i) {
121		if (is_func)
122			current_column += fprintf(options.output, "[%p] ",
123						  proc->return_addr);
124		else
125			current_column += fprintf(options.output, "[%p] ",
126						  proc->instruction_pointer);
127	}
128	if (options.indent > 0 && indent) {
129		output_indent(proc);
130	}
131}
132
133static struct arg_type_info *
134get_unknown_type(void)
135{
136	static struct arg_type_info *info = NULL;
137	if (info == NULL) {
138		info = malloc(sizeof(*info));
139		if (info == NULL) {
140			report_global_error("malloc: %s", strerror(errno));
141			abort();
142		}
143		*info = *type_get_simple(ARGTYPE_LONG);
144		info->lens = &guess_lens;
145	}
146	return info;
147}
148
149/* The default prototype is: long X(long, long, long, long).  */
150static Function *
151build_default_prototype(void)
152{
153	Function *ret = malloc(sizeof(*ret));
154	size_t i = 0;
155	if (ret == NULL)
156		goto err;
157	memset(ret, 0, sizeof(*ret));
158
159	struct arg_type_info *unknown_type = get_unknown_type();
160
161	ret->return_info = unknown_type;
162	ret->own_return_info = 0;
163
164	ret->num_params = 4;
165	ret->params = malloc(sizeof(*ret->params) * ret->num_params);
166	if (ret->params == NULL)
167		goto err;
168
169	for (i = 0; i < ret->num_params; ++i)
170		param_init_type(&ret->params[i], unknown_type, 0);
171
172	return ret;
173
174err:
175	report_global_error("malloc: %s", strerror(errno));
176	if (ret->params != NULL) {
177		while (i-- > 0)
178			param_destroy(&ret->params[i]);
179		free(ret->params);
180	}
181
182	free(ret);
183
184	return NULL;
185}
186
187static Function *
188name2func(char const *name) {
189	Function *tmp;
190	const char *str1, *str2;
191
192	for (tmp = list_of_functions; tmp != NULL; tmp = tmp->next) {
193		str1 = tmp->name;
194		str2 = name;
195		if (!strcmp(str1, str2))
196			return tmp;
197	}
198
199	static Function *def = NULL;
200	if (def == NULL)
201		def = build_default_prototype();
202
203	return def;
204}
205
206void
207output_line(Process *proc, char *fmt, ...) {
208	va_list args;
209
210	if (options.summary) {
211		return;
212	}
213	if (current_proc) {
214		if (current_proc->callstack[current_depth].return_addr) {
215			fprintf(options.output, " <unfinished ...>\n");
216		} else {
217			fprintf(options.output, " <no return ...>\n");
218		}
219	}
220	current_proc = 0;
221	if (!fmt) {
222		return;
223	}
224	begin_of_line(proc, 0, 0);
225
226	va_start(args, fmt);
227	vfprintf(options.output, fmt, args);
228	fprintf(options.output, "\n");
229	va_end(args);
230	current_column = 0;
231}
232
233static void
234tabto(int col) {
235	if (current_column < col) {
236		fprintf(options.output, "%*s", col - current_column, "");
237	}
238}
239
240static int
241account_output(int o)
242{
243	if (o < 0)
244		return -1;
245	current_column += o;
246	return 0;
247}
248
249static int
250output_error(void)
251{
252	return account_output(fprintf(options.output, "?"));
253}
254
255static int
256fetch_simple_param(enum tof type, Process *proc, struct fetch_context *context,
257		   struct value_dict *arguments, struct arg_type_info *info,
258		   struct value *valuep)
259{
260	/* Arrays decay into pointers per C standard.  We check for
261	 * this here, because here we also capture arrays that come
262	 * from parameter packs.  */
263	int own = 0;
264	if (info->type == ARGTYPE_ARRAY) {
265		struct arg_type_info *tmp = malloc(sizeof(*tmp));
266		if (tmp != NULL) {
267			type_init_pointer(tmp, info, 0);
268			tmp->lens = info->lens;
269			info = tmp;
270			own = 1;
271		}
272	}
273
274	struct value value;
275	value_init(&value, proc, NULL, info, own);
276	if (fetch_arg_next(context, type, proc, info, &value) < 0)
277		return -1;
278
279	if (val_dict_push_next(arguments, &value) < 0) {
280		value_destroy(&value);
281		return -1;
282	}
283
284	if (valuep != NULL)
285		*valuep = value;
286
287	return 0;
288}
289
290static void
291fetch_param_stop(struct value_dict *arguments, ssize_t *params_leftp)
292{
293	if (*params_leftp == -1)
294		*params_leftp = val_dict_count(arguments);
295}
296
297static int
298fetch_param_pack(enum tof type, Process *proc, struct fetch_context *context,
299		 struct value_dict *arguments, struct param *param,
300		 ssize_t *params_leftp)
301{
302	struct param_enum *e = param_pack_init(param, arguments);
303	if (e == NULL)
304		return -1;
305
306	int ret = 0;
307	while (1) {
308		int insert_stop = 0;
309		struct arg_type_info *info = malloc(sizeof(*info));
310		if (info == NULL
311		    || param_pack_next(param, e, info, &insert_stop) < 0) {
312		fail:
313			free(info);
314			ret = -1;
315			break;
316		}
317
318		if (insert_stop)
319			fetch_param_stop(arguments, params_leftp);
320
321		if (info->type == ARGTYPE_VOID)
322			break;
323
324		struct value val;
325		if (fetch_simple_param(type, proc, context, arguments,
326				       info, &val) < 0)
327			goto fail;
328
329		int stop = 0;
330		switch (param_pack_stop(param, e, &val)) {
331		case PPCB_ERR:
332			goto fail;
333		case PPCB_STOP:
334			stop = 1;
335		case PPCB_CONT:
336			break;
337		}
338
339		if (stop)
340			break;
341	}
342
343	param_pack_done(param, e);
344	return ret;
345}
346
347static int
348fetch_one_param(enum tof type, Process *proc, struct fetch_context *context,
349		struct value_dict *arguments, struct param *param,
350		ssize_t *params_leftp)
351{
352	switch (param->flavor) {
353	case PARAM_FLAVOR_TYPE:
354		return fetch_simple_param(type, proc, context, arguments,
355					  param->u.type.type, NULL);
356
357	case PARAM_FLAVOR_PACK:
358		return fetch_param_pack(type, proc, context, arguments,
359					param, params_leftp);
360
361	case PARAM_FLAVOR_STOP:
362		fetch_param_stop(arguments, params_leftp);
363		return 0;
364	}
365
366	assert(!"Invalid param flavor!");
367	abort();
368}
369
370static int
371fetch_params(enum tof type, Process *proc, struct fetch_context *context,
372	     struct value_dict *arguments, Function *func, ssize_t *params_leftp)
373{
374	size_t i;
375	for (i = 0; i < func->num_params; ++i)
376		if (fetch_one_param(type, proc, context, arguments,
377				    &func->params[i], params_leftp) < 0)
378			return -1;
379
380	/* Implicit stop at the end of parameter list.  */
381	fetch_param_stop(arguments, params_leftp);
382
383	return 0;
384}
385
386static int
387output_one(struct value *val, struct value_dict *arguments)
388{
389	int o = format_argument(options.output, val, arguments);
390	if (account_output(o) < 0) {
391		if (output_error() < 0)
392			return -1;
393		o = 1;
394	}
395	return o;
396}
397
398static int
399output_params(struct value_dict *arguments, size_t start, size_t end,
400	      int *need_delimp)
401{
402	size_t i;
403	int need_delim = *need_delimp;
404	for (i = start; i < end; ++i) {
405		if (need_delim
406		    && account_output(fprintf(options.output, ", ")) < 0)
407			return -1;
408		struct value *value = val_dict_get_num(arguments, i);
409		if (value == NULL)
410			return -1;
411		need_delim = output_one(value, arguments);
412		if (need_delim < 0)
413			return -1;
414	}
415	*need_delimp = need_delim;
416	return 0;
417}
418
419void
420output_left(enum tof type, struct Process *proc,
421	    struct library_symbol *libsym)
422{
423	const char *function_name = libsym->name;
424	Function *func;
425
426	if (options.summary) {
427		return;
428	}
429	if (current_proc) {
430		fprintf(options.output, " <unfinished ...>\n");
431		current_column = 0;
432	}
433	current_proc = proc;
434	current_depth = proc->callstack_depth;
435	begin_of_line(proc, type == LT_TOF_FUNCTION, 1);
436	if (!options.hide_caller && libsym->lib != NULL
437	    && libsym->plt_type != LS_TOPLT_NONE)
438		current_column += fprintf(options.output, "%s->",
439					  libsym->lib->soname);
440
441	const char *name = function_name;
442#ifdef USE_DEMANGLE
443	if (options.demangle)
444		name = my_demangle(function_name);
445#endif
446	if (account_output(fprintf(options.output, "%s(", name)) < 0)
447		return;
448
449	func = name2func(function_name);
450	if (func == NULL)
451		return;
452
453	struct fetch_context *context = fetch_arg_init(type, proc,
454						       func->return_info);
455	struct value_dict *arguments = malloc(sizeof(*arguments));
456	if (arguments == NULL)
457		return;
458	val_dict_init(arguments);
459
460	ssize_t params_left = -1;
461	int need_delim = 0;
462	if (fetch_params(type, proc, context, arguments, func, &params_left) < 0
463	    || output_params(arguments, 0, params_left, &need_delim) < 0) {
464		val_dict_destroy(arguments);
465		fetch_arg_done(context);
466		arguments = NULL;
467		context = NULL;
468	}
469
470	struct callstack_element *stel
471		= &proc->callstack[proc->callstack_depth - 1];
472	stel->fetch_context = context;
473	stel->arguments = arguments;
474	stel->out.params_left = params_left;
475	stel->out.need_delim = need_delim;
476}
477
478void
479output_right(enum tof type, struct Process *proc, struct library_symbol *libsym)
480{
481	const char *function_name = libsym->name;
482	Function *func = name2func(function_name);
483	if (func == NULL)
484		return;
485
486	if (options.summary) {
487		struct opt_c_struct *st;
488		if (!dict_opt_c) {
489			dict_opt_c =
490			    dict_init(dict_key2hash_string,
491				      dict_key_cmp_string);
492		}
493		st = dict_find_entry(dict_opt_c, function_name);
494		if (!st) {
495			char *na;
496			st = malloc(sizeof(struct opt_c_struct));
497			na = strdup(function_name);
498			if (!st || !na) {
499				perror("malloc()");
500				exit(1);
501			}
502			st->count = 0;
503			st->tv.tv_sec = st->tv.tv_usec = 0;
504			dict_enter(dict_opt_c, na, st);
505		}
506		if (st->tv.tv_usec + current_time_spent.tv_usec > 1000000) {
507			st->tv.tv_usec += current_time_spent.tv_usec - 1000000;
508			st->tv.tv_sec++;
509		} else {
510			st->tv.tv_usec += current_time_spent.tv_usec;
511		}
512		st->count++;
513		st->tv.tv_sec += current_time_spent.tv_sec;
514
515//              fprintf(options.output, "%s <%lu.%06d>\n", function_name,
516//                              current_time_spent.tv_sec, (int)current_time_spent.tv_usec);
517		return;
518	}
519	if (current_proc && (current_proc != proc ||
520			    current_depth != proc->callstack_depth)) {
521		fprintf(options.output, " <unfinished ...>\n");
522		current_proc = 0;
523	}
524	if (current_proc != proc) {
525		begin_of_line(proc, type == LT_TOF_FUNCTIONR, 1);
526#ifdef USE_DEMANGLE
527		current_column +=
528		    fprintf(options.output, "<... %s resumed> ",
529			    options.demangle ? my_demangle(function_name) : function_name);
530#else
531		current_column +=
532		    fprintf(options.output, "<... %s resumed> ", function_name);
533#endif
534	}
535
536	struct callstack_element *stel
537		= &proc->callstack[proc->callstack_depth - 1];
538
539	struct fetch_context *context = stel->fetch_context;
540
541	/* Fetch & enter into dictionary the retval first, so that
542	 * other values can use it in expressions.  */
543	struct value retval;
544	int own_retval = 0;
545	if (context != NULL) {
546		value_init(&retval, proc, NULL, func->return_info, 0);
547		own_retval = 1;
548		if (fetch_retval(context, type, proc, func->return_info,
549				 &retval) == 0) {
550			if (stel->arguments != NULL
551			    && val_dict_push_named(stel->arguments, &retval,
552						   "retval", 0) == 0)
553				own_retval = 0;
554		}
555	}
556
557	if (stel->arguments != NULL)
558		output_params(stel->arguments, stel->out.params_left,
559			      val_dict_count(stel->arguments),
560			      &stel->out.need_delim);
561
562	current_column += fprintf(options.output, ") ");
563	tabto(options.align - 1);
564	fprintf(options.output, "= ");
565
566	if (context != NULL && retval.type != NULL)
567		output_one(&retval, stel->arguments);
568
569	if (own_retval)
570		value_destroy(&retval);
571
572	if (stel->arguments != NULL) {
573		val_dict_destroy(stel->arguments);
574		free(stel->arguments);
575	}
576	if (context != NULL)
577		fetch_arg_done(context);
578
579	if (opt_T) {
580		fprintf(options.output, " <%lu.%06d>",
581			current_time_spent.tv_sec,
582			(int)current_time_spent.tv_usec);
583	}
584	fprintf(options.output, "\n");
585
586#if defined(HAVE_LIBUNWIND)
587	if (options.bt_depth > 0) {
588		unw_cursor_t cursor;
589		unw_word_t ip, sp;
590		int unwind_depth = options.bt_depth;
591		char fn_name[100];
592
593		unw_init_remote(&cursor, proc->unwind_as, proc->unwind_priv);
594		while (unwind_depth) {
595			unw_get_reg(&cursor, UNW_REG_IP, &ip);
596			unw_get_reg(&cursor, UNW_REG_SP, &sp);
597			unw_get_proc_name(&cursor, fn_name, 100, NULL);
598			fprintf(options.output, "\t\t\t%s (ip = 0x%lx)\n", fn_name, (long) ip);
599			if (unw_step(&cursor) <= 0)
600				break;
601			unwind_depth--;
602		}
603		fprintf(options.output, "\n");
604	}
605#endif /* defined(HAVE_LIBUNWIND) */
606
607	current_proc = 0;
608	current_column = 0;
609}
610
611static void
612do_report(const char *filename, unsigned line_no, const char *severity,
613	  const char *fmt, va_list args)
614{
615	char buf[128];
616	vsnprintf(buf, sizeof(buf), fmt, args);
617	buf[sizeof(buf) - 1] = 0;
618	if (filename != NULL)
619		output_line(0, "%s:%d: %s: %s",
620			    filename, line_no, severity, buf);
621	else
622		output_line(0, "%s: %s", severity, buf);
623}
624
625void
626report_error(const char *filename, unsigned line_no, char *fmt, ...)
627{
628	va_list args;
629	va_start(args, fmt);
630	do_report(filename, line_no, "error", fmt, args);
631	va_end(args);
632}
633
634void
635report_warning(const char *filename, unsigned line_no, char *fmt, ...)
636{
637	va_list args;
638	va_start(args, fmt);
639	do_report(filename, line_no, "warning", fmt, args);
640	va_end(args);
641}
642
643void
644report_global_error(char *fmt, ...)
645{
646	va_list args;
647	va_start(args, fmt);
648	do_report(NULL, 0, "error", fmt, args);
649	va_end(args);
650}
651