DF-5535 / dumpchk.c
/* * dumpchk.c - check whether physical pages made it into a DragonFly * amd64 minidump (as saved by savecore to vmcore.N). * * usage: dumpchk <vmcore-file> <pa> [<pa> ...] * * Prints SET (page in dump bitmap) or CLEAR (page missing) for each pa. */ #include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <inttypes.h> struct mdhdr2 { char magic[24]; uint32_t version; uint32_t unused01; uint64_t msgbufsize; uint64_t bitmapsize; uint64_t ptesize; uint64_t kernbase; uint64_t dmapbase; uint64_t dmapend; }; int main(int argc, char **argv) { FILE *f; unsigned char hdr[512], page[4096]; struct mdhdr2 *md; uint64_t bitmap_off; unsigned char *bm; long bmsz; int i; if (argc < 3) { fprintf(stderr, "usage: %s vmcore pa...\n", argv[0]); return (2); } f = fopen(argv[1], "rb"); if (!f) { perror(argv[1]); return (2); } if (fread(page, 1, 4096, f) != 4096) { fprintf(stderr, "short mdhdr page\n"); return (2); } if (memcmp(page, "minidump DFlyBSD/x86-64", 24) != 0) { /* maybe the kerneldumpheader prefix was kept: skip it */ if (fseek(f, 512, SEEK_SET) != 0 || fread(page, 1, 4096, f) != 4096 || memcmp(page, "minidump DFlyBSD/x86-64", 24) != 0) { fprintf(stderr, "bad minidump magic: %.24s\n", page); return (2); } } md = (struct mdhdr2 *)(void *)page; if (memcmp(md->magic, "minidump DFlyBSD/x86-64", 24) != 0) { fprintf(stderr, "bad minidump magic: %.24s\n", md->magic); return (2); } printf("minidump: version=%u msgbufsize=%" PRIu64 " bitmapsize=%" PRIu64 " ptesize=%" PRIu64 "\n", md->version, md->msgbufsize, md->bitmapsize, md->ptesize); bmsz = (long)md->bitmapsize; bm = malloc(bmsz); if (!bm) { perror("malloc"); return (2); } /* file position now after kdh(512) + mdhdr page(4096) */ bitmap_off = ftell(f); /* then msgbuf, rounded to page */ if (fseek(f, (md->msgbufsize + 4095) & ~4095UL, SEEK_CUR) != 0) { perror("seek msgbuf"); return (2); } if (fread(bm, 1, bmsz, f) != (size_t)bmsz) { fprintf(stderr, "short bitmap read\n"); return (2); } printf("bitmap at file offset %" PRIu64 " (%ld bytes)\n", (uint64_t)(bitmap_off + ((md->msgbufsize + 4095) & ~4095UL)), bmsz); for (i = 2; i < argc; i++) { uint64_t pa = strtoull(argv[i], NULL, 0); uint64_t pg = pa >> 12; uint64_t word = pg >> 6; int bit = (int)(pg & 63); /* little-endian: byte word*8 + bit/8, bit bit&7 */ int set = (bm[word * 8 + (bit >> 3)] >> (bit & 7)) & 1; printf("pa 0x%09" PRIx64 " (page %" PRIu64 "): %s\n", pa, pg, set ? "SET (in dump)" : "CLEAR (MISSING from dump)"); } return (0); } |