main.c revision 178670
1176349Smarcel/*
2176349Smarcel * Copyright (c) 2004 Marcel Moolenaar
3182724Sraj * All rights reserved.
4182724Sraj *
5176349Smarcel * Redistribution and use in source and binary forms, with or without
6176349Smarcel * modification, are permitted provided that the following conditions
7176349Smarcel * are met:
8176349Smarcel *
9176349Smarcel * 1. Redistributions of source code must retain the above copyright
10176349Smarcel *    notice, this list of conditions and the following disclaimer.
11176349Smarcel * 2. Redistributions in binary form must reproduce the above copyright
12176349Smarcel *    notice, this list of conditions and the following disclaimer in the
13176349Smarcel *    documentation and/or other materials provided with the distribution.
14176349Smarcel *
15176349Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16176349Smarcel * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17176349Smarcel * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18176349Smarcel * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19176349Smarcel * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20176349Smarcel * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21176349Smarcel * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22176349Smarcel * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23176349Smarcel * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24176349Smarcel * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25176349Smarcel */
26176349Smarcel
27176349Smarcel#include <sys/cdefs.h>
28176349Smarcel__FBSDID("$FreeBSD: head/gnu/usr.bin/gdb/kgdb/main.c 178670 2008-04-29 20:32:45Z jhb $");
29176349Smarcel
30176349Smarcel#include <sys/param.h>
31176349Smarcel#include <sys/stat.h>
32176349Smarcel#include <sys/types.h>
33176349Smarcel#include <sys/ioctl.h>
34176349Smarcel#include <sys/resource.h>
35176349Smarcel#include <sys/select.h>
36176349Smarcel#include <sys/time.h>
37176349Smarcel#include <sys/wait.h>
38176349Smarcel#include <errno.h>
39176349Smarcel#include <err.h>
40176349Smarcel#include <inttypes.h>
41176349Smarcel#include <kvm.h>
42176487Smarcel#include <limits.h>
43176349Smarcel#include <paths.h>
44208538Sraj#include <stdio.h>
45243693Sgonzo#include <stdlib.h>
46208538Sraj#include <string.h>
47208538Sraj#include <unistd.h>
48176349Smarcel
49176349Smarcel/* libgdb stuff. */
50176349Smarcel#include <defs.h>
51176349Smarcel#include <frame.h>
52176489Smarcel#include <frame-unwind.h>
53176349Smarcel#include <inferior.h>
54176489Smarcel#include <interps.h>
55176489Smarcel#include <cli-out.h>
56176349Smarcel#include <main.h>
57176489Smarcel#include <objfiles.h>
58176489Smarcel#include <target.h>
59176489Smarcel#include <top.h>
60176489Smarcel#include <ui-file.h>
61176489Smarcel#include <bfd.h>
62176489Smarcel#include <gdbcore.h>
63176489Smarcel#include <wrapper.h>
64176489Smarcel
65176489Smarcelextern frame_unwind_sniffer_ftype *kgdb_sniffer_kluge;
66176489Smarcel
67176489Smarcel#include "kgdb.h"
68176489Smarcel
69176349Smarcelstatic int dumpnr;
70176349Smarcelstatic int quiet;
71176487Smarcelstatic int verbose;
72176349Smarcel
73176349Smarcelstatic char crashdir[PATH_MAX];
74176489Smarcelstatic char *kernel;
75235094Skientzlestatic char *remote;
76176489Smarcelstatic char *vmcore;
77176489Smarcelstatic struct ui_file *parse_gdberr;
78176489Smarcel
79176489Smarcelstatic void (*kgdb_new_objfile_chain)(struct objfile * objfile);
80176489Smarcel
81176489Smarcelstatic void
82176489Smarcelusage(void)
83176489Smarcel{
84176489Smarcel
85176489Smarcel	fprintf(stderr,
86176489Smarcel	    "usage: %s [-afqv] [-d crashdir] [-c core | -n dumpnr | -r device]\n"
87176489Smarcel	    "\t[kernel [core]]\n", getprogname());
88176489Smarcel	exit(1);
89176489Smarcel}
90176489Smarcel
91176489Smarcelstatic void
92176489Smarcelkernel_from_dumpnr(int nr)
93176489Smarcel{
94176489Smarcel	char path[PATH_MAX];
95176489Smarcel	FILE *info;
96176489Smarcel	char *s;
97176489Smarcel	struct stat st;
98176489Smarcel	int l;
99176489Smarcel
100176489Smarcel	/*
101176489Smarcel	 * If there's a kernel image right here in the crash directory, then
102176489Smarcel	 * use it.  The kernel image is either called kernel.<nr> or is in a
103176489Smarcel	 * subdirectory kernel.<nr> and called kernel.  The latter allows us
104176489Smarcel	 * to collect the modules in the same place.
105176489Smarcel	 */
106176489Smarcel	snprintf(path, sizeof(path), "%s/kernel.%d", crashdir, nr);
107176489Smarcel	if (stat(path, &st) == 0) {
108176489Smarcel		if (S_ISREG(st.st_mode)) {
109176489Smarcel			kernel = strdup(path);
110176489Smarcel			return;
111176489Smarcel		}
112176489Smarcel		if (S_ISDIR(st.st_mode)) {
113176489Smarcel			snprintf(path, sizeof(path), "%s/kernel.%d/kernel",
114176489Smarcel			    crashdir, nr);
115176489Smarcel			if (stat(path, &st) == 0 && S_ISREG(st.st_mode)) {
116176489Smarcel				kernel = strdup(path);
117176489Smarcel				return;
118176489Smarcel			}
119176489Smarcel		}
120176489Smarcel	}
121176489Smarcel
122176489Smarcel	/*
123176489Smarcel	 * No kernel image here.  Parse the dump header.  The kernel object
124176489Smarcel	 * directory can be found there and we probably have the kernel
125176489Smarcel	 * image still in it.  The object directory may also have a kernel
126176489Smarcel	 * with debugging info (called kernel.debug).  If we have a debug
127176489Smarcel	 * kernel, use it.
128176349Smarcel	 */
129176349Smarcel	snprintf(path, sizeof(path), "%s/info.%d", crashdir, nr);
130176489Smarcel	info = fopen(path, "r");
131176489Smarcel	if (info == NULL) {
132176489Smarcel		warn(path);
133176489Smarcel		return;
134176489Smarcel	}
135176489Smarcel	while (fgets(path, sizeof(path), info) != NULL) {
136235094Skientzle		l = strlen(path);
137235094Skientzle		if (l > 0 && path[l - 1] == '\n')
138235094Skientzle			path[--l] = '\0';
139235094Skientzle		if (strncmp(path, "    ", 4) == 0) {
140235094Skientzle			s = strchr(path, ':');
141235094Skientzle			s = (s == NULL) ? path + 4 : s + 1;
142176489Smarcel			l = snprintf(path, sizeof(path), "%s/kernel.debug", s);
143176489Smarcel			if (stat(path, &st) == -1 || !S_ISREG(st.st_mode)) {
144176349Smarcel				path[l - 6] = '\0';
145176349Smarcel				if (stat(path, &st) == -1 ||
146176349Smarcel				    !S_ISREG(st.st_mode))
147176349Smarcel					break;
148176349Smarcel			}
149176349Smarcel			kernel = strdup(path);
150176349Smarcel			break;
151176487Smarcel		}
152176349Smarcel	}
153176349Smarcel	fclose(info);
154176489Smarcel}
155176489Smarcel
156176489Smarcelstatic void
157176489Smarcelkgdb_new_objfile(struct objfile *objfile)
158176489Smarcel{
159176489Smarcel	static int once = 1;
160176489Smarcel
161176489Smarcel	kld_new_objfile(objfile);
162176489Smarcel	kgdb_trgt_new_objfile(objfile);
163176489Smarcel
164176489Smarcel	if (kgdb_new_objfile_chain != NULL)
165176489Smarcel		kgdb_new_objfile_chain(objfile);
166176489Smarcel
167176489Smarcel	if (once && objfile != NULL && objfile == symfile_objfile) {
168176489Smarcel		/*
169176349Smarcel		 * The initial kernel has just been loaded.  Start the
170176349Smarcel		 * remote target if we have one.
171176349Smarcel		 */
172176489Smarcel		once = 0;
173176349Smarcel		if (remote != NULL)
174176349Smarcel			push_remote_target (remote, 0);
175176349Smarcel	}
176176349Smarcel}
177176349Smarcel
178176349Smarcel/*
179176349Smarcel * Parse an expression and return its value.  If 'quiet' is true, then
180176349Smarcel * any error messages from the parser are masked.
181176349Smarcel */
182176349SmarcelCORE_ADDR
183176349Smarcelkgdb_parse_1(const char *exp, int quiet)
184176349Smarcel{
185176349Smarcel	struct ui_file *old_stderr;
186176349Smarcel	struct cleanup *old_chain;
187176349Smarcel	struct expression *expr;
188176349Smarcel	struct value *val;
189176349Smarcel	char *s;
190176349Smarcel	CORE_ADDR n;
191176489Smarcel
192176349Smarcel	old_stderr = gdb_stderr;
193176349Smarcel	if (quiet)
194176489Smarcel		gdb_stderr = parse_gdberr;
195176349Smarcel	n = 0;
196176349Smarcel	s = xstrdup(exp);
197176349Smarcel	old_chain = make_cleanup(xfree, s);
198176489Smarcel	if (gdb_parse_exp_1(&s, NULL, 0, &expr) && *s == '\0') {
199176349Smarcel		make_cleanup(free_current_contents, &expr);
200176349Smarcel		if (gdb_evaluate_expression(expr, &val))
201176349Smarcel		    n = value_as_address(val);
202176489Smarcel	}
203176349Smarcel	do_cleanups(old_chain);
204176349Smarcel	gdb_stderr = old_stderr;
205176349Smarcel	return (n);
206176489Smarcel}
207176489Smarcel
208176489Smarcel#define	MSGBUF_SEQ_TO_POS(size, seq)	((seq) % (size))
209176349Smarcel
210176489Smarcelvoid
211176349Smarcelkgdb_dmesg(void)
212176349Smarcel{
213176349Smarcel	CORE_ADDR bufp;
214176489Smarcel	int size, rseq, wseq;
215176349Smarcel	char c;
216176349Smarcel
217176349Smarcel	/*
218176489Smarcel	 * Display the unread portion of the message buffer. This gives the
219176489Smarcel	 * user a some initial data to work from.
220176349Smarcel	 */
221176489Smarcel	if (quiet)
222176349Smarcel		return;
223176349Smarcel	bufp = kgdb_parse("msgbufp->msg_ptr");
224176349Smarcel	size = (int)kgdb_parse("msgbufp->msg_size");
225176489Smarcel	rseq = (int)kgdb_parse("msgbufp->msg_rseq");
226176349Smarcel	wseq = (int)kgdb_parse("msgbufp->msg_wseq");
227176349Smarcel	rseq = MSGBUF_SEQ_TO_POS(size, rseq);
228176349Smarcel	wseq = MSGBUF_SEQ_TO_POS(size, wseq);
229176489Smarcel	if (bufp == 0 || size == 0 || rseq == wseq)
230176349Smarcel		return;
231176349Smarcel
232176349Smarcel	printf("\nUnread portion of the kernel message buffer:\n");
233176349Smarcel	while (rseq < wseq) {
234176487Smarcel		read_memory(bufp + rseq, &c, 1);
235176349Smarcel		putchar(c);
236176349Smarcel		rseq++;
237176489Smarcel		if (rseq == size)
238176489Smarcel			rseq = 0;
239176489Smarcel	}
240199534Sraj	if (c != '\n')
241176349Smarcel		putchar('\n');
242176489Smarcel	putchar('\n');
243176489Smarcel}
244176489Smarcel
245176349Smarcelstatic void
246176489Smarcelkgdb_init(char *argv0 __unused)
247176489Smarcel{
248176489Smarcel
249176489Smarcel	parse_gdberr = mem_fileopen();
250199534Sraj	set_prompt("(kgdb) ");
251199534Sraj	initialize_kgdb_target();
252176489Smarcel	initialize_kld_target();
253176489Smarcel	kgdb_new_objfile_chain = target_new_objfile_hook;
254176489Smarcel	target_new_objfile_hook = kgdb_new_objfile;
255176489Smarcel}
256176489Smarcel
257176349Smarcel/*
258176489Smarcel * Remote targets can support any number of syntaxes and we want to
259176489Smarcel * support them all with one addition: we support specifying a device
260176349Smarcel * node for a serial device without the "/dev/" prefix.
261176349Smarcel *
262176349Smarcel * What we do is to stat(2) the existing remote target first.  If that
263208538Sraj * fails, we try it with "/dev/" prepended.  If that succeeds we use
264176349Smarcel * the resulting path, otherwise we use the original target.  If
265176349Smarcel * either stat(2) succeeds make sure the file is either a character
266176349Smarcel * device or a FIFO.
267176349Smarcel */
268176349Smarcelstatic void
269176349Smarcelverify_remote(void)
270176349Smarcel{
271176349Smarcel	char path[PATH_MAX];
272176349Smarcel	struct stat st;
273208538Sraj
274176489Smarcel	if (stat(remote, &st) != 0) {
275176489Smarcel		snprintf(path, sizeof(path), "/dev/%s", remote);
276176489Smarcel		if (stat(path, &st) != 0)
277176489Smarcel			return;
278176489Smarcel		free(remote);
279176489Smarcel		remote = strdup(path);
280176489Smarcel	}
281176489Smarcel	if (!S_ISCHR(st.st_mode) && !S_ISFIFO(st.st_mode))
282243693Sgonzo		errx(1, "%s: not a special file, FIFO or socket", remote);
283208538Sraj}
284243693Sgonzo
285243693Sgonzostatic void
286176489Smarceladd_arg(struct captured_main_args *args, char *arg)
287176489Smarcel{
288176489Smarcel
289176349Smarcel	args->argc++;
290176489Smarcel	args->argv = reallocf(args->argv, (args->argc + 1) * sizeof(char *));
291176489Smarcel	if (args->argv == NULL)
292176489Smarcel		err(1, "Out of memory building argument list");
293176489Smarcel	args->argv[args->argc] = arg;
294176489Smarcel}
295208538Sraj
296208538Srajint
297208538Srajmain(int argc, char *argv[])
298208538Sraj{
299208538Sraj	char path[PATH_MAX];
300176489Smarcel	struct stat st;
301176349Smarcel	struct captured_main_args args;
302176489Smarcel	char *s;
303176349Smarcel	int a, ch;
304176489Smarcel
305176489Smarcel	dumpnr = -1;
306176489Smarcel
307176489Smarcel	strlcpy(crashdir, "/var/crash", sizeof(crashdir));
308176489Smarcel	s = getenv("KGDB_CRASH_DIR");
309176489Smarcel	if (s != NULL)
310176489Smarcel		strlcpy(crashdir, s, sizeof(crashdir));
311176489Smarcel
312176489Smarcel	/* Convert long options into short options. */
313176489Smarcel	for (a = 1; a < argc; a++) {
314176349Smarcel		s = argv[a];
315208538Sraj		if (s[0] == '-') {
316176489Smarcel			s++;
317176489Smarcel			/* Long options take either 1 or 2 dashes. */
318176489Smarcel			if (s[0] == '-')
319176489Smarcel				s++;
320176489Smarcel			if (strcmp(s, "quiet") == 0)
321208538Sraj				argv[a] = "-q";
322176489Smarcel			else if (strcmp(s, "fullname") == 0)
323176349Smarcel				argv[a] = "-f";
324208538Sraj		}
325176489Smarcel	}
326176489Smarcel
327176349Smarcel	quiet = 0;
328208538Sraj	memset (&args, 0, sizeof args);
329176489Smarcel	args.use_windows = 0;
330176349Smarcel	args.interpreter_p = INTERP_CONSOLE;
331243693Sgonzo	args.argv = malloc(sizeof(char *));
332243693Sgonzo	args.argv[0] = argv[0];
333243693Sgonzo
334243693Sgonzo	while ((ch = getopt(argc, argv, "ac:d:fn:qr:vw")) != -1) {
335243693Sgonzo		switch (ch) {
336243693Sgonzo		case 'a':
337243693Sgonzo			annotation_level++;
338243693Sgonzo			break;
339243693Sgonzo		case 'c':	/* use given core file. */
340243693Sgonzo			if (vmcore != NULL) {
341176489Smarcel				warnx("option %c: can only be specified once",
342176489Smarcel				    optopt);
343176489Smarcel				usage();
344176489Smarcel				/* NOTREACHED */
345176489Smarcel			}
346176489Smarcel			vmcore = strdup(optarg);
347176489Smarcel			break;
348208538Sraj		case 'd':	/* lookup dumps in given directory. */
349208538Sraj			strlcpy(crashdir, optarg, sizeof(crashdir));
350208538Sraj			break;
351243693Sgonzo		case 'f':
352233230Sraj			annotation_level = 1;
353233230Sraj			break;
354233230Sraj		case 'n':	/* use dump with given number. */
355233230Sraj			dumpnr = strtol(optarg, &s, 0);
356208538Sraj			if (dumpnr < 0 || *s != '\0') {
357208538Sraj				warnx("option %c: invalid kernel dump number",
358176489Smarcel				    optopt);
359176349Smarcel				usage();
360208538Sraj				/* NOTREACHED */
361176489Smarcel			}
362176489Smarcel			break;
363176489Smarcel		case 'q':
364176349Smarcel			quiet = 1;
365208538Sraj			add_arg(&args, "-q");
366176489Smarcel			break;
367176489Smarcel		case 'r':	/* use given device for remote session. */
368176349Smarcel			if (remote != NULL) {
369176489Smarcel				warnx("option %c: can only be specified once",
370176489Smarcel				    optopt);
371176349Smarcel				usage();
372246135Sian				/* NOTREACHED */
373246135Sian			}
374246135Sian			remote = strdup(optarg);
375246135Sian			break;
376246135Sian		case 'v':	/* increase verbosity. */
377246135Sian			verbose++;
378246135Sian			break;
379246135Sian		case 'w':	/* core file is writeable. */
380246135Sian			add_arg(&args, "--write");
381176489Smarcel			break;
382176489Smarcel		case '?':
383208538Sraj		default:
384208538Sraj			usage();
385176489Smarcel		}
386176349Smarcel	}
387208538Sraj
388176349Smarcel	if (((vmcore != NULL) ? 1 : 0) + ((dumpnr >= 0) ? 1 : 0) +
389	    ((remote != NULL) ? 1 : 0) > 1) {
390		warnx("options -c, -n and -r are mutually exclusive");
391		usage();
392		/* NOTREACHED */
393	}
394
395	if (verbose > 1)
396		warnx("using %s as the crash directory", crashdir);
397
398	if (argc > optind)
399		kernel = strdup(argv[optind++]);
400
401	if (argc > optind && (dumpnr >= 0 || remote != NULL)) {
402		warnx("options -n and -r do not take a core file. Ignored");
403		optind = argc;
404	}
405
406	if (dumpnr >= 0) {
407		snprintf(path, sizeof(path), "%s/vmcore.%d", crashdir, dumpnr);
408		if (stat(path, &st) == -1)
409			err(1, path);
410		if (!S_ISREG(st.st_mode))
411			errx(1, "%s: not a regular file", path);
412		vmcore = strdup(path);
413	} else if (remote != NULL) {
414		verify_remote();
415	} else if (argc > optind) {
416		if (vmcore == NULL)
417			vmcore = strdup(argv[optind++]);
418		if (argc > optind)
419			warnx("multiple core files specified. Ignored");
420	} else if (vmcore == NULL && kernel == NULL) {
421		vmcore = strdup(_PATH_MEM);
422		kernel = strdup(getbootfile());
423	}
424
425	if (verbose) {
426		if (vmcore != NULL)
427			warnx("core file: %s", vmcore);
428		if (remote != NULL)
429			warnx("device file: %s", remote);
430		if (kernel != NULL)
431			warnx("kernel image: %s", kernel);
432	}
433
434	/* A remote target requires an explicit kernel argument. */
435	if (remote != NULL && kernel == NULL) {
436		warnx("remote debugging requires a kernel");
437		usage();
438		/* NOTREACHED */
439	}
440
441	/* If we don't have a kernel image yet, try to find one. */
442	if (kernel == NULL) {
443		if (dumpnr >= 0)
444			kernel_from_dumpnr(dumpnr);
445
446		if (kernel == NULL)
447			errx(1, "couldn't find a suitable kernel image");
448		if (verbose)
449			warnx("kernel image: %s", kernel);
450	}
451	add_arg(&args, kernel);
452
453	if (vmcore != NULL)
454		add_arg(&args, vmcore);
455
456	/* The libgdb code uses optind too. Reset it... */
457	optind = 0;
458
459	/* Terminate argv list. */
460	add_arg(&args, NULL);
461
462	init_ui_hook = kgdb_init;
463
464	kgdb_sniffer_kluge = kgdb_trgt_trapframe_sniffer;
465
466	return (gdb_main(&args));
467}
468