Print thread IDs nicely.
[openssl.git] / apps / openssl.c
index 119d3e8ff679622df8726b5fdd4ec7ed3754cc08..d6820a191e4f82877c5fc347b9db01797c3cc9d6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -118,6 +118,8 @@ static char *make_config_name(void)
     return p;
 }
 
+
+#ifndef OPENSSL_NO_TRACE
 typedef struct tracedata_st {
     BIO *bio;
     unsigned int ingroup:1;
@@ -128,11 +130,8 @@ static size_t internal_trace_cb(const char *buf, size_t cnt,
 {
     int ret = 0;
     tracedata *trace_data = vdata;
-    union {
-        CRYPTO_THREAD_ID tid;
-        unsigned long ltid;
-    } tid;
-    char buffer[256];
+    char buffer[256], *hex;
+    CRYPTO_THREAD_ID tid;
 
     switch (cmd) {
     case OSSL_TRACE_CTRL_BEGIN:
@@ -140,11 +139,11 @@ static size_t internal_trace_cb(const char *buf, size_t cnt,
             return 0;
         trace_data->ingroup = 1;
 
-        tid.ltid = 0;
-        tid.tid = CRYPTO_THREAD_get_current_id();
-
-        BIO_snprintf(buffer, sizeof(buffer), "TRACE[%lx]:%s: ", tid.ltid,
-                     OSSL_trace_get_category_name(category));
+        tid = CRYPTO_THREAD_get_current_id();
+        hex = OPENSSL_buf2hexstr((const unsigned char *)&tid, sizeof(tid));
+        BIO_snprintf(buffer, sizeof(buffer), "TRACE[%s]:%s: ",
+                     hex, OSSL_trace_get_category_name(category));
+        OPENSSL_free(hex);
         BIO_ctrl(trace_data->bio, PREFIX_CTRL_SET_PREFIX,
                  strlen(buffer), buffer);
         break;
@@ -183,10 +182,44 @@ static void cleanup_trace(void)
     sk_tracedata_pop_free(trace_data_stack, tracedata_free);
 }
 
+static void setup_trace_category(int category)
+{
+    BIO *channel;
+    tracedata *trace_data;
+
+    if (OSSL_trace_enabled(category))
+        return;
+
+    channel = BIO_push(BIO_new(apps_bf_prefix()),
+                       dup_bio_err(FORMAT_TEXT));
+    trace_data = OPENSSL_zalloc(sizeof(*trace_data));
+
+    if (trace_data == NULL
+        || (trace_data->bio = channel) == NULL
+        || OSSL_trace_set_callback(category, internal_trace_cb,
+                                   trace_data) == 0
+        || sk_tracedata_push(trace_data_stack, trace_data) == 0) {
+
+        fprintf(stderr,
+                "warning: unable to setup trace callback for category '%s'.\n",
+                OSSL_trace_get_category_name(category));
+
+        OSSL_trace_set_callback(category, NULL, NULL);
+        BIO_free_all(channel);
+    }
+}
+
 static void setup_trace(const char *str)
 {
     char *val;
 
+    /*
+     * We add this handler as early as possible to ensure it's executed
+     * as late as possible, i.e. after the TRACE code has done its cleanup
+     * (which happens last in OPENSSL_cleanup).
+     */
+    atexit(cleanup_trace);
+
     trace_data_stack = sk_tracedata_new_null();
     val = OPENSSL_strdup(str);
 
@@ -197,33 +230,22 @@ static void setup_trace(const char *str)
         for (valp = val; (item = strtok(valp, ",")) != NULL; valp = NULL) {
             int category = OSSL_trace_get_category_num(item);
 
-            if (category >= 0) {
-                BIO *channel = BIO_push(BIO_new(apps_bf_prefix()),
-                                        dup_bio_err(FORMAT_TEXT));
-                tracedata *trace_data = OPENSSL_zalloc(sizeof(*trace_data));
-
-                if (trace_data == NULL
-                    || (trace_data->bio = channel) == NULL
-                    || OSSL_trace_set_callback(category, internal_trace_cb,
-                                               trace_data) == 0
-                    || sk_tracedata_push(trace_data_stack, trace_data) == 0) {
-                    OSSL_trace_set_callback(category, NULL, NULL);
-                    BIO_free_all(channel);
-                    fprintf(stderr,
-                            "warning: unable to setup trace callback for category '%s'.\n",
-                            item);
-                }
+            if (category == OSSL_TRACE_CATEGORY_ALL) {
+                while (++category < OSSL_TRACE_CATEGORY_NUM)
+                    setup_trace_category(category);
+                break;
+            } else if (category > 0) {
+                setup_trace_category(category);
             } else {
                 fprintf(stderr,
-                        "warning: unknown trace category: '%s'.\n",
-                        item);
+                        "warning: unknown trace category: '%s'.\n", item);
             }
         }
     }
 
     OPENSSL_free(val);
-    atexit(cleanup_trace);
 }
+#endif /* OPENSSL_NO_TRACE */
 
 int main(int argc, char *argv[])
 {
@@ -260,7 +282,9 @@ int main(int argc, char *argv[])
      */
     atexit(destroy_prefix_method);
 
+#ifndef OPENSSL_NO_TRACE
     setup_trace(getenv("OPENSSL_TRACE"));
+#endif
 
     p = getenv("OPENSSL_DEBUG_MEMORY");
     if (p != NULL && strcmp(p, "on") == 0)
@@ -715,8 +739,9 @@ static void list_type(FUNC_TYPE ft, int one)
 {
     FUNCTION *fp;
     int i = 0;
-    DISPLAY_COLUMNS dc = {0};
+    DISPLAY_COLUMNS dc;
 
+    memset(&dc, 0, sizeof(dc));
     if (!one)
         calculate_columns(&dc);
 
@@ -922,9 +947,6 @@ static void list_disabled(void)
 #ifdef OPENSSL_NO_GOST
     BIO_puts(bio_out, "GOST\n");
 #endif
-#ifdef OPENSSL_NO_HEARTBEATS
-    BIO_puts(bio_out, "HEARTBEATS\n");
-#endif
 #ifdef OPENSSL_NO_IDEA
     BIO_puts(bio_out, "IDEA\n");
 #endif