1/* 2 * Copyright (c) 2004 Marcel Moolenaar 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h>
| 1/* 2 * Copyright (c) 2004 Marcel Moolenaar 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h>
|
28__FBSDID("$FreeBSD: head/gnu/usr.bin/gdb/kgdb/main.c 137993 2004-11-22 16:08:19Z joerg $");
| 28__FBSDID("$FreeBSD: head/gnu/usr.bin/gdb/kgdb/main.c 142151 2005-02-20 22:55:07Z kan $");
|
29 30#include <sys/param.h> 31#include <sys/stat.h> 32#include <sys/types.h> 33#include <sys/ioctl.h> 34#include <sys/resource.h> 35#include <sys/select.h> 36#include <sys/time.h> 37#include <sys/wait.h> 38#include <errno.h> 39#include <err.h> 40#include <fcntl.h> 41#include <inttypes.h> 42#include <kvm.h> 43#include <limits.h> 44#include <paths.h> 45#include <stdio.h> 46#include <stdlib.h> 47#include <string.h> 48#include <unistd.h> 49 50/* libgdb stuff. */ 51#include <defs.h> 52#include <frame.h> 53#include <inferior.h> 54#include <interps.h> 55#include <cli-out.h> 56#include <main.h> 57#include <target.h> 58#include <top.h>
| 29 30#include <sys/param.h> 31#include <sys/stat.h> 32#include <sys/types.h> 33#include <sys/ioctl.h> 34#include <sys/resource.h> 35#include <sys/select.h> 36#include <sys/time.h> 37#include <sys/wait.h> 38#include <errno.h> 39#include <err.h> 40#include <fcntl.h> 41#include <inttypes.h> 42#include <kvm.h> 43#include <limits.h> 44#include <paths.h> 45#include <stdio.h> 46#include <stdlib.h> 47#include <string.h> 48#include <unistd.h> 49 50/* libgdb stuff. */ 51#include <defs.h> 52#include <frame.h> 53#include <inferior.h> 54#include <interps.h> 55#include <cli-out.h> 56#include <main.h> 57#include <target.h> 58#include <top.h>
|
| 59#include <bfd.h> 60#include <gdbcore.h>
|
59 60extern void (*init_ui_hook)(char *); 61 62extern void symbol_file_add_main (char *args, int from_tty); 63 64#include "kgdb.h" 65 66kvm_t *kvm; 67 68static int dumpnr; 69static int verbose; 70 71static char crashdir[PATH_MAX]; 72static char *kernel; 73static char *remote; 74static char *vmcore; 75 76static void (*kgdb_new_objfile_chain)(struct objfile * objfile); 77 78static void 79usage(void) 80{ 81 82 fprintf(stderr, 83 "usage: %s [-a] [-v] [-d crashdir] [-c core | -n dumpnr | -r device]\n" 84 "\t[kernel [core]]\n", getprogname()); 85 exit(1); 86} 87 88static void 89kernel_from_dumpnr(int nr) 90{ 91 char path[PATH_MAX]; 92 FILE *info; 93 char *s; 94 struct stat st; 95 int l; 96 97 /* 98 * If there's a kernel image right here in the crash directory, then 99 * use it. The kernel image is either called kernel.<nr> or is in a 100 * subdirectory kernel.<nr> and called kernel. The latter allows us 101 * to collect the modules in the same place. 102 */ 103 snprintf(path, sizeof(path), "%s/kernel.%d", crashdir, nr); 104 if (stat(path, &st) == 0) { 105 if (S_ISREG(st.st_mode)) { 106 kernel = strdup(path); 107 return; 108 } 109 if (S_ISDIR(st.st_mode)) { 110 snprintf(path, sizeof(path), "%s/kernel.%d/kernel", 111 crashdir, nr); 112 if (stat(path, &st) == 0 && S_ISREG(st.st_mode)) { 113 kernel = strdup(path); 114 return; 115 } 116 } 117 } 118 119 /* 120 * No kernel image here. Parse the dump header. The kernel object 121 * directory can be found there and we probably have the kernel 122 * image still in it. The object directory may also have a kernel 123 * with debugging info (called kernel.debug). If we have a debug 124 * kernel, use it. 125 */ 126 snprintf(path, sizeof(path), "%s/info.%d", crashdir, nr); 127 info = fopen(path, "r"); 128 if (info == NULL) { 129 warn(path); 130 return; 131 } 132 while (fgets(path, sizeof(path), info) != NULL) { 133 l = strlen(path); 134 if (l > 0 && path[l - 1] == '\n') 135 path[--l] = '\0'; 136 if (strncmp(path, " ", 4) == 0) { 137 s = strchr(path, ':'); 138 s = (s == NULL) ? path + 4 : s + 1; 139 l = snprintf(path, sizeof(path), "%s/kernel.debug", s); 140 if (stat(path, &st) == -1 || !S_ISREG(st.st_mode)) { 141 path[l - 6] = '\0'; 142 if (stat(path, &st) == -1 || 143 !S_ISREG(st.st_mode)) 144 break; 145 } 146 kernel = strdup(path); 147 break; 148 } 149 } 150 fclose(info); 151} 152 153static void 154kgdb_new_objfile(struct objfile *objfile) 155{ 156#if 0 157 printf("XXX: %s(%p)\n", __func__, objfile); 158 if (objfile != NULL) { 159 goto out; 160 } 161 162out: 163#endif 164 if (kgdb_new_objfile_chain != NULL) 165 kgdb_new_objfile_chain(objfile); 166} 167 168static void
| 61 62extern void (*init_ui_hook)(char *); 63 64extern void symbol_file_add_main (char *args, int from_tty); 65 66#include "kgdb.h" 67 68kvm_t *kvm; 69 70static int dumpnr; 71static int verbose; 72 73static char crashdir[PATH_MAX]; 74static char *kernel; 75static char *remote; 76static char *vmcore; 77 78static void (*kgdb_new_objfile_chain)(struct objfile * objfile); 79 80static void 81usage(void) 82{ 83 84 fprintf(stderr, 85 "usage: %s [-a] [-v] [-d crashdir] [-c core | -n dumpnr | -r device]\n" 86 "\t[kernel [core]]\n", getprogname()); 87 exit(1); 88} 89 90static void 91kernel_from_dumpnr(int nr) 92{ 93 char path[PATH_MAX]; 94 FILE *info; 95 char *s; 96 struct stat st; 97 int l; 98 99 /* 100 * If there's a kernel image right here in the crash directory, then 101 * use it. The kernel image is either called kernel.<nr> or is in a 102 * subdirectory kernel.<nr> and called kernel. The latter allows us 103 * to collect the modules in the same place. 104 */ 105 snprintf(path, sizeof(path), "%s/kernel.%d", crashdir, nr); 106 if (stat(path, &st) == 0) { 107 if (S_ISREG(st.st_mode)) { 108 kernel = strdup(path); 109 return; 110 } 111 if (S_ISDIR(st.st_mode)) { 112 snprintf(path, sizeof(path), "%s/kernel.%d/kernel", 113 crashdir, nr); 114 if (stat(path, &st) == 0 && S_ISREG(st.st_mode)) { 115 kernel = strdup(path); 116 return; 117 } 118 } 119 } 120 121 /* 122 * No kernel image here. Parse the dump header. The kernel object 123 * directory can be found there and we probably have the kernel 124 * image still in it. The object directory may also have a kernel 125 * with debugging info (called kernel.debug). If we have a debug 126 * kernel, use it. 127 */ 128 snprintf(path, sizeof(path), "%s/info.%d", crashdir, nr); 129 info = fopen(path, "r"); 130 if (info == NULL) { 131 warn(path); 132 return; 133 } 134 while (fgets(path, sizeof(path), info) != NULL) { 135 l = strlen(path); 136 if (l > 0 && path[l - 1] == '\n') 137 path[--l] = '\0'; 138 if (strncmp(path, " ", 4) == 0) { 139 s = strchr(path, ':'); 140 s = (s == NULL) ? path + 4 : s + 1; 141 l = snprintf(path, sizeof(path), "%s/kernel.debug", s); 142 if (stat(path, &st) == -1 || !S_ISREG(st.st_mode)) { 143 path[l - 6] = '\0'; 144 if (stat(path, &st) == -1 || 145 !S_ISREG(st.st_mode)) 146 break; 147 } 148 kernel = strdup(path); 149 break; 150 } 151 } 152 fclose(info); 153} 154 155static void 156kgdb_new_objfile(struct objfile *objfile) 157{ 158#if 0 159 printf("XXX: %s(%p)\n", __func__, objfile); 160 if (objfile != NULL) { 161 goto out; 162 } 163 164out: 165#endif 166 if (kgdb_new_objfile_chain != NULL) 167 kgdb_new_objfile_chain(objfile); 168} 169 170static void
|
| 171kgdb_init_target(void) 172{ 173 bfd *kern_bfd; 174 int kern_desc; 175 176 kern_desc = open(kernel, O_RDONLY); 177 if (kern_desc == -1) 178 errx(1, "couldn't open a kernel image"); 179 180 kern_bfd = bfd_fdopenr(kernel, gnutarget, kern_desc); 181 if (kern_bfd == NULL) { 182 close(kern_desc); 183 errx(1, "\"%s\": can't open to probe ABI: %s.", kernel, 184 bfd_errmsg (bfd_get_error ())); 185 } 186 bfd_set_cacheable(kern_bfd, 1); 187 188 if (!bfd_check_format (kern_bfd, bfd_object)) { 189 bfd_close(kern_bfd); 190 errx(1, "\"%s\": not in executable format: %s", kernel, 191 bfd_errmsg(bfd_get_error())); 192 } 193 194 set_gdbarch_from_file (kern_bfd); 195 bfd_close(kern_bfd); 196 197 symbol_file_add_main (kernel, 0); 198 if (remote) 199 push_remote_target (remote, 0); 200 else 201 kgdb_target(); 202} 203 204static void
|
169kgdb_interp_command_loop(void *data) 170{ 171 static int once = 0; 172 173 if (!once) { 174 once = 1;
| 205kgdb_interp_command_loop(void *data) 206{ 207 static int once = 0; 208 209 if (!once) { 210 once = 1;
|
175 symbol_file_add_main (kernel, 0); 176 if (remote) 177 push_remote_target (remote, 0); 178 else 179 kgdb_target(); 180 print_stack_frame(get_current_frame(), -1, 0);
| 211 kgdb_init_target(); 212 kgdb_target(); 213 print_stack_frame (get_selected_frame (), 214 frame_relative_level (get_selected_frame ()), 1);
|
181 } 182 command_loop(); 183} 184 185static void 186kgdb_init(char *argv0 __unused) 187{ 188 static struct interp_procs procs = { 189 NULL, 190 NULL, 191 NULL, 192 NULL, 193 NULL, 194 kgdb_interp_command_loop 195 }; 196 struct interp *kgdb; 197 kgdb = interp_new("kgdb", NULL, cli_out_new(gdb_stdout), &procs); 198 interp_add(kgdb); 199 200 set_prompt("(kgdb) "); 201 kgdb_new_objfile_chain = target_new_objfile_hook; 202 target_new_objfile_hook = kgdb_new_objfile; 203} 204 205int 206main(int argc, char *argv[]) 207{ 208 char path[PATH_MAX]; 209 struct stat st; 210 struct captured_main_args args; 211 char *s; 212 int ch; 213 214 dumpnr = -1; 215 216 strlcpy(crashdir, "/var/crash", sizeof(crashdir)); 217 s = getenv("KGDB_CRASH_DIR"); 218 if (s != NULL) 219 strlcpy(crashdir, s, sizeof(crashdir)); 220 221 while ((ch = getopt(argc, argv, "ac:d:n:r:v")) != -1) { 222 switch (ch) { 223 case 'a': 224 annotation_level++; 225 break; 226 case 'c': /* use given core file. */ 227 if (vmcore != NULL) { 228 warnx("option %c: can only be specified once", 229 optopt); 230 usage(); 231 /* NOTREACHED */ 232 } 233 vmcore = strdup(optarg); 234 break; 235 case 'd': /* lookup dumps in given directory. */ 236 strlcpy(crashdir, optarg, sizeof(crashdir)); 237 break; 238 case 'n': /* use dump with given number. */ 239 dumpnr = strtol(optarg, &s, 0); 240 if (dumpnr < 0 || *s != '\0') { 241 warnx("option %c: invalid kernel dump number", 242 optopt); 243 usage(); 244 /* NOTREACHED */ 245 } 246 break; 247 case 'r': /* use given device for remote session. */ 248 if (remote != NULL) { 249 warnx("option %c: can only be specified once", 250 optopt); 251 usage(); 252 /* NOTREACHED */ 253 } 254 remote = strdup(optarg); 255 break; 256 case 'v': /* increase verbosity. */ 257 verbose++; 258 break; 259 case '?': 260 default: 261 usage(); 262 } 263 } 264 265 if (((vmcore != NULL) ? 1 : 0) + ((dumpnr >= 0) ? 1 : 0) + 266 ((remote != NULL) ? 1 : 0) > 1) { 267 warnx("options -c, -n and -r are mutually exclusive"); 268 usage(); 269 /* NOTREACHED */ 270 } 271 272 if (verbose > 1) 273 warnx("using %s as the crash directory", crashdir); 274 275 if (argc > optind) 276 kernel = strdup(argv[optind++]); 277 278 if (argc > optind && (dumpnr >= 0 || remote != NULL)) { 279 warnx("options -n and -r do not take a core file. Ignored"); 280 optind = argc; 281 } 282 283 if (dumpnr >= 0) { 284 snprintf(path, sizeof(path), "%s/vmcore.%d", crashdir, dumpnr); 285 if (stat(path, &st) == -1) 286 err(1, path); 287 if (!S_ISREG(st.st_mode)) 288 errx(1, "%s: not a regular file", path); 289 vmcore = strdup(path); 290 } else if (remote != NULL && remote[0] != ':' && remote[0] != '|') { 291 if (stat(remote, &st) != 0) { 292 snprintf(path, sizeof(path), "/dev/%s", remote); 293 if (stat(path, &st) != 0) { 294 err(1, "%s", remote); 295 /* NOTREACHED */ 296 } 297 free(remote); 298 remote = strdup(path); 299 } 300 if (!S_ISCHR(st.st_mode) && !S_ISFIFO(st.st_mode)) { 301 errx(1, "%s: not a special file, FIFO or socket", 302 remote); 303 /* NOTREACHED */ 304 } 305 } else if (argc > optind) { 306 if (vmcore == NULL) 307 vmcore = strdup(argv[optind++]); 308 if (argc > optind) 309 warnx("multiple core files specified. Ignored"); 310 } else if (vmcore == NULL && kernel == NULL) { 311 vmcore = strdup(_PATH_MEM); 312 kernel = strdup(getbootfile()); 313 } 314 315 if (verbose) { 316 if (vmcore != NULL) 317 warnx("core file: %s", vmcore); 318 if (remote != NULL) 319 warnx("device file: %s", remote); 320 if (kernel != NULL) 321 warnx("kernel image: %s", kernel); 322 } 323 324 /* 325 * At this point we must either have a core file or have a kernel 326 * with a remote target. 327 */ 328 if (remote != NULL && kernel == NULL) { 329 warnx("remote debugging requires a kernel"); 330 usage(); 331 /* NOTREACHED */ 332 } 333 if (vmcore == NULL && remote == NULL) { 334 warnx("need a core file or a device for remote debugging"); 335 usage(); 336 /* NOTREACHED */ 337 } 338 339 /* If we don't have a kernel image yet, try to find one. */ 340 if (kernel == NULL) { 341 if (dumpnr >= 0) 342 kernel_from_dumpnr(dumpnr); 343 344 if (kernel == NULL) 345 errx(1, "couldn't find a suitable kernel image"); 346 if (verbose) 347 warnx("kernel image: %s", kernel); 348 } 349 350 if (remote == NULL) { 351 s = malloc(_POSIX2_LINE_MAX); 352 kvm = kvm_openfiles(kernel, vmcore, NULL, O_RDONLY, s); 353 if (kvm == NULL) 354 errx(1, s); 355 free(s); 356 kgdb_thr_init(); 357 } 358 359 memset (&args, 0, sizeof args); 360 args.argc = 1; 361 args.argv = argv; 362 args.use_windows = 0; 363 args.interpreter_p = "kgdb"; 364 365 init_ui_hook = kgdb_init; 366 367 return (gdb_main(&args)); 368}
| 215 } 216 command_loop(); 217} 218 219static void 220kgdb_init(char *argv0 __unused) 221{ 222 static struct interp_procs procs = { 223 NULL, 224 NULL, 225 NULL, 226 NULL, 227 NULL, 228 kgdb_interp_command_loop 229 }; 230 struct interp *kgdb; 231 kgdb = interp_new("kgdb", NULL, cli_out_new(gdb_stdout), &procs); 232 interp_add(kgdb); 233 234 set_prompt("(kgdb) "); 235 kgdb_new_objfile_chain = target_new_objfile_hook; 236 target_new_objfile_hook = kgdb_new_objfile; 237} 238 239int 240main(int argc, char *argv[]) 241{ 242 char path[PATH_MAX]; 243 struct stat st; 244 struct captured_main_args args; 245 char *s; 246 int ch; 247 248 dumpnr = -1; 249 250 strlcpy(crashdir, "/var/crash", sizeof(crashdir)); 251 s = getenv("KGDB_CRASH_DIR"); 252 if (s != NULL) 253 strlcpy(crashdir, s, sizeof(crashdir)); 254 255 while ((ch = getopt(argc, argv, "ac:d:n:r:v")) != -1) { 256 switch (ch) { 257 case 'a': 258 annotation_level++; 259 break; 260 case 'c': /* use given core file. */ 261 if (vmcore != NULL) { 262 warnx("option %c: can only be specified once", 263 optopt); 264 usage(); 265 /* NOTREACHED */ 266 } 267 vmcore = strdup(optarg); 268 break; 269 case 'd': /* lookup dumps in given directory. */ 270 strlcpy(crashdir, optarg, sizeof(crashdir)); 271 break; 272 case 'n': /* use dump with given number. */ 273 dumpnr = strtol(optarg, &s, 0); 274 if (dumpnr < 0 || *s != '\0') { 275 warnx("option %c: invalid kernel dump number", 276 optopt); 277 usage(); 278 /* NOTREACHED */ 279 } 280 break; 281 case 'r': /* use given device for remote session. */ 282 if (remote != NULL) { 283 warnx("option %c: can only be specified once", 284 optopt); 285 usage(); 286 /* NOTREACHED */ 287 } 288 remote = strdup(optarg); 289 break; 290 case 'v': /* increase verbosity. */ 291 verbose++; 292 break; 293 case '?': 294 default: 295 usage(); 296 } 297 } 298 299 if (((vmcore != NULL) ? 1 : 0) + ((dumpnr >= 0) ? 1 : 0) + 300 ((remote != NULL) ? 1 : 0) > 1) { 301 warnx("options -c, -n and -r are mutually exclusive"); 302 usage(); 303 /* NOTREACHED */ 304 } 305 306 if (verbose > 1) 307 warnx("using %s as the crash directory", crashdir); 308 309 if (argc > optind) 310 kernel = strdup(argv[optind++]); 311 312 if (argc > optind && (dumpnr >= 0 || remote != NULL)) { 313 warnx("options -n and -r do not take a core file. Ignored"); 314 optind = argc; 315 } 316 317 if (dumpnr >= 0) { 318 snprintf(path, sizeof(path), "%s/vmcore.%d", crashdir, dumpnr); 319 if (stat(path, &st) == -1) 320 err(1, path); 321 if (!S_ISREG(st.st_mode)) 322 errx(1, "%s: not a regular file", path); 323 vmcore = strdup(path); 324 } else if (remote != NULL && remote[0] != ':' && remote[0] != '|') { 325 if (stat(remote, &st) != 0) { 326 snprintf(path, sizeof(path), "/dev/%s", remote); 327 if (stat(path, &st) != 0) { 328 err(1, "%s", remote); 329 /* NOTREACHED */ 330 } 331 free(remote); 332 remote = strdup(path); 333 } 334 if (!S_ISCHR(st.st_mode) && !S_ISFIFO(st.st_mode)) { 335 errx(1, "%s: not a special file, FIFO or socket", 336 remote); 337 /* NOTREACHED */ 338 } 339 } else if (argc > optind) { 340 if (vmcore == NULL) 341 vmcore = strdup(argv[optind++]); 342 if (argc > optind) 343 warnx("multiple core files specified. Ignored"); 344 } else if (vmcore == NULL && kernel == NULL) { 345 vmcore = strdup(_PATH_MEM); 346 kernel = strdup(getbootfile()); 347 } 348 349 if (verbose) { 350 if (vmcore != NULL) 351 warnx("core file: %s", vmcore); 352 if (remote != NULL) 353 warnx("device file: %s", remote); 354 if (kernel != NULL) 355 warnx("kernel image: %s", kernel); 356 } 357 358 /* 359 * At this point we must either have a core file or have a kernel 360 * with a remote target. 361 */ 362 if (remote != NULL && kernel == NULL) { 363 warnx("remote debugging requires a kernel"); 364 usage(); 365 /* NOTREACHED */ 366 } 367 if (vmcore == NULL && remote == NULL) { 368 warnx("need a core file or a device for remote debugging"); 369 usage(); 370 /* NOTREACHED */ 371 } 372 373 /* If we don't have a kernel image yet, try to find one. */ 374 if (kernel == NULL) { 375 if (dumpnr >= 0) 376 kernel_from_dumpnr(dumpnr); 377 378 if (kernel == NULL) 379 errx(1, "couldn't find a suitable kernel image"); 380 if (verbose) 381 warnx("kernel image: %s", kernel); 382 } 383 384 if (remote == NULL) { 385 s = malloc(_POSIX2_LINE_MAX); 386 kvm = kvm_openfiles(kernel, vmcore, NULL, O_RDONLY, s); 387 if (kvm == NULL) 388 errx(1, s); 389 free(s); 390 kgdb_thr_init(); 391 } 392 393 memset (&args, 0, sizeof args); 394 args.argc = 1; 395 args.argv = argv; 396 args.use_windows = 0; 397 args.interpreter_p = "kgdb"; 398 399 init_ui_hook = kgdb_init; 400 401 return (gdb_main(&args)); 402}
|