1 #define MYBINARYNAME "model"
2 #define MYLIBRARYNAME "libmodel.so"
3 #define MYALLOCNAME "libmymemory.so"
4 #define PROCNAME "/proc/*/maps"
7 #include "snapshot-interface.h"
11 #include <sys/types.h>
15 typedef std::basic_stringstream< char, std::char_traits< char >, MyAlloc< char > > MyStringStream;
16 std::vector< MyString, MyAlloc< MyString> > splitString( MyString input, char delim ){
17 std::vector< MyString, MyAlloc< MyString > > splits;
18 MyStringStream ss( input );
20 while( std::getline( ss, item, delim ) ){
21 splits.push_back( item );
26 bool checkPermissions( MyString permStr ){
27 return permStr.find("w") != MyString::npos;
29 static void takeSegmentSnapshot( const MyString & lineText ){
30 std::vector< MyString, MyAlloc< MyString > > firstSplit = splitString( lineText, ' ' );
31 if( checkPermissions( firstSplit[ 1 ] ) ){
32 std::vector< MyString, MyAlloc< MyString > > secondSplit = splitString( firstSplit[ 0 ], '-' );
33 size_t val1 = 0, val2 = 0;
34 sscanf( secondSplit[ 0 ].c_str(), "%zx", &val1 );
35 sscanf( secondSplit[ 1 ].c_str(), "%zx", &val2 );
36 size_t len = ( val2 - val1 ) / PAGESIZE;
38 addMemoryRegionToSnapShot( ( void * )val1, len );
42 void snapshot_utils::SnapshotGlobalSegments(){
43 MyString fn = PROCNAME;
44 static char sProcessSize[ 12 ] = { 0 };
45 std::pair< const char *, bool > dataSect[ 3 ];
46 dataSect[ 0 ] = std::make_pair( MYBINARYNAME, false );
47 dataSect[ 1 ] = std::make_pair( MYLIBRARYNAME, false );
48 dataSect[ 2 ] = std::make_pair( MYALLOCNAME, false );
49 static pid_t sProcID = 0;
52 sprintf( sProcessSize, "%d", sProcID );
54 fn.replace( REPLACEPOS, 1, sProcessSize );
55 std::ifstream procName( fn.c_str() );
56 if( procName.is_open() ){
58 while( procName.good() ){
59 getline( procName, line );
61 for( i = 0; i < 3; ++i ){
62 if( MyString::npos != line.find( dataSect[ i ].first ) ) break;
64 if( i >= 3 || dataSect[ i ].second == true ) continue;
65 dataSect[ i ].second = true;
66 if( !procName.good() )return;
67 getline( procName, line );
68 takeSegmentSnapshot( line );
73 //class definition of snapshotTree.....
75 namespace snapshot_utils{
76 snapshotTree * snapshotTree::msCurrentScope = 0;
77 BackTrackingParents_t snapshotTree::msRecordedParents;
78 SnapshotToStateMap_t snapshotTree::msSnapshottedStates;
79 SnapshotEdgeMap_t snapshotTree::msSnapshotEdgesMap;
80 unsigned int snapshotTree::msTimeCounter = 0;
81 void snapshotTree::EnsureRelevantRegionsSnapshotted(){
82 SnapshotGlobalSegments();
83 AddUserHeapToSnapshot();
85 //declaration of constructor....
86 snapshotTree::snapshotTree(){
87 EnsureRelevantRegionsSnapshotted();
90 snapshotTree::~snapshotTree(){
91 if( this == msCurrentScope ){
96 //static function definition
97 snapshotTree * snapshotTree::ReturnCurrentScope(){
98 return msCurrentScope;
101 MyString SerializeThreadSteps( const ThreadStepMap_t & theMap ){
103 char tempArray[ 2048 ] = { 0 };
104 char * ptr = tempArray;
105 for( ThreadStepMap_t::const_iterator myIter = theMap.begin(); myIter != theMap.end(); ++myIter ){
106 sprintf( ptr, "%d:%d#", myIter->first, myIter->second );
108 ptr += strlen( ptr );
113 //public function definiton
115 @funct: TakeStep( thrd_t current, thrd_t whoseNext )
117 @Desc: this function takes a series of steps creating
118 new tree elements and setting the current scope. This function returns true if the step just taken leads to the parent of
119 an unexplored back tracking point...
121 void snapshotTree::AddThreadStep( ThreadStepMap_t & theMap, thrd_t which ){
122 if( theMap.find( which ) != theMap.end() ){
126 theMap[ which ] = 1; //implicit thread creation....
128 bool snapshotTree::operator<( const snapshotTree & rhs ) const{
129 return this->mTimeStamp < rhs.mTimeStamp;
131 bool snapshotTreeComp::operator()( const std::pair< const snapshotTree*, snapshot_id > & lhs, const std::pair< const snapshotTree*, snapshot_id > & rhs ){
132 return *(lhs.first) < *(rhs.first);
134 std::pair< MyString, bool > snapshotTree::TakeStep( thrd_t which, thrd_t whoseNext ){
135 assert( msCurrentScope == this );
136 std::pair< MyString, bool > retVal;
137 ThreadStepMap_t temp = mThreadStepsTaken;
138 AddThreadStep( temp, which );
139 MyString serialized = SerializeThreadSteps( mThreadStepsTaken ); //is it necessary to cache this with the class....?
140 retVal.first = serialized;
141 if( msSnapshotEdgesMap.find( serialized ) != msSnapshotEdgesMap.end() ){
142 msCurrentScope = msSnapshotEdgesMap[ serialized ];
144 snapshotTree * newNode = new snapshotTree();
145 newNode->mThreadStepsTaken = temp;
146 newNode->mpParent = this;
147 this->mChildren.push_back( newNode );
148 newNode->mNextStepTaker = whoseNext; //dont know if this will be used yet....
149 newNode->mTimeStamp = msTimeCounter++;
150 msCurrentScope = newNode;
152 //is it an actual backtracking parent....
153 retVal.second = msRecordedParents.find( msCurrentScope ) != msRecordedParents.end();
158 @funct: BacktrackingPointSet()
160 @DESC: This sets up the internal states necessary in future should we take a snapshot or something...
162 void snapshotTree::BacktrackingPointSet(){
163 assert( msCurrentScope == this );
164 msRecordedParents.insert( msCurrentScope->mpParent );
168 @funct: ReturnEarliestSnapshotID( MyString key )
169 @DESC: For any key, return the snapshot id which is the latest but earlier than the transition defined by the current key....
171 snapshot_id snapshotTree::ReturnEarliestSnapshotID( MyString key ){
172 //first return a snapshotTree *
173 if( msSnapshotEdgesMap.find( key ) == msSnapshotEdgesMap.end() )return -1;
174 //snapshotTree * theNode = msSnapshotEdgesMap[ key ];
176 //do we have a greatest snapshot id that is lesser than the current id...