crasher.c revision 0f6c8313b78b9bc292a36388b23436d0e71a8fd9
1/* This program should crash and produce coredump */
2
3#include <stdio.h>
4#include <stdint.h>
5#include <stdlib.h>
6#include <unistd.h>
7#ifdef __FreeBSD__
8#include <sys/types.h>
9#include <sys/sysctl.h>
10#include <sys/user.h>
11#endif
12
13void a(void) __attribute__((noinline));
14void b(int x) __attribute__((noinline));
15
16#if defined(__linux__)
17void write_maps(char *fname)
18{
19    char buf[512], path[128];
20    char exec;
21    uintmax_t addr;
22    FILE *maps = fopen("/proc/self/maps", "r");
23    FILE *out = fopen(fname, "w");
24
25    if (!maps || !out)
26        exit(EXIT_FAILURE);
27
28    while (fgets(buf, sizeof(buf), maps))
29    {
30        if (sscanf(buf, "%jx-%*jx %*c%*c%c%*c %*x %*s %*d /%126[^\n]", &addr, &exec, path+1) != 3)
31            continue;
32
33        if (exec != 'x')
34            continue;
35
36        path[0] = '/';
37        fprintf(out, "0x%jx:%s ", addr, path);
38    }
39    fprintf(out, "\n");
40
41    fclose(out);
42    fclose(maps);
43}
44#elif defined(__FreeBSD__)
45void
46write_maps(char *fname)
47{
48    FILE *out;
49    char *buf, *bp, *eb;
50    struct kinfo_vmentry *kv;
51    int mib[4], error;
52    size_t len;
53
54    out = fopen(fname, "w");
55    if (out == NULL)
56        exit(EXIT_FAILURE);
57
58    len = 0;
59    mib[0] = CTL_KERN;
60    mib[1] = KERN_PROC;
61    mib[2] = KERN_PROC_VMMAP;
62    mib[3] = getpid();
63    error = sysctl(mib, 4, NULL, &len, NULL, 0);
64    if (error == -1)
65	exit(EXIT_FAILURE);
66    len = len * 4 / 3;
67    buf = malloc(len);
68    if (buf == NULL)
69	exit(EXIT_FAILURE);
70    error = sysctl(mib, 4, buf, &len, NULL, 0);
71    if (error == -1)
72	    exit(EXIT_FAILURE);
73
74    for (bp = buf, eb = buf + len; bp < eb; bp += kv->kve_structsize) {
75        kv = (struct kinfo_vmentry *)(uintptr_t)bp;
76	if (kv->kve_type == KVME_TYPE_VNODE &&
77	  (kv->kve_protection & KVME_PROT_EXEC) != 0) {
78	    fprintf(out, "0x%jx:%s ", kv->kve_start, kv->kve_path);
79	}
80    }
81
82    fprintf(out, "\n");
83    fclose(out);
84    free(buf);
85}
86#else
87#error Port me
88#endif
89
90void a(void)
91{
92  *(int *)NULL = 42;
93}
94
95void b(int x)
96{
97  if (x)
98    a();
99  else
100    b(1);
101}
102
103int
104main (int argc, char **argv)
105{
106  if (argc > 1)
107      write_maps(argv[1]);
108  b(0);
109  return 0;
110}
111
112