• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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__)
write_maps(char * fname)16 void 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__)
44 void
write_maps(char * fname)45 write_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__
90 #ifndef __clang__
91 // Gcc >= 8 became too good at inlining aliase c into b when using -O2 or -O3,
92 // so force -O1 in all cases, otherwise a frame will be missing in the tests.
93 #pragma GCC optimize "-O1"
94 #endif
95 int c(int x) NOINLINE ALIAS(b);
96 #define compiler_barrier() __asm__ __volatile__ ("");
97 #else
98 int c(int x);
99 #define compiler_barrier()
100 #endif
101 
a(void)102 int NOINLINE a(void)
103 {
104   *(volatile int *)32 = 1;
105   return 1;
106 }
107 
b(int x)108 int NOINLINE b(int x)
109 {
110   int r;
111 
112   compiler_barrier();
113 
114   if (x)
115     r = a();
116   else
117     r = c(1);
118   return r + 1;
119 }
120 
121 int
main(int argc,char ** argv)122 main (int argc, char **argv)
123 {
124   if (argc > 1)
125       write_maps(argv[1]);
126   b(0);
127   return 0;
128 }
129 
130