Пример #1
0
int test(int argc, char **argv){

  MSG_process_sleep(1);

  XBT_INFO("**** Start test ****");
  XBT_INFO("Free after first snapshot");
  
  char *toto = xbt_malloc(5);
  XBT_INFO("Toto allocated");

  void *snap1 = MC_snapshot();

  MSG_process_sleep(1);

  XBT_INFO("First snapshot");

  xbt_free(toto);
  XBT_INFO("Toto free");

  void *snap2 = MC_snapshot();

  XBT_INFO("Second snapshot");

  MSG_process_sleep(1);
  
  MC_ignore_stack("snap2", "test");   
  MC_ignore_stack("snap1", "test");

  XBT_INFO("Test result : %d (0 = state equality, 1 = different states)", MC_compare_snapshots(snap1, snap2));
  
  XBT_INFO("**** End test ****");

  xbt_abort();
}
Пример #2
0
/**
 * \ingroup simix_synchro_management
 *
 */
smx_mutex_t simcall_mutex_init(void)
{
  if(!simix_global) {
    fprintf(stderr,"You must run MSG_init before using MSG\n"); // We can't use xbt_die since we may get there before the initialization
    xbt_abort();
  }
  return simcall_BODY_mutex_init();
}
Пример #3
0
int smpi_global_size(void)
{
  char *value = getenv("SMPI_GLOBAL_SIZE");

  if (!value) {
    fprintf(stderr,
            "Please set env var SMPI_GLOBAL_SIZE to expected number of processes.\n");
    xbt_abort();
  }
  return atoi(value);
}
Пример #4
0
char *bvprintf(const char *fmt, va_list ap)
{
  char *res;

  if (vasprintf(&res, fmt, ap) < 0) {
    /* Do not want to use xbt_die() here, as it uses the logging
     * infrastucture and may fail to allocate memory too. */
    fprintf(stderr, "bprintf: vasprintf failed. Aborting.\n");
    xbt_abort();
  }
  return res;
}
Пример #5
0
void MC_init_dot_output()
{
  dot_output = fopen(_sg_mc_dot_output_file, "w");

  if (dot_output == nullptr) {
    perror("Error open dot output file");
    xbt_abort();
  }

  fprintf(dot_output,
          "digraph graphname{\n fixedsize=true; rankdir=TB; ranksep=.25; edge [fontsize=12]; node [fontsize=10, shape=circle,width=.5 ]; graph [resolution=20, fontsize=10];\n");

}
Пример #6
0
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
}
Пример #7
0
/* default __ex_terminate callback function */
void __xbt_ex_terminate_default(xbt_ex_t * e)
{
  xbt_ex_display(e);
  xbt_abort();
}
Пример #8
0
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;
}
Пример #9
0
static int xbt_log_layout_format_doit(xbt_log_layout_t l, xbt_log_event_t ev, const char *msg_fmt)
{
  char *p = ev->buffer;
  int rem_size = ev->buffer_size;
  int precision = -1;
  int length = -1;
  char *q;

  for (q = l->data ; *q != '\0' ; q++) {
    if (*q == '%') {
      q++;
    handle_modifier:
      switch (*q) {
      case '\0':
        fprintf(stderr, "Layout format (%s) ending with %%\n", (char *)l->data);
        xbt_abort();
      case '%':
        *p = '%';
        check_overflow(1);
        break;
      case 'n':         /* platform-dependant line separator; LOG4J compliant */
        *p = '\n';
        check_overflow(1);
        break;
      case 'e':                 /* plain space; SimGrid extension */
        *p = ' ';
        check_overflow(1);
        break;
      case '.':                 /* precision specifier */
        precision = strtol(q + 1, &q, 10);
        goto handle_modifier;
      case '0':
      case '1':
      case '2':
      case '3':
      case '4':
      case '5':
      case '6':
      case '7':
      case '8':
      case '9':                 /* length modifier */
        length = strtol(q, &q, 10);
        goto handle_modifier;
      case 'c':                 /* category name; LOG4J compliant
                                   should accept a precision postfix to show the hierarchy */
        show_string(ev->cat->name);
        break;
      case 'p':                 /* priority name; LOG4J compliant */
        show_string(xbt_log_priority_names[ev->priority]);
        break;
      case 'h':                 /* host name; SimGrid extension */
        show_string(SIMIX_host_self_get_name());
        break;
      case 't':                 /* thread name; LOG4J compliant */
        show_string(SIMIX_process_self_get_name());
        break;
      case 'P':                 /* process name; SimGrid extension */
        show_string(xbt_procname());
        break;
      case 'i':                 /* process PID name; SimGrid extension */
        show_int(xbt_getpid());
        break;
      case 'F':                 /* file name; LOG4J compliant */
        show_string(ev->fileName);
        break;
      case 'l': {               /* location; LOG4J compliant */
        int len, sz;
        set_sz_from_precision();
        len = snprintf(p, sz, "%s:%d", ev->fileName, ev->lineNum);
        check_overflow(MIN(sz, len));
        break;
      }
      case 'L':                 /* line number; LOG4J compliant */
        show_int(ev->lineNum);
        break;
      case 'M':                /* method (ie, function) name; LOG4J compliant */
        show_string(ev->functionName);
        break;
      case 'b':                 /* backtrace; called %throwable in LOG4J */
      case 'B':         /* short backtrace; called %throwable{short} in LOG4J */
// TODO, backtrace
#if 0 && HAVE_BACKTRACE && HAVE_EXECINFO_H && HAVE_POPEN && defined(ADDR2LINE)
        {
          xbt_ex_t e("");

          e.used = backtrace((void **) e.bt, XBT_BACKTRACE_SIZE);
          e.bt_strings = NULL;
          xbt_ex_setup_backtrace(&e);
          if (*q == 'B') {
            show_string(e.bt_strings[1] + 8);
          } else {
            xbt_strbuff_t buff = xbt_strbuff_new();
            int i;
            xbt_strbuff_append(buff, e.bt_strings[1] + 8);
            for (i = 2; i < e.used; i++) {
              xbt_strbuff_append(buff, "\n");
              xbt_strbuff_append(buff, e.bt_strings[i] + 8);
            }
            show_string(buff->data);
            xbt_strbuff_free(buff);
          }
        }
#else
        show_string("(no backtrace on this arch)");
#endif
        break;
      case 'd':                 /* date; LOG4J compliant */
        show_double(surf_get_clock());
        break;
      case 'r':                 /* application age; LOG4J compliant */
        show_double(surf_get_clock() - format_begin_of_time);
        break;
      case 'm': {               /* user-provided message; LOG4J compliant */
        int len, sz;
        set_sz_from_precision();
        len = vsnprintf(p, sz, msg_fmt, ev->ap);
        check_overflow(MIN(sz, len));
        break;
      }
      default:
        fprintf(stderr, ERRMSG, *q, (char *)l->data);
        xbt_abort();
      }
    } else {
      *p = *q;
      check_overflow(1);
    }
  }
  *p = '\0';

  return 1;
}
Пример #10
0
/**
 * \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;
}