コード例 #1
0
ファイル: jsapi-private.cpp プロジェクト: Katyunechka/gjs
void
gjs_error_reporter(JSContext     *context,
                   const char    *message,
                   JSErrorReport *report)
{
    const char *warning;

    if (gjs_environment_variable_is_set("GJS_ABORT_ON_OOM") &&
        report->flags == JSREPORT_ERROR &&
        report->errorNumber == JSMSG_OUT_OF_MEMORY) {
        g_error("GJS ran out of memory at %s: %i.",
                report->filename,
                report->lineno);
    }

    if ((report->flags & JSREPORT_WARNING) != 0) {
        /* We manually insert "WARNING" into the output instead of
         * having GJS_DEBUG_WARNING because it's convenient to
         * search for 'JS ERROR' to find all problems
         */
        warning = "WARNING: ";

        /* suppress bogus warnings. See mozilla/js/src/js.msg */
        switch (report->errorNumber) {
            /* 162, JSMSG_UNDEFINED_PROP: warns every time a lazy property
             * is resolved, since the property starts out
             * undefined. When this is a real bug it should usually
             * fail somewhere else anyhow.
             */
        case 162:
            return;
        }
    } else {
        warning = "REPORTED: ";
    }

    gjs_debug(GJS_DEBUG_ERROR,
              "%s'%s'",
              warning,
              message);

    gjs_debug(GJS_DEBUG_ERROR,
              "%sfile '%s' line %u exception %d number %d",
              warning,
              report->filename, report->lineno,
              (report->flags & JSREPORT_EXCEPTION) != 0,
              report->errorNumber);
}
コード例 #2
0
void
gjs_debug(GjsDebugTopic topic,
          const char   *format,
          ...)
{
    static FILE *logfp = NULL;
    static gboolean debug_log_enabled = FALSE;
    static gboolean strace_timestamps = FALSE;
    static gboolean checked_for_timestamp = FALSE;
    static gboolean print_timestamp = FALSE;
    static GTimer *timer = NULL;
    const char *prefix;
    va_list args;
    char *s;

    if (!checked_for_timestamp) {
        print_timestamp = gjs_environment_variable_is_set("GJS_DEBUG_TIMESTAMP");
        checked_for_timestamp = TRUE;
    }

    if (print_timestamp && !timer) {
        timer = g_timer_new();
    }

    if (logfp == NULL) {
        const char *debug_output = g_getenv("GJS_DEBUG_OUTPUT");
        if (debug_output != NULL &&
            strcmp(debug_output, "stderr") == 0) {
            debug_log_enabled = TRUE;
        } else if (debug_output != NULL) {
            const char *log_file;
            char *free_me;
            char *c;

            /* Allow debug-%u.log for per-pid logfiles as otherwise log
             * messages from multiple processes can overwrite each other.
             *
             * (printf below should be safe as we check '%u' is the only format
             * string)
             */
            c = strchr((char *) debug_output, '%');
            if (c && c[1] == 'u' && !strchr(c+1, '%')) {
                free_me = g_strdup_printf(debug_output, (guint)getpid());
                log_file = free_me;
            } else {
                log_file = debug_output;
                free_me = NULL;
            }

            /* avoid truncating in case we're using shared logfile */
            logfp = fopen(log_file, "a");
            if (!logfp)
                fprintf(stderr, "Failed to open log file `%s': %s\n",
                        log_file, g_strerror(errno));

            g_free(free_me);

            debug_log_enabled = TRUE;
        }

        if (logfp == NULL)
            logfp = stderr;

        strace_timestamps = gjs_environment_variable_is_set("GJS_STRACE_TIMESTAMPS");
    }

    /* only strace timestamps if debug
     * log wasn't specifically switched on
     */
    if (!debug_log_enabled &&
        topic != GJS_DEBUG_STRACE_TIMESTAMP)
        return;

    switch (topic) {
    case GJS_DEBUG_STRACE_TIMESTAMP:
        /* return early if strace timestamps are disabled, avoiding
         * printf format overhead and so forth.
         */
        if (!strace_timestamps)
            return;
        /* this is a special magic topic for use with
         * git clone http://www.gnome.org/~federico/git/performance-scripts.git
         * http://www.gnome.org/~federico/news-2006-03.html#timeline-tools
         */
        prefix = "MARK";
        break;
    case GJS_DEBUG_GI_USAGE:
        prefix = "JS GI USE";
        break;
    case GJS_DEBUG_MEMORY:
        prefix = "JS MEMORY";
        break;
    case GJS_DEBUG_CONTEXT:
        prefix = "JS CTX";
        break;
    case GJS_DEBUG_IMPORTER:
        prefix = "JS IMPORT";
        break;
    case GJS_DEBUG_NATIVE:
        prefix = "JS NATIVE";
        break;
    case GJS_DEBUG_KEEP_ALIVE:
        prefix = "JS KP ALV";
        break;
    case GJS_DEBUG_GREPO:
        prefix = "JS G REPO";
        break;
    case GJS_DEBUG_GNAMESPACE:
        prefix = "JS G NS";
        break;
    case GJS_DEBUG_GOBJECT:
        prefix = "JS G OBJ";
        break;
    case GJS_DEBUG_GFUNCTION:
        prefix = "JS G FUNC";
        break;
    case GJS_DEBUG_GCLOSURE:
        prefix = "JS G CLSR";
        break;
    case GJS_DEBUG_GBOXED:
        prefix = "JS G BXD";
        break;
    case GJS_DEBUG_GENUM:
        prefix = "JS G ENUM";
        break;
    case GJS_DEBUG_GPARAM:
        prefix = "JS G PRM";
        break;
    case GJS_DEBUG_DATABASE:
        prefix = "JS DB";
        break;
    case GJS_DEBUG_RESULTSET:
        prefix = "JS RS";
        break;
    case GJS_DEBUG_WEAK_HASH:
        prefix = "JS WEAK";
        break;
    case GJS_DEBUG_MAINLOOP:
        prefix = "JS MAINLOOP";
        break;
    case GJS_DEBUG_PROPS:
        prefix = "JS PROPS";
        break;
    case GJS_DEBUG_SCOPE:
        prefix = "JS SCOPE";
        break;
    case GJS_DEBUG_HTTP:
        prefix = "JS HTTP";
        break;
    case GJS_DEBUG_BYTE_ARRAY:
        prefix = "JS BYTE ARRAY";
        break;
    case GJS_DEBUG_GERROR:
        prefix = "JS G ERR";
        break;
    default:
        prefix = "???";
        break;
    }

    if (!is_allowed_prefix(prefix))
        return;

    va_start (args, format);
    s = g_strdup_vprintf (format, args);
    va_end (args);

    if (topic == GJS_DEBUG_STRACE_TIMESTAMP) {
        /* Put a magic string in strace output */
        char *s2;
        s2 = g_strdup_printf("%s: gjs: %s",
                             prefix, s);
        access(s2, F_OK);
        g_free(s2);
    } else {
        if (print_timestamp) {
            static gdouble previous = 0.0;
            gdouble total = g_timer_elapsed(timer, NULL) * 1000.0;
            gdouble since = total - previous;
            const char *ts_suffix;
            char *s2;

            if (since > 50.0) {
                ts_suffix = "!!  ";
            } else if (since > 100.0) {
                ts_suffix = "!!! ";
            } else if (since > 200.0) {
                ts_suffix = "!!!!";
            } else {
                ts_suffix = "    ";
            }

            s2 = g_strdup_printf("%g %s%s",
                                 total, ts_suffix, s);
            g_free(s);
            s = s2;

            previous = total;
        }

        write_to_stream(logfp, prefix, s);
    }

    g_free(s);
}