8 #include <sys/mman.h> // PROT_*
12 #include "mc_process.h"
13 #include "mc_object_info.h"
15 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_process, mc,
16 "MC process information");
18 static void MC_init_memory_map_info(mc_process_t process);
20 void MC_process_init(mc_process_t process, pid_t pid)
22 process->process_flags = MC_PROCESS_NO_FLAG;
25 process->process_flags |= MC_PROCESS_SELF_FLAG;
26 process->memory_map = MC_get_memory_map(pid);
27 MC_init_memory_map_info(process);
30 void MC_process_clear(mc_process_t process)
32 process->process_flags = MC_PROCESS_NO_FLAG;
35 MC_free_memory_map(process->memory_map);
36 process->memory_map = NULL;
38 process->maestro_stack_start = NULL;
39 process->maestro_stack_end = NULL;
42 for (i=0; i!=process->object_infos_size; ++i) {
43 MC_free_object_info(&process->object_infos[i]);
45 free(process->object_infos);
46 process->object_infos = NULL;
47 process->object_infos_size = 0;
50 #define SO_RE "\\.so[\\.0-9]*$"
51 #define VERSION_RE "-[\\.0-9]*$"
53 const char* FILTERED_LIBS[] = {
74 static bool MC_is_simgrid_lib(const char* libname)
76 return !strcmp(libname, "libsimgrid");
79 static bool MC_is_filtered_lib(const char* libname)
81 const size_t n = sizeof(FILTERED_LIBS) / sizeof(const char*);
84 if (strcmp(libname, FILTERED_LIBS[i])==0)
89 struct s_mc_memory_map_re {
94 static char* MC_get_lib_name(const char* pathname, struct s_mc_memory_map_re* res) {
95 const char* map_basename = basename((char*) pathname);
98 if(regexec(&res->so_re, map_basename, 1, &match, 0))
101 char* libname = strndup(map_basename, match.rm_so);
103 // Strip the version suffix:
104 if(libname && !regexec(&res->version_re, libname, 1, &match, 0)) {
105 char* temp = libname;
106 libname = strndup(temp, match.rm_so);
113 /** @brief Finds the range of the different memory segments and binary paths */
114 static void MC_init_memory_map_info(mc_process_t process)
116 XBT_INFO("Get debug information ...");
117 process->maestro_stack_start = NULL;
118 process->maestro_stack_end = NULL;
119 process->object_infos = NULL;
120 process->object_infos_size = 0;
121 process->binary_info = NULL;
122 process->libsimgrid_info = NULL;
124 struct s_mc_memory_map_re res;
126 if(regcomp(&res.so_re, SO_RE, 0) || regcomp(&res.version_re, VERSION_RE, 0))
127 xbt_die(".so regexp did not compile");
129 memory_map_t maps = process->memory_map;
131 const char* current_name = NULL;
134 for (i=0; i < maps->mapsize; i++) {
135 map_region_t reg = &(maps->regions[i]);
136 const char* pathname = maps->regions[i].pathname;
139 if (maps->regions[i].pathname == NULL) {
144 // [stack], [vvar], [vsyscall], [vdso] ...
145 if (pathname[0] == '[') {
146 if ((reg->prot & PROT_WRITE) && !memcmp(pathname, "[stack]", 7)) {
147 process->maestro_stack_start = reg->start_addr;
148 process->maestro_stack_end = reg->end_addr;
154 if (current_name && strcmp(current_name, pathname)==0)
157 current_name = pathname;
158 if (!(reg->prot & PROT_READ) && (reg->prot & PROT_EXEC))
161 const bool is_executable = !i;
162 char* libname = NULL;
163 if (!is_executable) {
164 libname = MC_get_lib_name(pathname, &res);
167 if (MC_is_filtered_lib(libname)) {
173 mc_object_info_t info =
174 MC_find_object_info(process->memory_map, pathname, is_executable);
175 process->object_infos = (mc_object_info_t*) realloc(process->object_infos,
176 (process->object_infos_size+1) * sizeof(mc_object_info_t*));
177 process->object_infos[process->object_infos_size] = info;
178 process->object_infos_size++;
180 process->binary_info = info;
181 else if (libname && MC_is_simgrid_lib(libname))
182 process->libsimgrid_info = info;
187 regfree(&res.version_re);
189 // Resolve time (including accress differents objects):
190 for (i=0; i!=process->object_infos_size; ++i)
191 MC_post_process_object_info(process, process->object_infos[i]);
193 xbt_assert(process->maestro_stack_start, "maestro_stack_start");
194 xbt_assert(process->maestro_stack_end, "maestro_stack_end");
196 XBT_INFO("Get debug information done !");
199 mc_object_info_t MC_process_find_object_info(mc_process_t process, void *ip)
202 for (i = 0; i != process->object_infos_size; ++i) {
203 if (ip >= (void *) process->object_infos[i]->start_exec
204 && ip <= (void *) process->object_infos[i]->end_exec) {
205 return process->object_infos[i];
211 dw_frame_t MC_process_find_function(mc_process_t process, void *ip)
213 mc_object_info_t info = MC_process_find_object_info(process, ip);
217 return MC_file_object_info_find_function(info, ip);