Logo AND Algorithmique Numérique Distribuée

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