Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
model-checker : change XBT_DEBUG for fprintf
[simgrid.git] / src / mc / memory_map.c
1 /* Copyright (c) 2008-2012 Da SimGrid Team. All rights reserved.            */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #define _GNU_SOURCE
7 #include "mc_private.h"
8 #include <stdlib.h>
9
10 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_memory_map, mc,
11                                 "Logging specific to algorithms for memory_map");
12
13 memory_map_t get_memory_map(void)
14 {
15   FILE *fp;                     /* File pointer to process's proc maps file */
16   char *line = NULL;            /* Temporal storage for each line that is readed */
17   ssize_t read;                 /* Number of bytes readed */
18   size_t n = 0;                 /* Amount of bytes to read by getline */
19   memory_map_t ret = NULL;      /* The memory map to return */
20
21 /* The following variables are used during the parsing of the file "maps" */
22   s_map_region_t memreg;          /* temporal map region used for creating the map */
23   char *lfields[6], *tok, *endptr;
24   int i;
25
26 /* Open the actual process's proc maps file and create the memory_map_t */
27 /* to be returned. */
28   fp = fopen("/proc/self/maps", "r");
29
30   if(fp == NULL)
31     perror("fopen failed");
32
33   xbt_assert(fp,
34               "Cannot open /proc/self/maps to investigate the memory map of the process. Please report this bug.");
35
36   ret = xbt_new0(s_memory_map_t, 1);
37
38   /* Read one line at the time, parse it and add it to the memory map to be returned */
39   while ((read = getline(&line, &n, fp)) != -1) {
40
41     //fprintf(stderr,"%s", line);
42
43     /* Wipeout the new line character */
44     line[read - 1] = '\0';
45
46     /* Tokenize the line using spaces as delimiters and store each token */
47     /* in lfields array. We expect 5 tokens/fields */
48     lfields[0] = strtok(line, " ");
49
50     for (i = 1; i < 6 && lfields[i - 1] != NULL; i++) {
51       lfields[i] = strtok(NULL, " ");
52     }
53
54     /* Check to see if we got the expected amount of columns */
55     if (i < 6)
56       xbt_abort();
57
58     /* Ok we are good enough to try to get the info we need */
59     /* First get the start and the end address of the map   */
60     tok = strtok(lfields[0], "-");
61     if (tok == NULL)
62       xbt_abort();
63
64     memreg.start_addr = (void *) strtoul(tok, &endptr, 16);
65     /* Make sure that the entire string was an hex number */
66     if (*endptr != '\0')
67       xbt_abort();
68
69     tok = strtok(NULL, "-");
70     if (tok == NULL)
71       xbt_abort();
72
73     memreg.end_addr = (void *) strtoul(tok, &endptr, 16);
74     /* Make sure that the entire string was an hex number */
75     if (*endptr != '\0')
76       xbt_abort();
77
78     /* Get the permissions flags */
79     if (strlen(lfields[1]) < 4)
80       xbt_abort();
81
82     memreg.prot = 0;
83
84     for (i = 0; i < 3; i++){
85       switch(lfields[1][i]){
86         case 'r':
87           memreg.prot |= PROT_READ;
88           break;
89         case 'w':
90           memreg.prot |= PROT_WRITE;
91           break;
92         case 'x':
93           memreg.prot |= PROT_EXEC;
94           break;
95         default:
96           break;
97       }
98     }
99     if (memreg.prot == 0)
100       memreg.prot |= PROT_NONE;
101
102     if (lfields[1][4] == 'p')
103       memreg.flags |= MAP_PRIVATE;
104
105     else if (lfields[1][4] == 's')
106       memreg.flags |= MAP_SHARED;
107
108     /* Get the offset value */
109     memreg.offset = (void *) strtoul(lfields[2], &endptr, 16);
110     /* Make sure that the entire string was an hex number */
111     if (*endptr != '\0')
112       xbt_abort();
113
114     /* Get the device major:minor bytes */
115     tok = strtok(lfields[3], ":");
116     if (tok == NULL)
117       xbt_abort();
118
119     memreg.dev_major = (char) strtoul(tok, &endptr, 16);
120     /* Make sure that the entire string was an hex number */
121     if (*endptr != '\0')
122       xbt_abort();
123
124     tok = strtok(NULL, ":");
125     if (tok == NULL)
126       xbt_abort();
127
128     memreg.dev_minor = (char) strtoul(tok, &endptr, 16);
129     /* Make sure that the entire string was an hex number */
130     if (*endptr != '\0')
131       xbt_abort();
132
133     /* Get the inode number and make sure that the entire string was a long int */
134     memreg.inode = strtoul(lfields[4], &endptr, 10);
135     if (*endptr != '\0')
136       xbt_abort();
137
138     /* And finally get the pathname */
139     memreg.pathname = xbt_strdup(lfields[5]);
140
141     /* Create space for a new map region in the region's array and copy the */
142     /* parsed stuff from the temporal memreg variable */
143     ret->regions =
144         xbt_realloc(ret->regions, sizeof(memreg) * (ret->mapsize + 1));
145     memcpy(ret->regions + ret->mapsize, &memreg, sizeof(memreg));
146     ret->mapsize++;
147
148   }
149
150   free(line);
151
152   fclose(fp);
153
154   return ret;
155 }