8971169786717cb84201208d565d152d7f80f7cc
[c11tester.git] / snapshot-interface.cc
1 #include "snapshot-interface.h"
2 #include <iostream>
3 #include <fstream>
4 #include <unistd.h>
5 #include <sys/types.h>
6 #include <sstream>
7 #include <cstring>
8 #include <cassert>
9
10 #define MYBINARYNAME "model"
11 #define MYLIBRARYNAME "libmodel.so"
12 #define PROCNAME      "/proc/*/maps"
13 #define REPLACEPOS              6
14 #define PAGESIZE 4096
15
16 snapshotStack * snapshotObject;
17
18 /*This looks like it might leak memory...  Subramanian should fix this. */
19
20 typedef std::basic_stringstream< char, std::char_traits< char >, MyAlloc< char > > MyStringStream;
21 std::vector< MyString, MyAlloc< MyString> > splitString( MyString input, char delim ){
22         std::vector< MyString, MyAlloc< MyString > > splits;
23         MyStringStream ss( input );     
24         MyString item;
25         while( std::getline( ss, item, delim ) ){
26                 splits.push_back( item );       
27         }
28         return splits;
29 }
30
31 bool checkPermissions( MyString permStr ){
32         return permStr.find("w") != MyString::npos;
33 }
34 static void takeSegmentSnapshot( const MyString & lineText ){
35         std::vector< MyString, MyAlloc< MyString > > firstSplit = splitString( lineText, ' ' );
36         if( checkPermissions( firstSplit[ 1 ] ) ){
37                 std::vector< MyString, MyAlloc< MyString > > secondSplit = splitString( firstSplit[ 0 ], '-' );    
38                 size_t val1 = 0, val2 = 0;
39                 sscanf( secondSplit[ 0 ].c_str(), "%zx", &val1 );
40                 sscanf( secondSplit[ 1 ].c_str(), "%zx", &val2 );
41                 size_t len = ( val2 - val1 ) / PAGESIZE;    
42                 if( 0 != len ){
43                         addMemoryRegionToSnapShot( ( void * )val1, len );        
44                 }
45         }
46 }
47 void SnapshotGlobalSegments(){
48         MyString fn = PROCNAME;
49         static char sProcessSize[ 12 ] = { 0 };
50         std::pair< const char *, bool > dataSect[ 2 ];
51         dataSect[ 0 ] = std::make_pair( MYBINARYNAME, false );
52         dataSect[ 1 ] = std::make_pair( MYLIBRARYNAME, false );
53         static pid_t sProcID = 0;
54         if( 0 == sProcID ) {
55                 sProcID = getpid();     
56                 sprintf( sProcessSize, "%d", sProcID );
57         }
58         fn.replace( REPLACEPOS, 1, sProcessSize );
59         std::ifstream procName( fn.c_str() );
60         if( procName.is_open() ){
61                 MyString line;
62                 while( procName.good() ){
63                         getline( procName, line );
64                         int i  = 0;
65                         for( i = 0; i < 3; ++i ){
66                                 if( MyString::npos != line.find( dataSect[ i ].first ) ) break;                 
67                         }
68                         if( i >= 3 || dataSect[ i ].second == true ) continue;
69                         dataSect[ i ].second = true;
70                         if( !procName.good() )return;
71                         getline( procName, line );
72                         takeSegmentSnapshot( line );    
73                 }       
74         }
75 }
76
77 //class definition of snapshotStack.....
78 //declaration of constructor....
79 snapshotStack::snapshotStack(){
80         SnapshotGlobalSegments();
81         stack=NULL;
82 }
83         
84 snapshotStack::~snapshotStack(){
85 }
86         
87 int snapshotStack::backTrackBeforeStep(int seqindex) {
88         while(true) {
89                 if (stack->index<=seqindex) {
90                         //have right entry
91                         rollBack(stack->snapshotid);
92                         return stack->index;
93                 }
94                 struct stackEntry *tmp=stack;
95                 free(tmp);
96                 stack=stack->next;
97         }
98 }
99
100 void snapshotStack::snapshotStep(int seqindex) {
101         struct stackEntry *tmp=(struct stackEntry *)malloc(sizeof(struct stackEntry));
102         tmp->next=stack;
103         tmp->index=seqindex;
104         tmp->snapshotid=takeSnapshot();
105         stack=tmp;
106 }