--- crash-4.0-4.2/main.c 2007-06-20 16:13:33.000000000 -0400 +++ crash-4.0-4.3/main.c 2007-06-14 17:18:48.000000000 -0400 @@ -1002,6 +1002,9 @@ if (pc->flags & PLEASE_WAIT) sprintf(&buf[strlen(buf)], "%sPLEASE_WAIT", others++ ? "|" : ""); + if (pc->flags & IFILE_ERROR) + sprintf(&buf[strlen(buf)], + "%sIFILE_ERROR", others++ ? "|" : ""); if (pc->flags) strcat(buf, ")"); @@ -1065,6 +1068,20 @@ fprintf(fp, " ifile_pipe: %lx\n", (ulong)pc->ifile_pipe); fprintf(fp, " ifile_ofile: %lx\n", (ulong)pc->ifile_ofile); fprintf(fp, " input_file: %s\n", pc->input_file); + fprintf(fp, "ifile_in_progress: %lx (", pc->ifile_in_progress); + others = 0; + if (pc->ifile_in_progress & RCHOME_IFILE) + fprintf(fp, "%sRCHOME_IFILE", others++ ? "|" : ""); + if (pc->ifile_in_progress & RCLOCAL_IFILE) + fprintf(fp, "%sRCLOCAL_IFILE", others++ ? "|" : ""); + if (pc->ifile_in_progress & CMDLINE_IFILE) + fprintf(fp, "%sCMDLINE_IFILE", others++ ? "|" : ""); + if (pc->ifile_in_progress & RUNTIME_IFILE) + fprintf(fp, "%sRUNTIME_IFILE", others++ ? "|" : ""); + fprintf(fp, ")\n"); + fprintf(fp, " ifile_offset: %lld\n", (ulonglong)pc->ifile_offset); + fprintf(fp, "runtime_ifile_cmd: %s\n", pc->runtime_ifile_cmd ? + pc->runtime_ifile_cmd : "(unused)"); fprintf(fp, " scroll_command: %s\n", pc->scroll_command == SCROLL_NONE ? "(none)" : pc->scroll_command == SCROLL_LESS ? --- crash-4.0-4.2/memory.c 2007-06-20 16:13:33.000000000 -0400 +++ crash-4.0-4.3/memory.c 2007-06-20 13:12:48.000000000 -0400 @@ -5786,7 +5786,7 @@ zone_start_paddr = PTOB(zone_start_pfn); if (!VALID_MEMBER(zone_zone_mem_map)) { - if (IS_SPARSEMEM()) { + if (IS_SPARSEMEM() || IS_DISCONTIGMEM()) { zone_mem_map = 0; if (size) { phys = PTOB(zone_start_pfn); --- crash-4.0-4.2/filesys.c 2007-06-20 16:13:33.000000000 -0400 +++ crash-4.0-4.3/filesys.c 2007-06-13 16:17:43.000000000 -0400 @@ -230,7 +230,7 @@ static void match_proc_version(void) { - char buffer[BUFSIZE]; + char buffer[BUFSIZE], *p1, *p2; if (pc->flags & KERNEL_DEBUG_QUERY) return; @@ -250,6 +250,24 @@ pc->namelist, strlen(pc->namelist) > 39 ? "\n " : " "); + /* + * find_booted_system_map() requires VTOP(), which used to be a + * hardwired masking of the kernel address. But some architectures + * may not know what their physical base address is at this point, + * and others may have different machdep->kvbase values, so for all + * but the 0-based kernel virtual address architectures, bail out + * here with a relevant error message. + */ + if (!machine_type("S390") && !machine_type("S390X")) { + p1 = &kt->proc_version[strlen("Linux version ")]; + p2 = strstr(p1, " "); + *p2 = NULLCHAR; + error(WARNING, "/proc/version indicates kernel version: %s\n", p1); + error(FATAL, "please use the vmlinux file for that kernel version, or try using\n" + " the System.map for that kernel version as an additional argument.\n", p1); + clean_exit(1); + } + if (find_booted_system_map()) pc->flags |= SYSMAP; } --- crash-4.0-4.2/cmdline.c 2007-06-20 16:13:33.000000000 -0400 +++ crash-4.0-4.3/cmdline.c 2007-06-14 17:18:48.000000000 -0400 @@ -70,8 +70,35 @@ * program invocation. * 4. from a terminal. * 5. from a pipe, if stdin is a pipe rather than a terminal. + * + * But first, handle the interruption of an input file caused + * by a FATAL error in one of its commands. + * */ - if (pc->flags & RCHOME_IFILE) { + if (pc->ifile_in_progress) { + switch (pc->ifile_in_progress) + { + case RCHOME_IFILE: + pc->flags |= INIT_IFILE|RCHOME_IFILE; + sprintf(pc->command_line, "< %s/.%src", + pc->home, pc->program_name); + break; + case RCLOCAL_IFILE: + sprintf(pc->command_line, "< .%src", pc->program_name); + pc->flags |= INIT_IFILE|RCLOCAL_IFILE; + break; + case CMDLINE_IFILE: + sprintf(pc->command_line, "< %s", pc->input_file); + pc->flags |= INIT_IFILE|CMDLINE_IFILE; + break; + case RUNTIME_IFILE: + sprintf(pc->command_line, "%s", pc->runtime_ifile_cmd); + pc->flags |= IFILE_ERROR; + break; + default: + error(FATAL, "invalid input file\n"); + } + } else if (pc->flags & RCHOME_IFILE) { sprintf(pc->command_line, "< %s/.%src", pc->home, pc->program_name); pc->flags |= INIT_IFILE; @@ -418,6 +445,9 @@ return REDIRECT_FAILURE; } + if (pc->flags & IFILE_ERROR) + append = TRUE; + if ((ofile = fopen(p, append ? "a+" : "w+")) == NULL) { error(INFO, "unable to open %s\n", p); @@ -923,7 +953,7 @@ wait_for_children(ZOMBIES_ONLY); - pc->flags &= ~(INIT_IFILE|RUNTIME_IFILE|_SIGINT_|PLEASE_WAIT); + pc->flags &= ~(INIT_IFILE|RUNTIME_IFILE|IFILE_ERROR|_SIGINT_|PLEASE_WAIT); pc->sigint_cnt = 0; pc->redirect = 0; pc->pipe_command[0] = NULLCHAR; @@ -983,6 +1013,8 @@ { int fd; + pc->flags &= ~IFILE_ERROR; + if (pc->ifile_pipe) { close(fileno(pc->ifile_pipe)); pc->ifile_pipe = NULL; @@ -1098,7 +1130,6 @@ } else this = 0; - if (pc->flags & RUNTIME_IFILE) { error(INFO, "embedded input files not allowed!\n"); return; @@ -1133,6 +1164,28 @@ pc->flags |= RUNTIME_IFILE; incoming_fp = fp; + /* + * Handle runtime commands that use input files. + */ + if ((pc->ifile_in_progress = this) == 0) { + if (!pc->runtime_ifile_cmd) { + if (!(pc->runtime_ifile_cmd = (char *)malloc(BUFSIZE))) { + error(INFO, + "cannot malloc input file command line buffer\n"); + return; + } + } + strcpy(pc->runtime_ifile_cmd, pc->orig_line); + pc->ifile_in_progress = RUNTIME_IFILE; + } + + /* + * If there's an offset, then there was a FATAL error caused + * by the last command executed from the input file. + */ + if (pc->ifile_offset) + fseek(pc->ifile, (long)pc->ifile_offset, SEEK_SET); + while (fgets(buf, BUFSIZE-1, pc->ifile)) { /* * Restore normal environment. @@ -1142,6 +1195,8 @@ BZERO(pc->command_line, BUFSIZE); BZERO(pc->orig_line, BUFSIZE); + pc->ifile_offset = ftell(pc->ifile); + if (STRNEQ(buf, "#") || STREQ(buf, "\n")) continue; @@ -1190,6 +1245,10 @@ fclose(pc->ifile); pc->ifile = NULL; pc->flags &= ~RUNTIME_IFILE; + pc->ifile_offset = 0; + if (pc->runtime_ifile_cmd) + BZERO(pc->runtime_ifile_cmd, BUFSIZE); + pc->ifile_in_progress = 0; } /* --- crash-4.0-4.2/defs.h 2007-06-20 16:13:33.000000000 -0400 +++ crash-4.0-4.3/defs.h 2007-06-14 17:18:16.000000000 -0400 @@ -177,6 +177,7 @@ #define XEN_HYPER (0x80000000000000ULL) #define XEN_CORE (0x100000000000000ULL) #define PLEASE_WAIT (0x200000000000000ULL) +#define IFILE_ERROR (0x400000000000000ULL) #define ACTIVE() (pc->flags & LIVE_SYSTEM) #define DUMPFILE() (!(pc->flags & LIVE_SYSTEM)) @@ -385,6 +386,9 @@ struct extension_table *curext; /* extension being loaded */ int (*readmem)(int, void *, int, ulong, physaddr_t); /* memory access */ int (*writemem)(int, void *, int, ulong, physaddr_t);/* memory access */ + ulong ifile_in_progress; /* original xxx_IFILE flags */ + off_t ifile_offset; /* current offset into input file */ + char *runtime_ifile_cmd; /* runtime command using input file */ }; #define READMEM pc->readmem