Home | History | Annotate | Download | only in tests
      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__)
     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
     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 int c(int x) NOINLINE ALIAS(b);
     91 #define compiler_barrier() asm volatile("");
     92 #else
     93 int c(int x);
     94 #define compiler_barrier()
     95 #endif
     96 
     97 int NOINLINE a(void)
     98 {
     99   *(volatile int *)32 = 1;
    100   return 1;
    101 }
    102 
    103 int 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 
    116 int
    117 main (int argc, char **argv)
    118 {
    119   if (argc > 1)
    120       write_maps(argv[1]);
    121   b(0);
    122   return 0;
    123 }
    124 
    125