// swap_testing2.c // Built via (c++ was clang++ 4.0 in my case): // // cc -g -std=c11 -Wpedantic -o swaptesting2 swap_testing2.c // -O0 and -O2 also gets the problem. #include // for fork(), sleep(.) #include // for pid_t #include // for wait(.) #include // for raise(.), SIGABRT extern void test_setup(void); // Sets up the memory byte patterns. extern void test_check(void); // Tests the memory byte patterns. extern void partial_test_check(void); // Tests just [0] of dyn_regions[0] int main(void) { test_setup(); test_check(); // Before fork() [passes] pid_t pid = fork(); int wait_status = 0;; // After fork; before waitsleep/swap-out. //if (0==pid) partial_test_check(); // Even the above is sufficient by // itself to prevent failure for // region_size 1u through // 4u*1024u! // But 4u*1024u+1u and above fail // with this access to memory. // The failing test is of // (*dyn_regions[0]).array[4096u]. // This test never fails here. if (0 // for size_t, NULL #include // for malloc(.), free(.) #define region_size (14u*1024u) // Bad dyn_regions patterns, parent and child // processes: // 256u, 2u*1024u, 4u*1024u, 8u*1024u, // 9u*1024u, 12u*1024u, 14u*1024u // (but see the partial_test_check() call // notes above). // Works: // 14u*1024u+1u, 15u*1024u, 16u*1024u, // 32u*1024u, 256u*1024u*1024u #define num_regions (256u*1024u*1024u/region_size) typedef volatile unsigned char value_type; struct region_struct { value_type array[region_size]; }; typedef struct region_struct region; static region * volatile dyn_regions[num_regions] = {NULL,}; static value_type value(size_t v) { return (value_type)((v&0xFEu)|0x1u); } // value now avoids the zero value since the failures // are zeros. void test_setup(void) { for(size_t i=0u; i