X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=snapshot.cc;h=2440b6e8bda8a06afa040475266e69d02094981e;hb=843f65d8af9e9b4c73f844ecc2a22fbafaee7967;hp=01e720113077ace8833d15a8b22849c6ce01c777;hpb=5a17bbf61bfd4cbf0c23a0c8183910943f02b79b;p=c11tester.git diff --git a/snapshot.cc b/snapshot.cc index 01e72011..2440b6e8 100644 --- a/snapshot.cc +++ b/snapshot.cc @@ -18,8 +18,8 @@ #include //extern declaration definition -#define FAILURE(mesg) { printf("failed in the API: %s with errno relative message: %s\n", mesg, strerror( errno ) ); exit( -1 ); } -#if USE_CHECKPOINTING +#define FAILURE(mesg) { printf("failed in the API: %s with errno relative message: %s\n", mesg, strerror( errno ) ); exit(EXIT_FAILURE); } +#if USE_MPROTECT_SNAPSHOT struct SnapShot * snapshotrecord = NULL; struct Snapshot_t * sTheRecord = NULL; #else @@ -37,13 +37,13 @@ void DumpIntoLog( const char * filename, const char * message ){ myFile = NULL; #endif } -#if !USE_CHECKPOINTING +#if !USE_MPROTECT_SNAPSHOT static ucontext_t savedSnapshotContext; static ucontext_t savedUserSnapshotContext; static snapshot_id snapshotid = 0; #endif /* Initialize snapshot data structure */ -#if USE_CHECKPOINTING +#if USE_MPROTECT_SNAPSHOT void initSnapShotRecord(unsigned int numbackingpages, unsigned int numsnapshots, unsigned int nummemoryregions) { snapshotrecord=( struct SnapShot * )MYMALLOC(sizeof(struct SnapShot)); snapshotrecord->regionsToSnapShot=( struct MemoryRegion * )MYMALLOC(sizeof(struct MemoryRegion)*nummemoryregions); @@ -62,12 +62,13 @@ void initSnapShotRecord(unsigned int numbackingpages, unsigned int numsnapshots, #endif //nothing to initialize for the fork based snapshotting. void HandlePF( int sig, siginfo_t *si, void * unused){ -#if USE_CHECKPOINTING +#if USE_MPROTECT_SNAPSHOT if( si->si_code == SEGV_MAPERR ){ printf("Real Fault at %p\n", si->si_addr); exit( EXIT_FAILURE ); } void* addr = ReturnPageAlignedAddress(si->si_addr); + unsigned int backingpage=snapshotrecord->lastBackingPage++; //Could run out of pages... if (backingpage==snapshotrecord->maxBackingPages) { printf("Out of backing pages at %p\n", si->si_addr); @@ -101,7 +102,7 @@ void * PageAlignAddressUpward(void * addr) { extern "C" { #endif void createSharedLibrary(){ -#if !USE_CHECKPOINTING +#if !USE_MPROTECT_SNAPSHOT //step 1. create shared memory. if( sTheRecord ) return; int fd = shm_open( "/ModelChecker-Snapshotter", O_RDWR | O_CREAT, 0777 ); //universal permissions. @@ -115,13 +116,16 @@ extern "C" { sTheRecord->mStackSize = STACK_SIZE_DEFAULT; sTheRecord->mIDToRollback = -1; sTheRecord->currSnapShotID = 0; + sTheRecord->mbFinalize = false; #endif } #ifdef __cplusplus } #endif -void initSnapShotLibrary(unsigned int numbackingpages, unsigned int numsnapshots, unsigned int nummemoryregions, unsigned int numheappages, MyFuncPtr entryPoint){ -#if USE_CHECKPOINTING +void initSnapShotLibrary(unsigned int numbackingpages, + unsigned int numsnapshots, unsigned int nummemoryregions, + unsigned int numheappages, VoidFuncPtr entryPoint) { +#if USE_MPROTECT_SNAPSHOT /* Setup a stack for our signal handler.... */ stack_t ss; ss.ss_sp = MYMALLOC(SIGSTACKSIZE); @@ -133,27 +137,39 @@ void initSnapShotLibrary(unsigned int numbackingpages, unsigned int numsnapshots sa.sa_flags = SA_SIGINFO | SA_NODEFER | SA_RESTART | SA_ONSTACK; sigemptyset( &sa.sa_mask ); sa.sa_sigaction = HandlePF; +#ifdef MAC + if( sigaction( SIGBUS, &sa, NULL ) == -1 ){ + printf("SIGACTION CANNOT BE INSTALLED\n"); + exit(EXIT_FAILURE); + } +#endif if( sigaction( SIGSEGV, &sa, NULL ) == -1 ){ printf("SIGACTION CANNOT BE INSTALLED\n"); - exit(-1); + exit(EXIT_FAILURE); } + initSnapShotRecord(numbackingpages, numsnapshots, nummemoryregions); + // EVIL HACK: We need to make sure that calls into the HandlePF method don't cause dynamic links + // The problem is that we end up protecting state in the dynamic linker... + // Solution is to call our signal handler before we start protecting stuff... + + siginfo_t si; + si.si_addr=ss.ss_sp; + si.si_code = 0; + HandlePF(SIGSEGV, &si, NULL); + snapshotrecord->lastBackingPage--; //remove the fake page we copied + basemySpace=MYMALLOC((numheappages+1)*PAGESIZE); void * pagealignedbase=PageAlignAddressUpward(basemySpace); mySpace = create_mspace_with_base(pagealignedbase, numheappages*PAGESIZE, 1 ); addMemoryRegionToSnapShot(pagealignedbase, numheappages); entryPoint(); #else - //add a signal to indicate that the process is going to terminate. - struct sigaction sa; - sa.sa_flags = SA_SIGINFO | SA_NODEFER | SA_RESTART; - sigemptyset( &sa.sa_mask ); - sa.sa_sigaction = HandlePF; - if( sigaction( SIGUSR1, &sa, NULL ) == -1 ){ - printf("SIGACTION CANNOT BE INSTALLED\n"); - exit(-1); - } + + basemySpace=system_malloc((numheappages+1)*PAGESIZE); + void * pagealignedbase=PageAlignAddressUpward(basemySpace); + mySpace = create_mspace_with_base(pagealignedbase, numheappages*PAGESIZE, 1 ); createSharedLibrary(); //step 2 setup the stack context. @@ -203,7 +219,7 @@ void initSnapShotLibrary(unsigned int numbackingpages, unsigned int numsnapshots } while( -1 == retVal && errno == EINTR ); if( sTheRecord->mIDToRollback != snapshotid ) - exit(0); + exit(EXIT_SUCCESS); else{ swapContext = true; } @@ -214,11 +230,11 @@ void initSnapShotLibrary(unsigned int numbackingpages, unsigned int numsnapshots } /* This function assumes that addr is page aligned */ void addMemoryRegionToSnapShot( void * addr, unsigned int numPages) { -#if USE_CHECKPOINTING +#if USE_MPROTECT_SNAPSHOT unsigned int memoryregion=snapshotrecord->lastRegion++; if (memoryregion==snapshotrecord->maxRegions) { printf("Exceeded supported number of memory regions!\n"); - exit(-1); + exit(EXIT_FAILURE); } snapshotrecord->regionsToSnapShot[ memoryregion ].basePtr=addr; @@ -227,18 +243,18 @@ void addMemoryRegionToSnapShot( void * addr, unsigned int numPages) { } //take snapshot snapshot_id takeSnapshot( ){ -#if USE_CHECKPOINTING +#if USE_MPROTECT_SNAPSHOT for(unsigned int region=0; regionlastRegion;region++) { if( mprotect(snapshotrecord->regionsToSnapShot[region].basePtr, snapshotrecord->regionsToSnapShot[region].sizeInPages*sizeof(struct SnapShotPage), PROT_READ ) == -1 ){ perror("mprotect"); printf("Failed to mprotect inside of takeSnapShot\n"); - exit(-1); + exit(EXIT_FAILURE); } } unsigned int snapshot=snapshotrecord->lastSnapShot++; if (snapshot==snapshotrecord->maxSnapShots) { printf("Out of snapshots\n"); - exit(-1); + exit(EXIT_FAILURE); } snapshotrecord->snapShots[snapshot].firstBackingPage=snapshotrecord->lastBackingPage; @@ -249,13 +265,13 @@ snapshot_id takeSnapshot( ){ #endif } void rollBack( snapshot_id theID ){ -#if USE_CHECKPOINTING +#if USE_MPROTECT_SNAPSHOT std::map< void *, bool, std::less< void * >, MyAlloc< std::pair< const void *, bool > > > duplicateMap; for(unsigned int region=0; regionlastRegion;region++) { if( mprotect(snapshotrecord->regionsToSnapShot[region].basePtr, snapshotrecord->regionsToSnapShot[region].sizeInPages*sizeof(struct SnapShotPage), PROT_READ | PROT_WRITE ) == -1 ){ perror("mprotect"); printf("Failed to mprotect inside of takeSnapShot\n"); - exit(-1); + exit(EXIT_FAILURE); } } for(unsigned int page=snapshotrecord->snapShots[theID].firstBackingPage; pagelastBackingPage; page++) { @@ -282,13 +298,13 @@ void rollBack( snapshot_id theID ){ #if SSDEBUG DumpIntoLog( "ModelSnapshot", "Invoked rollback" ); #endif - exit( 0 ); + exit(EXIT_SUCCESS); } #endif } void finalize(){ -#if !USE_CHECKPOINTING +#if !USE_MPROTECT_SNAPSHOT sTheRecord->mbFinalize = true; #endif }