Example #1
0
/* Initializer of each process */
void __attribute__((constructor)) init_malloc_wrapper()
{
    const char* malloc_detective_free = getenv(MALLOC_DETECTIVE_FREE);
    is_out_free_bt = (malloc_detective_free && atoi(malloc_detective_free) == 1);

    /* INNER_FLAG_UP: Logging file descriptor for child-processes. */
    const char* inner_flag_logfd = getenv(INNER_FLAG_LOGFD);
    char* output_name = NULL;

    /* MALLOC_DETECTIVE_CHILD: Reuse flag of log stream by children. */
    const char* malloc_detective_child = getenv(MALLOC_DETECTIVE_CHILD);
    const int is_reuse = (malloc_detective_child && atoi(malloc_detective_child) == 1);

    /* Get file discriptor for output log */
    malloc_wapper_logfd = STDERR_FILENO;
    if (inner_flag_logfd) {
        /* Reuse the file descriptor that parent has generated.
         * (or -1. Output suppressed by parents) */
        malloc_wapper_logfd = atoi(inner_flag_logfd);
    } else if ((output_name = getenv(MALLOC_DETECTIVE_OUTPUT)) != NULL) {
        /* Deciding output stream, stderr or fifo.
         *   Using fifo if defined env-value MALLOC_DETECTIVE_OUTPUT. */
        struct stat filestat;
        if (stat(output_name, &filestat) == -1) {
            /* Creating fifo, if not exists */
            if (mkfifo(output_name, 0600) == -1) {
                const char* errstr = strerror(errno);
                fprintf(stderr, "Error: Can't create fifo(%s). mkfifo:%s\n", output_name, errstr);
                _exit(2);
            }
        } else if (!S_ISFIFO(filestat.st_mode)) {
            fprintf(stderr, "Error: %s is not fifo.\n", output_name);
            _exit(3);
        }
        const mode_t openflag = O_WRONLY || (is_reuse ? 0 : O_CLOEXEC);
        malloc_wapper_logfd = open(output_name, openflag);
        if (malloc_wapper_logfd < 0) {
            const char* errstr = strerror(errno);
            fprintf(stderr, "Error: Can't open fifo(%s). open:%s\n", output_name, errstr);
            _exit(1);
        }

        /* Save output stream if defined MALLOC_DETECTIVE_CHILD environment as 1.
         * Otherwise save -1 to suppress output by children. */
        if (is_reuse) {
            char str_logfd[32] = {0};
            sprintf(str_logfd, "%d", malloc_wapper_logfd);
            setenv(INNER_FLAG_LOGFD, str_logfd, 1);
        } else {
            setenv(INNER_FLAG_LOGFD, "-1", 1);
        }
    }

    /* load libc's malloc/free */
    load_malloc();
    load_free();
    load_libc_malloc();
    load_libc_free();
}
Example #2
0
void free(void* p)
{
    if (!origin_free) {
        load_free();
    }

    origin_free(p);
    if (depth > 0|| malloc_wapper_logfd == -1) {
        return;
    }

    ++depth;
    log_output(is_out_free_bt, &loghead_build_free, p, 0);
    --depth;
}
Example #3
0
/**
 * @brief Loads or refreshes saved games.
 */
int load_refresh (void)
{
   char **files, buf[PATH_MAX], *tmp;
   int nfiles, i, len;
   int ok;
   nsave_t *ns;

   if (load_saves != NULL)
      load_free();
   load_saves = array_create( nsave_t );

   /* load the saves */
   files = nfile_readDir( &nfiles, "%ssaves", nfile_dataPath() );
   for (i=0; i<nfiles; i++) {
      len = strlen(files[i]);

      /* no save or backup save extension */
      if (((len < 5) || strcmp(&files[i][len-3],".ns")) &&
            ((len < 12) || strcmp(&files[i][len-10],".ns.backup"))) {
         free(files[i]);
         memmove( &files[i], &files[i+1], sizeof(char*) * (nfiles-i-1) );
         nfiles--;
         i--;
      }
   }

   /* Make sure files are none. */
   if (files == NULL)
      return 0;

   /* Make sure backups are after saves. */
   for (i=0; i<nfiles-1; i++) {
      len = strlen( files[i] );

      /* Only interested in swapping backup with file after it if it's not backup. */
      if ((len < 12) || strcmp( &files[i][len-10],".ns.backup" ))
         continue;

      /* Don't match. */
      if (strncmp( files[i], files[i+1], (len-10) ))
         continue;
  
      /* Swap around. */
      tmp         = files[i];
      files[i]    = files[i+1];
      files[i+1]  = tmp;
   }

   /* Allocate and parse. */
   ok = 0;
   ns = NULL;
   for (i=0; i<nfiles; i++) {
      if (!ok)
         ns = &array_grow( &load_saves );
      nsnprintf( buf, sizeof(buf), "%ssaves/%s", nfile_dataPath(), files[i] );
      ok = load_load( ns, buf );
   }

   /* If the save was invalid, array is 1 member too large. */
   if (ok)
      array_resize( &load_saves, array_size(load_saves)-1 );

   /* Clean up memory. */
   for (i=0; i<nfiles; i++)
      free(files[i]);
   free(files);

   return 0;
}