+++ /dev/null
-#include <stdlib.h>
-#include <unistd.h>
-#include <cstring>
-#include <inttypes.h>
-
-#include "snapshot-interface.h"
-#include "snapshot.h"
-#include "common.h"
-#include "mymemory.h"
-#include "stl-model.h"
-
-/* MYBINARYNAME only works because our pathname usually includes 'model' (e.g.,
- * /.../model-checker/test/userprog.o) */
-#define MYBINARYNAME "model"
-#define MAPFILE "/proc/self/maps"
-
-struct snapshot_entry {
- snapshot_entry(snapshot_id id, int idx) : snapshotid(id), index(idx) { }
- snapshot_id snapshotid;
- int index;
- MEMALLOC
-};
-
-class SnapshotStack {
-public:
- int backTrackBeforeStep(int seq_index);
- void snapshotStep(int seq_index);
-
- MEMALLOC
-private:
- ModelVector<struct snapshot_entry> stack;
-};
-
-static SnapshotStack *snap_stack;
-
-#ifdef MAC
-/** The SnapshotGlobalSegments function computes the memory regions
- * that may contain globals and then configures the snapshotting
- * library to snapshot them.
- */
-static void SnapshotGlobalSegments()
-{
- int pid = getpid();
- char buf[9000], execname[100];
- FILE *map;
-
- sprintf(execname, "vmmap -interleaved %d", pid);
- map = popen(execname, "r");
-
- if (!map) {
- perror("popen");
- exit(EXIT_FAILURE);
- }
-
- /* Wait for correct part */
- while (fgets(buf, sizeof(buf), map)) {
- if (strstr(buf, "==== regions for process"))
- break;
- }
-
- while (fgets(buf, sizeof(buf), map)) {
- char regionname[200] = "";
- char type[23];
- char smstr[23];
- char r, w, x;
- char mr, mw, mx;
- void *begin, *end;
-
- //Skip out at the end of the section
- if (buf[0] == '\n')
- break;
-
- sscanf(buf, "%22s %p-%p", type, &begin, &end);
-
- char * secondpart = strstr(buf, "]");
-
- sscanf(&secondpart[2], "%c%c%c/%c%c%c SM=%3s %200s\n", &r, &w, &x, &mr, &mw, &mx, smstr, regionname);
- if (w == 'w' && strstr(regionname, MYBINARYNAME)) {
- size_t len = ((uintptr_t)end - (uintptr_t)begin) / PAGESIZE;
- if (len != 0)
- snapshot_add_memory_region(begin, len);
- }
- }
- pclose(map);
-}
-#else
-
-static void get_binary_name(char *buf, size_t len)
-{
- ssize_t size = readlink("/proc/self/exe", buf, len);
- if (size < 0) {
- perror("readlink");
- exit(EXIT_FAILURE);
- }
-
- /* Terminate string */
- if ((size_t)size > len)
- size = len;
- buf[size] = '\0';
-}
-
-/** The SnapshotGlobalSegments function computes the memory regions
- * that may contain globals and then configures the snapshotting
- * library to snapshot them.
- */
-static void SnapshotGlobalSegments()
-{
- char buf[9000];
- char binary_name[800];
- FILE *map;
-
- map = fopen(MAPFILE, "r");
- if (!map) {
- perror("fopen");
- exit(EXIT_FAILURE);
- }
- get_binary_name(binary_name, sizeof(binary_name));
- while (fgets(buf, sizeof(buf), map)) {
- char regionname[200] = "";
- char r, w, x, p;
- void *begin, *end;
-
- sscanf(buf, "%p-%p %c%c%c%c %*x %*x:%*x %*u %200s\n", &begin, &end, &r, &w, &x, &p, regionname);
- if (w == 'w' && strstr(regionname, binary_name)) {
- size_t len = ((uintptr_t)end - (uintptr_t)begin) / PAGESIZE;
- if (len != 0)
- snapshot_add_memory_region(begin, len);
- DEBUG("%55s: %18p - %18p\t%c%c%c%c\n", regionname, begin, end, r, w, x, p);
- }
- }
- fclose(map);
-}
-#endif
-
-/** This method returns to the last snapshot before the inputted
- * sequence number. This function must be called from the model
- * checking thread and not from a snapshotted stack.
- * @param seqindex is the sequence number to rollback before.
- * @return is the sequence number we actually rolled back to.
- */
-int SnapshotStack::backTrackBeforeStep(int seqindex)
-{
- int i;
- for (i = (int)stack.size() - 1;i >= 0;i++)
- if (stack[i].index <= seqindex)
- break;
- else
- stack.pop_back();
-
- ASSERT(i >= 0);
- snapshot_roll_back(stack[i].snapshotid);
- return stack[i].index;
-}
-
-/** This method takes a snapshot at the given sequence number. */
-void SnapshotStack::snapshotStep(int seqindex)
-{
- stack.push_back(snapshot_entry(take_snapshot(), seqindex));
-}
-
-void snapshot_stack_init()
-{
- snap_stack = new SnapshotStack();
- SnapshotGlobalSegments();
-}
-
-void snapshot_record(int seq_index)
-{
- snap_stack->snapshotStep(seq_index);
-}
-
-int snapshot_backtrack_before(int seq_index)
-{
- return snap_stack->backTrackBeforeStep(seq_index);
-}