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