src/jdk.jdwp.agent/share/native/libjdwp/log_messages.c
changeset 47216 71c04702a3d5
parent 26223 3830bfd8440a
child 48235 8db54e2c453b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jdwp.agent/share/native/libjdwp/log_messages.c	Tue Sep 12 19:03:39 2017 +0200
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "util.h"
+
+#include <time.h>
+#include <errno.h>
+#include <sys/types.h>
+
+#include "proc_md.h"
+
+#include "log_messages.h"
+
+#ifdef JDWP_LOGGING
+
+#define MAXLEN_INTEGER          20
+#define MAXLEN_FILENAME         256
+#define MAXLEN_TIMESTAMP        80
+#define MAXLEN_LOCATION         (MAXLEN_FILENAME+MAXLEN_INTEGER+16)
+#define MAXLEN_MESSAGE          256
+#define MAXLEN_EXEC             (MAXLEN_FILENAME*2+MAXLEN_INTEGER+16)
+
+static MUTEX_T my_mutex = MUTEX_INIT;
+
+/* Static variables (should be protected with mutex) */
+static int logging;
+static FILE * log_file;
+static char logging_filename[MAXLEN_FILENAME+1+6];
+static char location_stamp[MAXLEN_LOCATION+1];
+static PID_T processPid;
+static int open_count;
+
+/* Ascii id of current native thread. */
+static void
+get_time_stamp(char *tbuf, size_t ltbuf)
+{
+    char timestamp_prefix[MAXLEN_TIMESTAMP+1];
+    char timestamp_postfix[MAXLEN_TIMESTAMP+1];
+    unsigned millisecs = 0;
+    time_t t = 0;
+
+    GETMILLSECS(millisecs);
+    if ( time(&t) == (time_t)(-1) ) {
+        t = 0;
+    }
+    /* Break this up so that the format strings are string literals
+       and we avoid a compiler warning. */
+    (void)strftime(timestamp_prefix, sizeof(timestamp_prefix),
+                "%d.%m.%Y %T", localtime(&t));
+    (void)strftime(timestamp_postfix, sizeof(timestamp_postfix),
+                "%Z", localtime(&t));
+    (void)snprintf(tbuf, ltbuf,
+                   "%s.%.3d %s", timestamp_prefix,
+                   (int)(millisecs), timestamp_postfix);
+}
+
+/* Get basename of filename */
+static const char *
+file_basename(const char *file)
+{
+    char *p1;
+    char *p2;
+
+    if ( file==NULL )
+        return "unknown";
+    p1 = strrchr(file, '\\');
+    p2 = strrchr(file, '/');
+    p1 = ((p1 > p2) ? p1 : p2);
+    if (p1 != NULL) {
+        file = p1 + 1;
+    }
+    return file;
+}
+
+/* Fill in the exact source location of the LOG entry. */
+static void
+fill_location_stamp(const char *flavor, const char *file, int line)
+{
+    (void)snprintf(location_stamp, sizeof(location_stamp),
+                    "%s:\"%s\":%d;",
+                    flavor, file_basename(file), line);
+    location_stamp[sizeof(location_stamp)-1] = 0;
+}
+
+/* Begin a log entry. */
+void
+log_message_begin(const char *flavor, const char *file, int line)
+{
+    MUTEX_LOCK(my_mutex); /* Unlocked in log_message_end() */
+    if ( logging ) {
+        location_stamp[0] = 0;
+        fill_location_stamp(flavor, file, line);
+    }
+}
+
+/* Standard Logging Format Entry */
+static void
+standard_logging_format(FILE *fp,
+        const char *datetime,
+        const char *level,
+        const char *product,
+        const char *module,
+        const char *optional,
+        const char *messageID,
+        const char *message)
+{
+    const char *format;
+
+    /* "[#|Date&Time&Zone|LogLevel|ProductName|ModuleID|
+     *     OptionalKey1=Value1;OptionalKeyN=ValueN|MessageID:MessageText|#]\n"
+     */
+
+    format="[#|%s|%s|%s|%s|%s|%s:%s|#]\n";
+
+    print_message(fp, "", "", format,
+            datetime,
+            level,
+            product,
+            module,
+            optional,
+            messageID,
+            message);
+}
+
+/* End a log entry */
+void
+log_message_end(const char *format, ...)
+{
+    if ( logging ) {
+        va_list ap;
+        THREAD_T tid;
+        char datetime[MAXLEN_TIMESTAMP+1];
+        const char *level;
+        const char *product;
+        const char *module;
+        char optional[MAXLEN_INTEGER+6+MAXLEN_INTEGER+6+MAXLEN_LOCATION+1];
+        const char *messageID;
+        char message[MAXLEN_MESSAGE+1];
+
+        /* Grab the location, start file if needed, and clear the lock */
+        if ( log_file == NULL && open_count == 0 && logging_filename[0] != 0 ) {
+            open_count++;
+            log_file = fopen(logging_filename, "w");
+            if ( log_file!=NULL ) {
+                (void)setvbuf(log_file, NULL, _IOLBF, BUFSIZ);
+            } else {
+                logging = 0;
+            }
+        }
+
+        if ( log_file != NULL ) {
+
+            /* Get the rest of the needed information */
+            tid = GET_THREAD_ID();
+            level = "FINEST"; /* FIXUP? */
+            product = "J2SE1.5"; /* FIXUP? */
+            module = "jdwp"; /* FIXUP? */
+            messageID = ""; /* FIXUP: Unique message string ID? */
+            (void)snprintf(optional, sizeof(optional),
+                        "LOC=%s;PID=%d;THR=t@%d",
+                        location_stamp,
+                        (int)processPid,
+                        (int)(intptr_t)tid);
+
+            /* Construct message string. */
+            va_start(ap, format);
+            (void)vsnprintf(message, sizeof(message), format, ap);
+            va_end(ap);
+
+            get_time_stamp(datetime, sizeof(datetime));
+
+            /* Send out standard logging format message */
+            standard_logging_format(log_file,
+                datetime,
+                level,
+                product,
+                module,
+                optional,
+                messageID,
+                message);
+        }
+        location_stamp[0] = 0;
+    }
+    MUTEX_UNLOCK(my_mutex); /* Locked in log_message_begin() */
+}
+
+#endif
+
+/* Set up the logging with the name of a logging file. */
+void
+setup_logging(const char *filename, unsigned flags)
+{
+#ifdef JDWP_LOGGING
+    FILE *fp = NULL;
+
+    /* Turn off logging */
+    logging = 0;
+    gdata->log_flags = 0;
+
+    /* Just return if not doing logging */
+    if ( filename==NULL || flags==0 )
+        return;
+
+    /* Create potential filename for logging */
+    processPid = GETPID();
+    (void)snprintf(logging_filename, sizeof(logging_filename),
+                    "%s.%d", filename, (int)processPid);
+
+    /* Turn on logging (do this last) */
+    logging = 1;
+    gdata->log_flags = flags;
+
+#endif
+}
+
+/* Finish up logging, flush output to the logfile. */
+void
+finish_logging()
+{
+#ifdef JDWP_LOGGING
+    MUTEX_LOCK(my_mutex);
+    if ( logging ) {
+        logging = 0;
+        if ( log_file != NULL ) {
+            (void)fflush(log_file);
+            (void)fclose(log_file);
+            log_file = NULL;
+        }
+    }
+    MUTEX_UNLOCK(my_mutex);
+#endif
+}