int main(int argc, char *argv[]){ msg_error_t res; MSG_init(&argc, argv); xbt_assert(argc > 3, "Usage: %s description_file platform_file deployment_file\n" "\tExample: %s smpi_multiple_apps msg_platform.xml msg_deployment.xml\n", argv[0], argv[0]); /* Simulation setting */ MSG_create_environment(argv[2]); /* Application deployment: read the description file in order to identify instances to launch */ FILE* fp = fopen(argv[1], "r"); if (fp == NULL) xbt_die("Cannot open %s", argv[1]); char *line = NULL; size_t n = 0; int instance_size = 0; const char* instance_id = NULL; while (xbt_getline(&line, &n, fp) != -1 ){ xbt_dynar_t elems = xbt_str_split_quoted_in_place(line); if(xbt_dynar_length(elems)<3){ xbt_die ("Not enough elements in the line"); } const char** line_char= xbt_dynar_to_array(elems); instance_id = line_char[0]; instance_size = xbt_str_parse_int(line_char[2], "Invalid size: %s"); XBT_INFO("Initializing instance %s of size %d", instance_id, instance_size); SMPI_app_instance_register(instance_id, smpi_replay,instance_size); xbt_free(line_char); } fclose(fp); MSG_launch_application(argv[3]); SMPI_init(); res = MSG_main(); XBT_INFO("Simulation time %g", MSG_get_clock()); SMPI_finalize(); return res != MSG_OK; }
xbt_dict_t Storage::parseContent(char *filename) { m_usedSize = 0; if ((!filename) || (strcmp(filename, "") == 0)) return NULL; xbt_dict_t parse_content = xbt_dict_new_homogeneous(xbt_free_f); FILE *file = NULL; file = surf_fopen(filename, "r"); if (file == NULL) xbt_die("Cannot open file '%s' (path=%s)", filename, xbt_str_join(surf_path, ":")); char *line = NULL; size_t len = 0; ssize_t read; char path[1024]; sg_size_t size; while ((read = xbt_getline(&line, &len, file)) != -1) { if (read){ if(sscanf(line,"%s %llu", path, &size) == 2) { m_usedSize += size; sg_size_t *psize = xbt_new(sg_size_t, 1); *psize = size; xbt_dict_set(parse_content,path,psize,NULL); } else { xbt_die("Be sure of passing a good format for content file.\n"); } } } free(line); fclose(file); return parse_content; }
XBT_PRIVATE std::vector<VmMap> get_memory_map(pid_t pid) { #ifdef __linux__ /* Open the actual process's proc maps file and create the memory_map_t */ /* to be returned. */ char* path = bprintf("/proc/%i/maps", (int) pid); FILE *fp = std::fopen(path, "r"); if(fp == NULL) std::perror("fopen failed"); xbt_assert(fp, "Cannot open %s to investigate the memory map of the process.", path); free(path); setbuf(fp, NULL); std::vector<VmMap> ret; /* Read one line at the time, parse it and add it to the memory map to be returned */ ssize_t read; /* Number of bytes readed */ char* line = NULL; std::size_t n = 0; /* Amount of bytes to read by xbt_getline */ while ((read = xbt_getline(&line, &n, fp)) != -1) { //fprintf(stderr,"%s", line); /* Wipeout the new line character */ line[read - 1] = '\0'; /* Tokenize the line using spaces as delimiters and store each token */ /* in lfields array. We expect 5 tokens/fields */ char* lfields[6]; lfields[0] = strtok(line, " "); int i; for (i = 1; i < 6 && lfields[i - 1] != NULL; i++) { lfields[i] = std::strtok(NULL, " "); } /* Check to see if we got the expected amount of columns */ if (i < 6) xbt_abort(); /* Ok we are good enough to try to get the info we need */ /* First get the start and the end address of the map */ char *tok = std::strtok(lfields[0], "-"); if (tok == NULL) xbt_abort(); VmMap memreg; char *endptr; memreg.start_addr = std::strtoull(tok, &endptr, 16); /* Make sure that the entire string was an hex number */ if (*endptr != '\0') xbt_abort(); tok = std::strtok(NULL, "-"); if (tok == NULL) xbt_abort(); memreg.end_addr = std::strtoull(tok, &endptr, 16); /* Make sure that the entire string was an hex number */ if (*endptr != '\0') xbt_abort(); /* Get the permissions flags */ if (std::strlen(lfields[1]) < 4) xbt_abort(); memreg.prot = 0; for (i = 0; i < 3; i++){ switch(lfields[1][i]){ case 'r': memreg.prot |= PROT_READ; break; case 'w': memreg.prot |= PROT_WRITE; break; case 'x': memreg.prot |= PROT_EXEC; break; default: break; } } if (memreg.prot == 0) memreg.prot |= PROT_NONE; if (lfields[1][4] == 'p') memreg.flags |= MAP_PRIVATE; else if (lfields[1][4] == 's') memreg.flags |= MAP_SHARED; /* Get the offset value */ memreg.offset = std::strtoull(lfields[2], &endptr, 16); /* Make sure that the entire string was an hex number */ if (*endptr != '\0') xbt_abort(); /* Get the device major:minor bytes */ tok = std::strtok(lfields[3], ":"); if (tok == NULL) xbt_abort(); memreg.dev_major = (char) strtoul(tok, &endptr, 16); /* Make sure that the entire string was an hex number */ if (*endptr != '\0') xbt_abort(); tok = std::strtok(NULL, ":"); if (tok == NULL) xbt_abort(); memreg.dev_minor = (char) std::strtoul(tok, &endptr, 16); /* Make sure that the entire string was an hex number */ if (*endptr != '\0') xbt_abort(); /* Get the inode number and make sure that the entire string was a long int */ memreg.inode = strtoul(lfields[4], &endptr, 10); if (*endptr != '\0') xbt_abort(); /* And finally get the pathname */ if (lfields[5]) memreg.pathname = lfields[5]; /* Create space for a new map region in the region's array and copy the */ /* parsed stuff from the temporal memreg variable */ XBT_DEBUG("Found region for %s", !memreg.pathname.empty() ? memreg.pathname.c_str() : "(null)"); ret.push_back(std::move(memreg)); } std::free(line); std::fclose(fp); return ret; #else /* On FreeBSD, kinfo_getvmmap() could be used but mmap() support is disabled anyway. */ xbt_die("Could not get memory map from process %lli", (long long int) pid); #endif }
memory_map_t get_memory_map(void) { FILE *fp; /* File pointer to process's proc maps file */ char *line = NULL; /* Temporal storage for each line that is readed */ ssize_t read; /* Number of bytes readed */ size_t n = 0; /* Amount of bytes to read by xbt_getline */ memory_map_t ret = NULL; /* The memory map to return */ /* The following variables are used during the parsing of the file "maps" */ s_map_region_t memreg; /* temporal map region used for creating the map */ char *lfields[6], *tok, *endptr; int i; /* Open the actual process's proc maps file and create the memory_map_t */ /* to be returned. */ fp = fopen("/proc/self/maps", "r"); if(fp == NULL) perror("fopen failed"); xbt_assert(fp, "Cannot open /proc/self/maps to investigate the memory map of the process. Please report this bug."); setbuf(fp, NULL); ret = xbt_new0(s_memory_map_t, 1); /* Read one line at the time, parse it and add it to the memory map to be returned */ while ((read = xbt_getline(&line, &n, fp)) != -1) { //fprintf(stderr,"%s", line); /* Wipeout the new line character */ line[read - 1] = '\0'; /* Tokenize the line using spaces as delimiters and store each token */ /* in lfields array. We expect 5 tokens/fields */ lfields[0] = strtok(line, " "); for (i = 1; i < 6 && lfields[i - 1] != NULL; i++) { lfields[i] = strtok(NULL, " "); } /* Check to see if we got the expected amount of columns */ if (i < 6) xbt_abort(); /* Ok we are good enough to try to get the info we need */ /* First get the start and the end address of the map */ tok = strtok(lfields[0], "-"); if (tok == NULL) xbt_abort(); memreg.start_addr = (void *) strtoul(tok, &endptr, 16); /* Make sure that the entire string was an hex number */ if (*endptr != '\0') xbt_abort(); tok = strtok(NULL, "-"); if (tok == NULL) xbt_abort(); memreg.end_addr = (void *) strtoul(tok, &endptr, 16); /* Make sure that the entire string was an hex number */ if (*endptr != '\0') xbt_abort(); /* Get the permissions flags */ if (strlen(lfields[1]) < 4) xbt_abort(); memreg.prot = 0; for (i = 0; i < 3; i++){ switch(lfields[1][i]){ case 'r': memreg.prot |= PROT_READ; break; case 'w': memreg.prot |= PROT_WRITE; break; case 'x': memreg.prot |= PROT_EXEC; break; default: break; } } if (memreg.prot == 0) memreg.prot |= PROT_NONE; if (lfields[1][4] == 'p') memreg.flags |= MAP_PRIVATE; else if (lfields[1][4] == 's') memreg.flags |= MAP_SHARED; /* Get the offset value */ memreg.offset = (void *) strtoul(lfields[2], &endptr, 16); /* Make sure that the entire string was an hex number */ if (*endptr != '\0') xbt_abort(); /* Get the device major:minor bytes */ tok = strtok(lfields[3], ":"); if (tok == NULL) xbt_abort(); memreg.dev_major = (char) strtoul(tok, &endptr, 16); /* Make sure that the entire string was an hex number */ if (*endptr != '\0') xbt_abort(); tok = strtok(NULL, ":"); if (tok == NULL) xbt_abort(); memreg.dev_minor = (char) strtoul(tok, &endptr, 16); /* Make sure that the entire string was an hex number */ if (*endptr != '\0') xbt_abort(); /* Get the inode number and make sure that the entire string was a long int */ memreg.inode = strtoul(lfields[4], &endptr, 10); if (*endptr != '\0') xbt_abort(); /* And finally get the pathname */ memreg.pathname = xbt_strdup(lfields[5]); /* Create space for a new map region in the region's array and copy the */ /* parsed stuff from the temporal memreg variable */ ret->regions = xbt_realloc(ret->regions, sizeof(memreg) * (ret->mapsize + 1)); memcpy(ret->regions + ret->mapsize, &memreg, sizeof(memreg)); ret->mapsize++; } free(line); fclose(fp); return ret; }
int main(int argc, char *argv[]){ msg_error_t res; const char *platform_file; const char *application_file; const char *description_file; MSG_init(&argc, argv); if (argc < 4) { printf("Usage: %s description_file platform_file deployment_file\n", argv[0]); printf("example: %s smpi_multiple_apps msg_platform.xml msg_deployment.xml\n", argv[0]); exit(1); } description_file = argv[1]; platform_file = argv[2]; application_file = argv[3]; { /* Simulation setting */ MSG_create_environment(platform_file); } { /* Application deployment */ //read the description file in order to identify instances to launch FILE* fp = fopen(description_file, "r"); if (fp == NULL) xbt_die("Cannot open %s", description_file); ssize_t read; char *line = NULL; size_t n = 0; int instance_size = 0; const char* instance_id = NULL; while ((read = xbt_getline(&line, &n, fp)) != -1 ){ xbt_dynar_t elems = xbt_str_split_quoted_in_place(line); if(xbt_dynar_length(elems)<3){ xbt_die ("Not enough elements in the line"); } const char** line_char= xbt_dynar_to_array(elems); instance_id = line_char[0]; instance_size = atoi(line_char[2]); XBT_INFO("Initializing instance %s of size %d", instance_id, instance_size); SMPI_app_instance_register(instance_id, smpi_replay,instance_size); xbt_free(line_char); } MSG_launch_application(application_file); SMPI_init(); } res = MSG_main(); XBT_INFO("Simulation time %g", MSG_get_clock()); SMPI_finalize(); if (res == MSG_OK) return 0; else return 1; }
/** * \todo This function contains many cases that do not allow for a * recovery. Currently, xbt_abort() is called but we should * much rather die with the specific reason so that it's easier * to find out what's going on. */ XBT_PRIVATE std::vector<VmMap> get_memory_map(pid_t pid) { std::vector<VmMap> ret; #ifdef __linux__ /* Open the actual process's proc maps file and create the memory_map_t */ /* to be returned. */ char* path = bprintf("/proc/%i/maps", (int) pid); FILE *fp = std::fopen(path, "r"); if (fp == nullptr) { std::perror("fopen failed"); xbt_die("Cannot open %s to investigate the memory map of the process.", path); } free(path); setbuf(fp, nullptr); /* Read one line at the time, parse it and add it to the memory map to be returned */ ssize_t read; /* Number of bytes readed */ char* line = nullptr; std::size_t n = 0; /* Amount of bytes to read by xbt_getline */ while ((read = xbt_getline(&line, &n, fp)) != -1) { /** * The lines that we read have this format: (This is just an example) * 00602000-00603000 rw-p 00002000 00:28 1837264 <complete-path-to-file> */ //fprintf(stderr,"%s", line); /* Wipeout the new line character */ line[read - 1] = '\0'; /* Tokenize the line using spaces as delimiters and store each token in lfields array. We expect 5 tokens for 6 fields */ char* lfields[6]; lfields[0] = strtok(line, " "); int i; for (i = 1; i < 6 && lfields[i - 1] != nullptr; i++) { lfields[i] = std::strtok(nullptr, " "); } /* Check to see if we got the expected amount of columns */ if (i < 6) xbt_die("The memory map apparently only supplied less than 6 columns. Recovery impossible."); /* Ok we are good enough to try to get the info we need */ /* First get the start and the end address of the map */ char *tok = std::strtok(lfields[0], "-"); if (tok == nullptr) xbt_die("Start and end address of the map are not concatenated by a hyphen (-). Recovery impossible."); VmMap memreg; char *endptr; memreg.start_addr = std::strtoull(tok, &endptr, 16); /* Make sure that the entire string was an hex number */ if (*endptr != '\0') xbt_abort(); tok = std::strtok(nullptr, "-"); if (tok == nullptr) xbt_abort(); memreg.end_addr = std::strtoull(tok, &endptr, 16); /* Make sure that the entire string was an hex number */ if (*endptr != '\0') xbt_abort(); /* Get the permissions flags */ if (std::strlen(lfields[1]) < 4) xbt_abort(); memreg.prot = 0; for (i = 0; i < 3; i++){ switch(lfields[1][i]){ case 'r': memreg.prot |= PROT_READ; break; case 'w': memreg.prot |= PROT_WRITE; break; case 'x': memreg.prot |= PROT_EXEC; break; default: break; } } if (memreg.prot == 0) memreg.prot |= PROT_NONE; if (lfields[1][3] == 'p') { memreg.flags |= MAP_PRIVATE; } else { memreg.flags |= MAP_SHARED; if (lfields[1][3] != 's') XBT_WARN("The protection is neither 'p' (private) nor 's' (shared) but '%s'. Let's assume shared, as on b0rken win-ubuntu systems.\nFull line: %s\n", lfields[1], line); } /* Get the offset value */ memreg.offset = std::strtoull(lfields[2], &endptr, 16); /* Make sure that the entire string was an hex number */ if (*endptr != '\0') xbt_abort(); /* Get the device major:minor bytes */ tok = std::strtok(lfields[3], ":"); if (tok == nullptr) xbt_abort(); memreg.dev_major = (char) strtoul(tok, &endptr, 16); /* Make sure that the entire string was an hex number */ if (*endptr != '\0') xbt_abort(); tok = std::strtok(nullptr, ":"); if (tok == nullptr) xbt_abort(); memreg.dev_minor = (char) std::strtoul(tok, &endptr, 16); /* Make sure that the entire string was an hex number */ if (*endptr != '\0') xbt_abort(); /* Get the inode number and make sure that the entire string was a long int */ memreg.inode = strtoul(lfields[4], &endptr, 10); if (*endptr != '\0') xbt_abort(); /* And finally get the pathname */ if (lfields[5]) memreg.pathname = lfields[5]; /* Create space for a new map region in the region's array and copy the */ /* parsed stuff from the temporal memreg variable */ XBT_DEBUG("Found region for %s", !memreg.pathname.empty() ? memreg.pathname.c_str() : "(null)"); ret.push_back(std::move(memreg)); } std::free(line); std::fclose(fp); #elif defined __FreeBSD__ struct procstat *prstat; struct kinfo_proc *proc; struct kinfo_vmentry *vmentries; unsigned int cnt; if ((prstat = procstat_open_sysctl()) == NULL) { std::perror("procstat_open_sysctl failed"); xbt_die("Cannot access kernel state information"); } if ((proc = procstat_getprocs(prstat, KERN_PROC_PID, pid, &cnt)) == NULL) { std::perror("procstat_open_sysctl failed"); xbt_die("Cannot access process information"); } if ((vmentries = procstat_getvmmap(prstat, proc, &cnt)) == NULL) { std::perror("procstat_getvmmap failed"); xbt_die("Cannot access process memory mappings"); } for (unsigned int i = 0; i < cnt; i++) { VmMap memreg; /* Addresses */ memreg.start_addr = vmentries[i].kve_start; memreg.end_addr = vmentries[i].kve_end; /* Permissions */ memreg.prot = PROT_NONE; if (vmentries[i].kve_protection & KVME_PROT_READ) memreg.prot |= PROT_READ; if (vmentries[i].kve_protection & KVME_PROT_WRITE) memreg.prot |= PROT_WRITE; if (vmentries[i].kve_protection & KVME_PROT_EXEC) memreg.prot |= PROT_EXEC; /* Private (copy-on-write) or shared? */ if (vmentries[i].kve_flags & KVME_FLAG_COW) memreg.flags |= MAP_PRIVATE; else memreg.flags |= MAP_SHARED; /* Offset */ memreg.offset = vmentries[i].kve_offset; /* Device : not sure this can be mapped to something outside of Linux? */ memreg.dev_major = 0; memreg.dev_minor = 0; /* Inode */ memreg.inode = vmentries[i].kve_vn_fileid; /* * Path. Linuxize result by giving an anonymous mapping a path from * the previous mapping, provided previous is vnode and has a path, * and mark the stack. */ if (vmentries[i].kve_path[0] != '\0') memreg.pathname = vmentries[i].kve_path; else if (vmentries[i].kve_type == KVME_TYPE_DEFAULT && vmentries[i-1].kve_type == KVME_TYPE_VNODE && vmentries[i-1].kve_path[0] != '\0') memreg.pathname = vmentries[i-1].kve_path; else if (vmentries[i].kve_type == KVME_TYPE_DEFAULT && vmentries[i].kve_flags & KVME_FLAG_GROWS_DOWN) memreg.pathname = "[stack]"; /* * One last dirty modification: remove write permission from shared * libraries private clean pages. This is necessary because simgrid * later identifies mappings based on the permissions that are expected * when running the Linux kernel. */ if (vmentries[i].kve_type == KVME_TYPE_VNODE && ! (vmentries[i].kve_flags & KVME_FLAG_NEEDS_COPY)) memreg.prot &= ~PROT_WRITE; ret.push_back(std::move(memreg)); } procstat_freevmmap(prstat, vmentries); procstat_freeprocs(prstat, proc); procstat_close(prstat); #else xbt_die("Could not get memory map from process %lli", (long long int) pid); #endif return ret; }