Exemple #1
0
/**
 * b u _ i p w d
 *
 * set/return the path to the initial working directory.
 * bu_setprogname() must be called on app startup for the correct pwd to
 * be acquired/set.
 */
static const char *
bu_ipwd()
{
    /* private stash */
    static const char *ipwd = NULL;
    static char buffer[MAXPATHLEN] = {0};

    if (ipwd) {
	return ipwd;
    }

    ipwd = getenv("PWD"); /* not our memory to free */

    if (!ipwd && (ipwd = bu_which("pwd"))) {
	FILE *fp;

	fp = popen(ipwd, "r");
	if (fp) {
	    if (bu_fgets(buffer, MAXPATHLEN, fp)) {
		ipwd = buffer;
	    } else {
		ipwd = ".";
	    }
	} else {
	    ipwd = ".";
	}
    } else {
	ipwd = ".";
    }

    return ipwd;
}
Exemple #2
0
/**
 * b u _ a r g v 0 _ f u l l _ p a t h
 *
 * returns the full path to argv0, regardless of how the application
 * was invoked.
 */
const char *
bu_argv0_full_path(void)
{
    static char buffer[MAXPATHLEN] = {0};

    const char *argv0 = bu_argv0();
    const char *ipwd = bu_ipwd();

    const char *which = bu_which(argv0);

    if (argv0[0] == BU_DIR_SEPARATOR) {
	/* seems to be a full path */
	snprintf(buffer, MAXPATHLEN, "%s", argv0);
	return buffer;
    }

    if (argv0[0] == '.' && argv0[1] == BU_DIR_SEPARATOR) {
	/* remove a ./ if present */
	argv0 += 2;
    }

    /* running from installed */
    if (which) {
	snprintf(buffer, MAXPATHLEN, "%s", which);
	return buffer;
    }

    /* running from source dir */
    snprintf(buffer, MAXPATHLEN, "%s%c%s", ipwd, BU_DIR_SEPARATOR, argv0);
    if (bu_file_exists(buffer)) {
	return buffer;
    }

    /* give up */
    snprintf(buffer, MAXPATHLEN, "%s", argv0);
    return buffer;
}
int
bu_crashreport(const char *filename)
{
    if (UNLIKELY(!filename || strlen(filename) == 0)) {
	return 0;
    }

    /* vat time ist? */
    (void)time(&now);

    path = bu_argv0_full_path();

    /* do our own expansion to avoid heap allocation */
    snprintf(buffer, CR_BUFSIZE, "******************************************\n\n"
	     "%s\n"		/* version info */
	     "Command: %s\n"	/* program name */
	     "Process: %d\n"	/* pid */
	     "Path: %s\n"	/* which binary */
	     "Date: %s\n",	/* date/time */
	     brlcad_ident("Crash Report"),
	     bu_getprogname(),
	     bu_process_id(),
	     path ? path : "Unknown",
	     ctime(&now));

    fp = fopen(filename, "ab");
    if (UNLIKELY(!fp || ferror(fp))) {
	perror("unable to open crash report file");
	bu_log("ERROR: Unable to open crash report file [%s]\n", filename);
	return 0;
    }

    /* make the file stream unbuffered */
    if (setvbuf(fp, (char *)NULL, _IONBF, 0) != 0) {
	perror("unable to make stream unbuffered");
    }

    /* print the report header */
    if (fwrite(buffer, 1, strlen(buffer), fp) != strlen(buffer)) {
	/* cannot bomb */
	bu_log("ERROR: Unable to write to crash report file [%s]\n", filename);
	(void)fclose(fp);
	fp = NULL;
	return 0;
    }

    /* write out the backtrace */
    fprintf(fp, "Call stack backtrace (thread %d):\n", bu_parallel_id());
    fflush(fp);
    if (bu_backtrace(fp) == 0) {
	bu_log("WARNING: Unable to obtain a call stack backtrace\n");
    }

    /* write out operating system information */
    path = bu_which("uname");
    if (path) {
	snprintf(buffer, CR_BUFSIZE, "%s -a 2>&1", path);
#if defined(HAVE_POPEN) && !defined(STRICT_FLAGS)
	popenfp = popen(buffer, "r");
	if (!popenfp) {
	    perror("unable to popen uname");
	    bu_log("WARNING: Unable to obtain uname information\n");
	}
#endif
	if (popenfp) {
	    fprintf(fp, "\nSystem characteristics:\n");
	    fflush(fp);
	    while (bu_fgets(buffer, CR_BUFSIZE, popenfp)) {
		size_t ret;
		size_t len;

		len = strlen(buffer);
		ret = fwrite(buffer, 1, len, fp);
		if (ret != len)
		    perror("fwrite failed");
	    }
	}
#if defined(HAVE_POPEN) && !defined(STRICT_FLAGS)
	(void)pclose(popenfp);
#endif
	popenfp = NULL;
	path = NULL;
    }

    /* write out kernel and hardware information */
    path = bu_which("sysctl");
    if (path) {
	/* need 2>&1 to capture stderr junk from sysctl on Mac OS X for kern.exec */
	snprintf(buffer, CR_BUFSIZE, "%s -a 2>&1", path);
#if defined(HAVE_POPEN) && !defined(STRICT_FLAGS)
	popenfp = popen(buffer, "r");
	if (popenfp == (FILE *)NULL) {
	    perror("unable to popen sysctl");
	    bu_log("WARNING: Unable to obtain sysctl information\n");
	}
#endif
	if (popenfp != (FILE *)NULL) {
	    fprintf(fp, "\nSystem information:\n");
	    fflush(fp);
	    while (bu_fgets(buffer, CR_BUFSIZE, popenfp)) {
		size_t ret;
		size_t len;

		len = strlen(buffer);
		if ((len == 0)
		    || ((len == 1) && (buffer[0] == '\n')))
		{
		    continue;
		}

		ret = fwrite(buffer, 1, len, fp);
		if (ret != len)
		    perror("fwrite failed");
	    }
	}
#if defined(HAVE_POPEN) && !defined(STRICT_FLAGS)
	(void)pclose(popenfp);
#endif
	popenfp = NULL;
	path = NULL;
    }

    memset(buffer, 0, CR_BUFSIZE);
    fprintf(fp, "\n");
    fflush(fp);
    (void)fclose(fp);
    fp = NULL;

    /* success */
    return 1;
}