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