DF-5833 / parse_core.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | /* * parse_core.c -- DF-5833 rig: analyze a produced core file. * Prints: e_phnum, PT_NOTE size, NT_PRSTATUS count + list of pr_pid * (lwp_tid) values, and the derived counts the rig needs for tuning. */ #include <sys/types.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct { uint32_t namesz, descsz, type; } Elf64_Nhdr_t; #pragma pack(1) typedef struct { unsigned char e_ident[16]; uint16_t e_type, e_machine; uint32_t e_version; uint64_t e_entry, e_phoff, e_shoff; uint32_t e_flags; uint16_t e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum, e_shstrndx; } Ehdr; typedef struct { uint32_t p_type, p_flags; uint64_t p_offset, p_vaddr, p_paddr, p_filesz, p_memsz, p_align; } Phdr; #pragma pack() int main(int argc, char **argv) { if (argc < 2) { fprintf(stderr, "usage: %s core\n", argv[0]); return (1); } FILE *f = fopen(argv[1], "rb"); if (!f) { perror(argv[1]); return (1); } Ehdr eh; if (fread(&eh, sizeof(eh), 1, f) != 1) { fprintf(stderr, "short read ehdr\n"); return (1); } printf("e_phnum=%u e_phoff=%llu\n", eh.e_phnum, (unsigned long long)eh.e_phoff); Phdr *ph = calloc(eh.e_phnum, sizeof(Phdr)); fseek(f, eh.e_phoff, SEEK_SET); if (fread(ph, sizeof(Phdr), eh.e_phnum, f) != eh.e_phnum) { fprintf(stderr, "short read phdrs\n"); return (1); } int count_prstatus = 0, count_fpreg = 0, count_psinfo = 0; int pids[4096]; int npid = 0; uint64_t note_off = 0, note_sz = 0; for (int i = 0; i < eh.e_phnum; i++) { if (ph[i].p_type != 4) /* PT_NOTE */ continue; note_off = ph[i].p_offset; note_sz = ph[i].p_filesz; unsigned char *buf = malloc(note_sz); fseek(f, note_off, SEEK_SET); if (fread(buf, 1, note_sz, f) != note_sz) { fprintf(stderr, "short read notes\n"); return (1); } uint64_t off = 0; while (off + sizeof(Elf64_Nhdr_t) <= note_sz) { Elf64_Nhdr_t n; memcpy(&n, buf + off, sizeof(n)); uint64_t p = off + sizeof(n); uint64_t namepad = (n.namesz + 3) & ~3ULL; uint64_t descpad = (n.descsz + 3) & ~3ULL; if (p + namepad + n.descsz > note_sz) break; if (n.type == 1) { /* NT_PRSTATUS */ count_prstatus++; /* pr_pid at desc+40 */ int pid; memcpy(&pid, buf + p + namepad + 40, 4); if (npid < 4096) pids[npid++] = pid; } else if (n.type == 2) { count_fpreg++; } else if (n.type == 3) { count_psinfo++; } off = p + namepad + descpad; off = (off + 3) & ~3ULL; } } printf("note_off=%llu note_sz=%llu\n", (unsigned long long)note_off, (unsigned long long)note_sz); printf("NT_PRSTATUS=%d NT_FPREGSET=%d NT_PRPSINFO=%d\n", count_prstatus, count_fpreg, count_psinfo); printf("PIDS:"); for (int i = 0; i < npid; i++) printf(" %d", pids[i]); printf("\n"); return (0); } |