main.c revision 245705
11590Srgrimes/* 21590Srgrimes * Copyright (c) 2004 Marcel Moolenaar 31590Srgrimes * All rights reserved. 41590Srgrimes * 51590Srgrimes * Redistribution and use in source and binary forms, with or without 61590Srgrimes * modification, are permitted provided that the following conditions 71590Srgrimes * are met: 81590Srgrimes * 91590Srgrimes * 1. Redistributions of source code must retain the above copyright 101590Srgrimes * notice, this list of conditions and the following disclaimer. 111590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 121590Srgrimes * notice, this list of conditions and the following disclaimer in the 131590Srgrimes * documentation and/or other materials provided with the distribution. 141590Srgrimes * 151590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 161590Srgrimes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 171590Srgrimes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 181590Srgrimes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 191590Srgrimes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 201590Srgrimes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 211590Srgrimes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 221590Srgrimes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 231590Srgrimes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 241590Srgrimes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 251590Srgrimes */ 261590Srgrimes 271590Srgrimes#include <sys/cdefs.h> 281590Srgrimes__FBSDID("$FreeBSD: head/gnu/usr.bin/gdb/kgdb/main.c 245705 2013-01-21 01:46:36Z adrian $"); 291590Srgrimes 301590Srgrimes#include <sys/param.h> 311590Srgrimes#include <sys/stat.h> 321590Srgrimes#include <sys/types.h> 331590Srgrimes#include <sys/ioctl.h> 341590Srgrimes#include <sys/resource.h> 351590Srgrimes#include <sys/select.h> 36116390Scharnier#include <sys/time.h> 371590Srgrimes#include <sys/wait.h> 381590Srgrimes#include <errno.h> 39116390Scharnier#include <err.h> 4027419Scharnier#include <inttypes.h> 41116390Scharnier#include <kvm.h> 4299112Sobrien#include <limits.h> 4399112Sobrien#include <paths.h> 441590Srgrimes#include <stdio.h> 4527419Scharnier#include <stdlib.h> 4627419Scharnier#include <string.h> 471590Srgrimes#include <unistd.h> 481590Srgrimes 491590Srgrimes/* libgdb stuff. */ 501590Srgrimes#include <defs.h> 5185632Sschweikh#include <frame.h> 521590Srgrimes#include <frame-unwind.h> 531590Srgrimes#include <inferior.h> 5485632Sschweikh#include <interps.h> 5585632Sschweikh#include <cli-out.h> 561590Srgrimes#include <main.h> 5785632Sschweikh#include <objfiles.h> 5885632Sschweikh#include <target.h> 591590Srgrimes#include <top.h> 601590Srgrimes#include <ui-file.h> 611590Srgrimes#include <bfd.h> 621590Srgrimes#include <gdbcore.h> 631590Srgrimes#include <wrapper.h> 6498771Sjmallett 6585632Sschweikhextern frame_unwind_sniffer_ftype *kgdb_sniffer_kluge; 6685632Sschweikh 671590Srgrimes#include "kgdb.h" 681590Srgrimes 691590Srgrimesstatic int dumpnr; 701590Srgrimesstatic int quiet; 711590Srgrimesstatic int verbose; 721590Srgrimes 731590Srgrimesstatic char crashdir[PATH_MAX]; 741590Srgrimesstatic char *kernel; 751590Srgrimesstatic char *remote; 761590Srgrimesstatic char *vmcore; 771590Srgrimesstatic struct ui_file *parse_gdberr; 781590Srgrimes 791590Srgrimesstatic void (*kgdb_new_objfile_chain)(struct objfile * objfile); 801590Srgrimes 811590Srgrimesstatic void 821590Srgrimesusage(void) 831590Srgrimes{ 841590Srgrimes 851590Srgrimes fprintf(stderr, 861590Srgrimes "usage: %s [-afqvw] [-d crashdir] [-c core | -n dumpnr | -r device]\n" 871590Srgrimes "\t[kernel [core]]\n", getprogname()); 881590Srgrimes exit(1); 891590Srgrimes} 9048566Sbillf 911590Srgrimesstatic void 921590Srgrimeskernel_from_dumpnr(int nr) 931590Srgrimes{ 941590Srgrimes char path[PATH_MAX]; 951590Srgrimes FILE *info; 961590Srgrimes char *s; 971590Srgrimes struct stat st; 981590Srgrimes int l; 9948566Sbillf 1001590Srgrimes /* 1011590Srgrimes * If there's a kernel image right here in the crash directory, then 1021590Srgrimes * use it. The kernel image is either called kernel.<nr> or is in a 1031590Srgrimes * subdirectory kernel.<nr> and called kernel. The latter allows us 1041590Srgrimes * to collect the modules in the same place. 1051590Srgrimes */ 1061590Srgrimes snprintf(path, sizeof(path), "%s/kernel.%d", crashdir, nr); 1071590Srgrimes if (stat(path, &st) == 0) { 1081590Srgrimes if (S_ISREG(st.st_mode)) { 1091590Srgrimes kernel = strdup(path); 1101590Srgrimes return; 1111590Srgrimes } 1121590Srgrimes if (S_ISDIR(st.st_mode)) { 1131590Srgrimes snprintf(path, sizeof(path), "%s/kernel.%d/kernel", 1141590Srgrimes crashdir, nr); 1151590Srgrimes if (stat(path, &st) == 0 && S_ISREG(st.st_mode)) { 1161590Srgrimes kernel = strdup(path); 1171590Srgrimes return; 1181590Srgrimes } 1191590Srgrimes } 1201590Srgrimes } 1211590Srgrimes 12298771Sjmallett /* 1231590Srgrimes * No kernel image here. Parse the dump header. The kernel object 1241590Srgrimes * directory can be found there and we probably have the kernel 1251590Srgrimes * image still in it. The object directory may also have a kernel 1261590Srgrimes * with debugging info (called kernel.debug). If we have a debug 1271590Srgrimes * kernel, use it. 1281590Srgrimes */ 1291590Srgrimes snprintf(path, sizeof(path), "%s/info.%d", crashdir, nr); 13093440Sdwmalone info = fopen(path, "r"); 1311590Srgrimes if (info == NULL) { 13293440Sdwmalone warn("%s", path); 1331590Srgrimes return; 1341590Srgrimes } 1351590Srgrimes while (fgets(path, sizeof(path), info) != NULL) { 1361590Srgrimes l = strlen(path); 1371590Srgrimes if (l > 0 && path[l - 1] == '\n') 1381590Srgrimes path[--l] = '\0'; 1391590Srgrimes if (strncmp(path, " ", 4) == 0) { 1401590Srgrimes s = strchr(path, ':'); 14198771Sjmallett s = (s == NULL) ? path + 4 : s + 1; 1421590Srgrimes l = snprintf(path, sizeof(path), "%s/kernel.debug", s); 1431590Srgrimes if (stat(path, &st) == -1 || !S_ISREG(st.st_mode)) { 1441590Srgrimes path[l - 6] = '\0'; 1451590Srgrimes if (stat(path, &st) == -1 || 1461590Srgrimes !S_ISREG(st.st_mode)) 1471590Srgrimes break; 1481590Srgrimes } 14998771Sjmallett kernel = strdup(path); 1501590Srgrimes break; 1511590Srgrimes } 1521590Srgrimes } 1531590Srgrimes fclose(info); 1541590Srgrimes} 1551590Srgrimes 1561590Srgrimesstatic void 1571590Srgrimeskgdb_new_objfile(struct objfile *objfile) 1581590Srgrimes{ 1591590Srgrimes static int once = 1; 1601590Srgrimes 1611590Srgrimes kld_new_objfile(objfile); 1621590Srgrimes kgdb_trgt_new_objfile(objfile); 16385632Sschweikh 1641590Srgrimes if (kgdb_new_objfile_chain != NULL) 1651590Srgrimes kgdb_new_objfile_chain(objfile); 16698771Sjmallett 1671590Srgrimes if (once && objfile != NULL && objfile == symfile_objfile) { 1681590Srgrimes /* 1691590Srgrimes * The initial kernel has just been loaded. Start the 1701590Srgrimes * remote target if we have one. 1711590Srgrimes */ 1721590Srgrimes once = 0; 1731590Srgrimes if (remote != NULL) 1741590Srgrimes push_remote_target (remote, 0); 1751590Srgrimes } 1761590Srgrimes} 1771590Srgrimes 1781590Srgrimes/* 1791590Srgrimes * Parse an expression and return its value. If 'quiet' is true, then 1801590Srgrimes * any error messages from the parser are masked. 1811590Srgrimes */ 1821590SrgrimesCORE_ADDR 1831590Srgrimeskgdb_parse_1(const char *exp, int quiet) 1841590Srgrimes{ 1851590Srgrimes struct ui_file *old_stderr; 1861590Srgrimes struct cleanup *old_chain; 1871590Srgrimes struct expression *expr; 1881590Srgrimes struct value *val; 1891590Srgrimes char *s; 1901590Srgrimes CORE_ADDR n; 1911590Srgrimes 19298771Sjmallett old_stderr = gdb_stderr; 1931590Srgrimes if (quiet) 1941590Srgrimes gdb_stderr = parse_gdberr; 1951590Srgrimes n = 0; 1961590Srgrimes s = xstrdup(exp); 1971590Srgrimes old_chain = make_cleanup(xfree, s); 1981590Srgrimes if (gdb_parse_exp_1(&s, NULL, 0, &expr) && *s == '\0') { 1991590Srgrimes make_cleanup(free_current_contents, &expr); 2001590Srgrimes if (gdb_evaluate_expression(expr, &val)) 2011590Srgrimes n = value_as_address(val); 2021590Srgrimes } 2031590Srgrimes do_cleanups(old_chain); 2041590Srgrimes gdb_stderr = old_stderr; 2051590Srgrimes return (n); 2061590Srgrimes} 2071590Srgrimes 2081590Srgrimes#define MSGBUF_SEQ_TO_POS(size, seq) ((seq) % (size)) 2091590Srgrimes 2101590Srgrimesvoid 2111590Srgrimeskgdb_dmesg(void) 2121590Srgrimes{ 2131590Srgrimes CORE_ADDR bufp; 2141590Srgrimes int size, rseq, wseq; 2151590Srgrimes char c; 2161590Srgrimes 2171590Srgrimes /* 2181590Srgrimes * Display the unread portion of the message buffer. This gives the 2191590Srgrimes * user a some initial data to work from. 2201590Srgrimes */ 2211590Srgrimes if (quiet) 22298771Sjmallett return; 22398771Sjmallett bufp = kgdb_parse("msgbufp->msg_ptr"); 2241590Srgrimes size = (int)kgdb_parse("msgbufp->msg_size"); 2251590Srgrimes if (bufp == 0 || size == 0) 2261590Srgrimes return; 2271590Srgrimes rseq = (int)kgdb_parse("msgbufp->msg_rseq"); 2281590Srgrimes wseq = (int)kgdb_parse("msgbufp->msg_wseq"); 2291590Srgrimes rseq = MSGBUF_SEQ_TO_POS(size, rseq); 2301590Srgrimes wseq = MSGBUF_SEQ_TO_POS(size, wseq); 2311590Srgrimes if (rseq == wseq) 2321590Srgrimes return; 2331590Srgrimes 2341590Srgrimes printf("\nUnread portion of the kernel message buffer:\n"); 235228992Suqs while (rseq < wseq) { 2361590Srgrimes read_memory(bufp + rseq, &c, 1); 2371590Srgrimes putchar(c); 2381590Srgrimes rseq++; 2391590Srgrimes if (rseq == size) 2401590Srgrimes rseq = 0; 2411590Srgrimes } 2421590Srgrimes if (c != '\n') 2431590Srgrimes putchar('\n'); 2441590Srgrimes putchar('\n'); 24548566Sbillf} 2461590Srgrimes 2471590Srgrimesstatic void 2481590Srgrimeskgdb_init(char *argv0 __unused) 2491590Srgrimes{ 25048566Sbillf 2511590Srgrimes parse_gdberr = mem_fileopen(); 2521590Srgrimes set_prompt("(kgdb) "); 2531590Srgrimes initialize_kgdb_target(); 2541590Srgrimes initialize_kld_target(); 2551590Srgrimes kgdb_new_objfile_chain = target_new_objfile_hook; 2561590Srgrimes target_new_objfile_hook = kgdb_new_objfile; 25785632Sschweikh} 2581590Srgrimes 2591590Srgrimes/* 2601590Srgrimes * Remote targets can support any number of syntaxes and we want to 2611590Srgrimes * support them all with one addition: we support specifying a device 2621590Srgrimes * node for a serial device without the "/dev/" prefix. 2631590Srgrimes * 2641590Srgrimes * What we do is to stat(2) the existing remote target first. If that 2651590Srgrimes * fails, we try it with "/dev/" prepended. If that succeeds we use 2661590Srgrimes * the resulting path, otherwise we use the original target. If 2671590Srgrimes * either stat(2) succeeds make sure the file is either a character 2681590Srgrimes * device or a FIFO. 2691590Srgrimes */ 2701590Srgrimesstatic void 2711590Srgrimesverify_remote(void) 2721590Srgrimes{ 2731590Srgrimes char path[PATH_MAX]; 2741590Srgrimes struct stat st; 2751590Srgrimes 2761590Srgrimes if (stat(remote, &st) != 0) { 2771590Srgrimes snprintf(path, sizeof(path), "/dev/%s", remote); 2781590Srgrimes if (stat(path, &st) != 0) 2791590Srgrimes return; 2801590Srgrimes free(remote); 2811590Srgrimes remote = strdup(path); 2821590Srgrimes } 2831590Srgrimes if (!S_ISCHR(st.st_mode) && !S_ISFIFO(st.st_mode)) 2841590Srgrimes errx(1, "%s: not a special file, FIFO or socket", remote); 2851590Srgrimes} 2861590Srgrimes 2871590Srgrimesstatic void 2881590Srgrimesadd_arg(struct captured_main_args *args, char *arg) 2891590Srgrimes{ 2901590Srgrimes 29185632Sschweikh args->argc++; 29285632Sschweikh args->argv = reallocf(args->argv, (args->argc + 1) * sizeof(char *)); 2931590Srgrimes if (args->argv == NULL) 29498771Sjmallett err(1, "Out of memory building argument list"); 2951590Srgrimes args->argv[args->argc] = arg; 2961590Srgrimes} 2971590Srgrimes 298125736Sbdeint 299125736Sbdemain(int argc, char *argv[]) 3001590Srgrimes{ 30198771Sjmallett char path[PATH_MAX]; 30298771Sjmallett struct stat st; 3031590Srgrimes struct captured_main_args args; 3041590Srgrimes char *s; 3051590Srgrimes int a, ch; 3061590Srgrimes 3071590Srgrimes dumpnr = -1; 3081590Srgrimes 3091590Srgrimes strlcpy(crashdir, "/var/crash", sizeof(crashdir)); 3101590Srgrimes s = getenv("KGDB_CRASH_DIR"); 3111590Srgrimes if (s != NULL) 3121590Srgrimes strlcpy(crashdir, s, sizeof(crashdir)); 3131590Srgrimes 3141590Srgrimes /* Convert long options into short options. */ 3151590Srgrimes for (a = 1; a < argc; a++) { 3161590Srgrimes s = argv[a]; 3171590Srgrimes if (s[0] == '-') { 31885632Sschweikh s++; 31985632Sschweikh /* Long options take either 1 or 2 dashes. */ 3201590Srgrimes if (s[0] == '-') 3211590Srgrimes s++; 3221590Srgrimes if (strcmp(s, "quiet") == 0) 3231590Srgrimes argv[a] = "-q"; 3241590Srgrimes else if (strcmp(s, "fullname") == 0) 3251590Srgrimes argv[a] = "-f"; 3261590Srgrimes } 3271590Srgrimes } 3281590Srgrimes 3291590Srgrimes quiet = 0; 3308874Srgrimes memset (&args, 0, sizeof args); 3311590Srgrimes args.use_windows = 0; 3328874Srgrimes args.interpreter_p = INTERP_CONSOLE; 3338874Srgrimes args.argv = malloc(sizeof(char *)); 3341590Srgrimes args.argv[0] = argv[0]; 3358874Srgrimes 3361590Srgrimes while ((ch = getopt(argc, argv, "ab:c:d:fn:qr:vw")) != -1) { 3378874Srgrimes switch (ch) { 3381590Srgrimes case 'a': 3391590Srgrimes annotation_level++; 3401590Srgrimes break; 3418874Srgrimes case 'b': 3421590Srgrimes { 34385632Sschweikh int i; 34485632Sschweikh char *p; 3451590Srgrimes 34698771Sjmallett i = strtol (optarg, &p, 0); 34798771Sjmallett if (i == 0 && p == optarg) 34898771Sjmallett warnx("warning: could not set baud rate to `%s'.\n", 3491590Srgrimes optarg); 3501590Srgrimes else 3511590Srgrimes baud_rate = i; 3521590Srgrimes } 3531590Srgrimes break; 3541590Srgrimes case 'c': /* use given core file. */ 3551590Srgrimes if (vmcore != NULL) { 3561590Srgrimes warnx("option %c: can only be specified once", 3571590Srgrimes optopt); 3581590Srgrimes usage(); 3591590Srgrimes /* NOTREACHED */ 36098771Sjmallett } 36198771Sjmallett vmcore = strdup(optarg); 36285632Sschweikh break; 363116390Scharnier case 'd': /* lookup dumps in given directory. */ 364116390Scharnier strlcpy(crashdir, optarg, sizeof(crashdir)); 3651590Srgrimes break; 3661590Srgrimes case 'f': 3671590Srgrimes annotation_level = 1; 3681590Srgrimes break; 3691590Srgrimes case 'n': /* use dump with given number. */ 3701590Srgrimes dumpnr = strtol(optarg, &s, 0); 3711590Srgrimes if (dumpnr < 0 || *s != '\0') { 3721590Srgrimes warnx("option %c: invalid kernel dump number", 3731590Srgrimes optopt); 3741590Srgrimes usage(); 3751590Srgrimes /* NOTREACHED */ 3761590Srgrimes } 3771590Srgrimes break; 3781590Srgrimes case 'q': 3791590Srgrimes quiet = 1; 3801590Srgrimes add_arg(&args, "-q"); 3811590Srgrimes break; 3821590Srgrimes case 'r': /* use given device for remote session. */ 3831590Srgrimes if (remote != NULL) { 3841590Srgrimes warnx("option %c: can only be specified once", 3851590Srgrimes optopt); 3861590Srgrimes usage(); 3871590Srgrimes /* NOTREACHED */ 3881590Srgrimes } 3891590Srgrimes remote = strdup(optarg); 3901590Srgrimes break; 3911590Srgrimes case 'v': /* increase verbosity. */ 3921590Srgrimes verbose++; 3931590Srgrimes break; 3941590Srgrimes case 'w': /* core file is writeable. */ 3951590Srgrimes add_arg(&args, "--write"); 3961590Srgrimes break; 3971590Srgrimes case '?': 3981590Srgrimes default: 3991590Srgrimes usage(); 40085632Sschweikh } 4011590Srgrimes } 4021590Srgrimes 4031590Srgrimes if (((vmcore != NULL) ? 1 : 0) + ((dumpnr >= 0) ? 1 : 0) + 4041590Srgrimes ((remote != NULL) ? 1 : 0) > 1) { 40585632Sschweikh warnx("options -c, -n and -r are mutually exclusive"); 4061590Srgrimes usage(); 4071590Srgrimes /* NOTREACHED */ 4081590Srgrimes } 4091590Srgrimes 4101590Srgrimes if (verbose > 1) 4111590Srgrimes warnx("using %s as the crash directory", crashdir); 4121590Srgrimes 4131590Srgrimes if (argc > optind) 4141590Srgrimes kernel = strdup(argv[optind++]); 4151590Srgrimes 4161590Srgrimes if (argc > optind && (dumpnr >= 0 || remote != NULL)) { 4171590Srgrimes warnx("options -n and -r do not take a core file. Ignored"); 4181590Srgrimes optind = argc; 4191590Srgrimes } 4201590Srgrimes 4211590Srgrimes if (dumpnr >= 0) { 4221590Srgrimes snprintf(path, sizeof(path), "%s/vmcore.%d", crashdir, dumpnr); 4231590Srgrimes if (stat(path, &st) == -1) 4241590Srgrimes err(1, "%s", path); 4251590Srgrimes if (!S_ISREG(st.st_mode)) 4261590Srgrimes errx(1, "%s: not a regular file", path); 4271590Srgrimes vmcore = strdup(path); 4281590Srgrimes } else if (remote != NULL) { 4291590Srgrimes verify_remote(); 4301590Srgrimes } else if (argc > optind) { 4311590Srgrimes if (vmcore == NULL) 4328874Srgrimes vmcore = strdup(argv[optind++]); 4331590Srgrimes if (argc > optind) 4348874Srgrimes warnx("multiple core files specified. Ignored"); 4358874Srgrimes } else if (vmcore == NULL && kernel == NULL) { 4361590Srgrimes vmcore = strdup(_PATH_MEM); 4378874Srgrimes kernel = strdup(getbootfile()); 4381590Srgrimes } 4391590Srgrimes 4408874Srgrimes if (verbose) { 4411590Srgrimes if (vmcore != NULL) 4428874Srgrimes warnx("core file: %s", vmcore); 4431590Srgrimes if (remote != NULL) 4441590Srgrimes warnx("device file: %s", remote); 4458874Srgrimes if (kernel != NULL) 4461590Srgrimes warnx("kernel image: %s", kernel); 4471590Srgrimes } 4488874Srgrimes 4491590Srgrimes /* A remote target requires an explicit kernel argument. */ 4508874Srgrimes if (remote != NULL && kernel == NULL) { 4511590Srgrimes warnx("remote debugging requires a kernel"); 4528874Srgrimes usage(); 4531590Srgrimes /* NOTREACHED */ 4548874Srgrimes } 4551590Srgrimes 4568874Srgrimes /* If we don't have a kernel image yet, try to find one. */ 4571590Srgrimes if (kernel == NULL) { 45885632Sschweikh if (dumpnr >= 0) 45985632Sschweikh kernel_from_dumpnr(dumpnr); 46085632Sschweikh 4611590Srgrimes if (kernel == NULL) 4621590Srgrimes errx(1, "couldn't find a suitable kernel image"); 46385632Sschweikh if (verbose) 46485632Sschweikh warnx("kernel image: %s", kernel); 4651590Srgrimes } 46698771Sjmallett add_arg(&args, kernel); 46798771Sjmallett 4681590Srgrimes if (vmcore != NULL) 4691590Srgrimes add_arg(&args, vmcore); 4701590Srgrimes 4711590Srgrimes /* The libgdb code uses optind too. Reset it... */ 4721590Srgrimes optind = 0; 4731590Srgrimes 4741590Srgrimes /* Terminate argv list. */ 475131184Sschweikh add_arg(&args, NULL); 476131184Sschweikh 477131184Sschweikh init_ui_hook = kgdb_init; 478131184Sschweikh 479131184Sschweikh kgdb_sniffer_kluge = kgdb_trgt_trapframe_sniffer; 480131184Sschweikh 481131184Sschweikh return (gdb_main(&args)); 4821590Srgrimes} 4831590Srgrimes