Logo AND Algorithmique Numérique Distribuée

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