output.c revision e99af270a60891e68d465c4cd97dbe29cd1a05e4
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#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		int rc;
354	case PARAM_FLAVOR_TYPE:
355		return fetch_simple_param(type, proc, context, arguments,
356					  param->u.type.type, NULL);
357
358	case PARAM_FLAVOR_PACK:
359		if (fetch_param_pack_start(context,
360					   param->u.pack.ppflavor) < 0)
361			return -1;
362	        rc = fetch_param_pack(type, proc, context, arguments,
363				      param, params_leftp);
364		fetch_param_pack_end(context);
365		return rc;
366
367	case PARAM_FLAVOR_STOP:
368		fetch_param_stop(arguments, params_leftp);
369		return 0;
370	}
371
372	assert(!"Invalid param flavor!");
373	abort();
374}
375
376static int
377fetch_params(enum tof type, Process *proc, struct fetch_context *context,
378	     struct value_dict *arguments, Function *func, ssize_t *params_leftp)
379{
380	size_t i;
381	for (i = 0; i < func->num_params; ++i)
382		if (fetch_one_param(type, proc, context, arguments,
383				    &func->params[i], params_leftp) < 0)
384			return -1;
385
386	/* Implicit stop at the end of parameter list.  */
387	fetch_param_stop(arguments, params_leftp);
388
389	return 0;
390}
391
392static int
393output_one(struct value *val, struct value_dict *arguments)
394{
395	int o = format_argument(options.output, val, arguments);
396	if (account_output(o) < 0) {
397		if (output_error() < 0)
398			return -1;
399		o = 1;
400	}
401	return o;
402}
403
404static int
405output_params(struct value_dict *arguments, size_t start, size_t end,
406	      int *need_delimp)
407{
408	size_t i;
409	int need_delim = *need_delimp;
410	for (i = start; i < end; ++i) {
411		if (need_delim
412		    && account_output(fprintf(options.output, ", ")) < 0)
413			return -1;
414		struct value *value = val_dict_get_num(arguments, i);
415		if (value == NULL)
416			return -1;
417		need_delim = output_one(value, arguments);
418		if (need_delim < 0)
419			return -1;
420	}
421	*need_delimp = need_delim;
422	return 0;
423}
424
425void
426output_left(enum tof type, struct Process *proc,
427	    struct library_symbol *libsym)
428{
429	const char *function_name = libsym->name;
430	Function *func;
431
432	if (options.summary) {
433		return;
434	}
435	if (current_proc) {
436		fprintf(options.output, " <unfinished ...>\n");
437		current_column = 0;
438	}
439	current_proc = proc;
440	current_depth = proc->callstack_depth;
441	begin_of_line(proc, type == LT_TOF_FUNCTION, 1);
442	if (!options.hide_caller && libsym->lib != NULL
443	    && libsym->plt_type != LS_TOPLT_NONE)
444		current_column += fprintf(options.output, "%s->",
445					  libsym->lib->soname);
446
447	const char *name = function_name;
448#ifdef USE_DEMANGLE
449	if (options.demangle)
450		name = my_demangle(function_name);
451#endif
452	if (account_output(fprintf(options.output, "%s(", name)) < 0)
453		return;
454
455	func = name2func(function_name);
456	if (func == NULL)
457		return;
458
459	struct fetch_context *context = fetch_arg_init(type, proc,
460						       func->return_info);
461	struct value_dict *arguments = malloc(sizeof(*arguments));
462	if (arguments == NULL)
463		return;
464	val_dict_init(arguments);
465
466	ssize_t params_left = -1;
467	int need_delim = 0;
468	if (fetch_params(type, proc, context, arguments, func, &params_left) < 0
469	    || output_params(arguments, 0, params_left, &need_delim) < 0) {
470		val_dict_destroy(arguments);
471		fetch_arg_done(context);
472		arguments = NULL;
473		context = NULL;
474	}
475
476	struct callstack_element *stel
477		= &proc->callstack[proc->callstack_depth - 1];
478	stel->fetch_context = context;
479	stel->arguments = arguments;
480	stel->out.params_left = params_left;
481	stel->out.need_delim = need_delim;
482}
483
484void
485output_right(enum tof type, struct Process *proc, struct library_symbol *libsym)
486{
487	const char *function_name = libsym->name;
488	Function *func = name2func(function_name);
489	if (func == NULL)
490		return;
491
492	if (options.summary) {
493		struct opt_c_struct *st;
494		if (!dict_opt_c) {
495			dict_opt_c =
496			    dict_init(dict_key2hash_string,
497				      dict_key_cmp_string);
498		}
499		st = dict_find_entry(dict_opt_c, function_name);
500		if (!st) {
501			char *na;
502			st = malloc(sizeof(struct opt_c_struct));
503			na = strdup(function_name);
504			if (!st || !na) {
505				perror("malloc()");
506				exit(1);
507			}
508			st->count = 0;
509			st->tv.tv_sec = st->tv.tv_usec = 0;
510			dict_enter(dict_opt_c, na, st);
511		}
512		if (st->tv.tv_usec + current_time_spent.tv_usec > 1000000) {
513			st->tv.tv_usec += current_time_spent.tv_usec - 1000000;
514			st->tv.tv_sec++;
515		} else {
516			st->tv.tv_usec += current_time_spent.tv_usec;
517		}
518		st->count++;
519		st->tv.tv_sec += current_time_spent.tv_sec;
520
521//              fprintf(options.output, "%s <%lu.%06d>\n", function_name,
522//                              current_time_spent.tv_sec, (int)current_time_spent.tv_usec);
523		return;
524	}
525	if (current_proc && (current_proc != proc ||
526			    current_depth != proc->callstack_depth)) {
527		fprintf(options.output, " <unfinished ...>\n");
528		current_proc = 0;
529	}
530	if (current_proc != proc) {
531		begin_of_line(proc, type == LT_TOF_FUNCTIONR, 1);
532#ifdef USE_DEMANGLE
533		current_column +=
534		    fprintf(options.output, "<... %s resumed> ",
535			    options.demangle ? my_demangle(function_name) : function_name);
536#else
537		current_column +=
538		    fprintf(options.output, "<... %s resumed> ", function_name);
539#endif
540	}
541
542	struct callstack_element *stel
543		= &proc->callstack[proc->callstack_depth - 1];
544
545	struct fetch_context *context = stel->fetch_context;
546
547	/* Fetch & enter into dictionary the retval first, so that
548	 * other values can use it in expressions.  */
549	struct value retval;
550	int own_retval = 0;
551	if (context != NULL) {
552		value_init(&retval, proc, NULL, func->return_info, 0);
553		own_retval = 1;
554		if (fetch_retval(context, type, proc, func->return_info,
555				 &retval) < 0)
556			value_set_type(&retval, NULL, 0);
557		else if (stel->arguments != NULL
558			   && val_dict_push_named(stel->arguments, &retval,
559						  "retval", 0) == 0)
560			own_retval = 0;
561	}
562
563	if (stel->arguments != NULL)
564		output_params(stel->arguments, stel->out.params_left,
565			      val_dict_count(stel->arguments),
566			      &stel->out.need_delim);
567
568	current_column += fprintf(options.output, ") ");
569	tabto(options.align - 1);
570	fprintf(options.output, "= ");
571
572	if (context != NULL && retval.type != NULL)
573		output_one(&retval, stel->arguments);
574
575	if (own_retval)
576		value_destroy(&retval);
577
578	if (stel->arguments != NULL) {
579		val_dict_destroy(stel->arguments);
580		free(stel->arguments);
581	}
582	if (context != NULL)
583		fetch_arg_done(context);
584
585	if (opt_T) {
586		fprintf(options.output, " <%lu.%06d>",
587			current_time_spent.tv_sec,
588			(int)current_time_spent.tv_usec);
589	}
590	fprintf(options.output, "\n");
591
592#if defined(HAVE_LIBUNWIND)
593	if (options.bt_depth > 0) {
594		unw_cursor_t cursor;
595		unw_word_t ip, sp;
596		int unwind_depth = options.bt_depth;
597		char fn_name[100];
598
599		unw_init_remote(&cursor, proc->unwind_as, proc->unwind_priv);
600		while (unwind_depth) {
601			unw_get_reg(&cursor, UNW_REG_IP, &ip);
602			unw_get_reg(&cursor, UNW_REG_SP, &sp);
603			unw_get_proc_name(&cursor, fn_name, 100, NULL);
604			fprintf(options.output, "\t\t\t%s (ip = 0x%lx)\n", fn_name, (long) ip);
605			if (unw_step(&cursor) <= 0)
606				break;
607			unwind_depth--;
608		}
609		fprintf(options.output, "\n");
610	}
611#endif /* defined(HAVE_LIBUNWIND) */
612
613	current_proc = 0;
614	current_column = 0;
615}
616
617static void
618do_report(const char *filename, unsigned line_no, const char *severity,
619	  const char *fmt, va_list args)
620{
621	char buf[128];
622	vsnprintf(buf, sizeof(buf), fmt, args);
623	buf[sizeof(buf) - 1] = 0;
624	if (filename != NULL)
625		output_line(0, "%s:%d: %s: %s",
626			    filename, line_no, severity, buf);
627	else
628		output_line(0, "%s: %s", severity, buf);
629}
630
631void
632report_error(const char *filename, unsigned line_no, char *fmt, ...)
633{
634	va_list args;
635	va_start(args, fmt);
636	do_report(filename, line_no, "error", fmt, args);
637	va_end(args);
638}
639
640void
641report_warning(const char *filename, unsigned line_no, char *fmt, ...)
642{
643	va_list args;
644	va_start(args, fmt);
645	do_report(filename, line_no, "warning", fmt, args);
646	va_end(args);
647}
648
649void
650report_global_error(char *fmt, ...)
651{
652	va_list args;
653	va_start(args, fmt);
654	do_report(NULL, 0, "error", fmt, args);
655	va_end(args);
656}
657