Improve logging

Adds coloured logging and tweaks the build flags to generate
more meaningful stacktraces.

Change-Id: Iab643a0cf995faacba0fa32424a1f6a0145ed30e
diff --git a/buildtools/BUILD.gn b/buildtools/BUILD.gn
index 6868064..1e3b859 100644
--- a/buildtools/BUILD.gn
+++ b/buildtools/BUILD.gn
@@ -412,6 +412,7 @@
       "//gn/standalone:extra_warnings",
       "//gn/standalone:no_exceptions",
       "//gn/standalone:no_rtti",
+      "//gn/standalone:visibility_hidden",
     ]
     configs += [
       ":libc++config",
@@ -464,6 +465,7 @@
       "//gn/standalone:extra_warnings",
       "//gn/standalone:no_exceptions",
       "//gn/standalone:no_rtti",
+      "//gn/standalone:visibility_hidden",
     ]
     configs += [
       ":libc++config",
diff --git a/gn/standalone/BUILD.gn b/gn/standalone/BUILD.gn
index 59f60fd..9a8ef68 100644
--- a/gn/standalone/BUILD.gn
+++ b/gn/standalone/BUILD.gn
@@ -44,6 +44,10 @@
   cflags = [ "-fno-rtti" ]
 }
 
+config("visibility_hidden") {
+  cflags = [ "-fvisibility=hidden" ]
+}
+
 config("default") {
   asmflags = []
   cflags = []
@@ -89,6 +93,8 @@
       "-mfpmath=sse",
     ]
     ldflags += [ "-m32" ]
+  } else if (current_cpu == "arm64") {
+    cflags += [ "-fno-omit-frame-pointer" ]
   }
 
   if (is_linux) {
@@ -145,26 +151,35 @@
 }
 
 config("debug_symbols") {
-  if (is_android) {
-    cflags = [
-      "-gline-tables-only",
-      "-funwind-tables",
-    ]
-  } else {
-    cflags = [ "-g2" ]
+  cflags = [
+    "-g",
+    "-O0",
+  ]
+  if (is_android || is_linux) {
+    cflags += [ "-funwind-tables" ]
+    ldflags = [ "-rdynamic" ]
   }
 }
 
 config("release") {
   cflags = [
-    "-O3",
     "-fdata-sections",
     "-ffunction-sections",
   ]
+  if (is_android) {
+    cflags += [ "-Oz" ]
+  } else {
+    cflags += [ "-O3" ]
+  }
   if (is_mac) {
     ldflags = [ "-dead_strip" ]
   } else {
-    ldflags = [ "-Wl,--gc-sections" ]
+    ldflags = [
+      "-fuse-ld=gold",
+      "-Wl,--gc-sections",
+      "-Wl,--icf=all",
+      "-Wl,-O1",
+    ]
   }
   defines = [ "NDEBUG" ]
 }
diff --git a/gn/standalone/BUILDCONFIG.gn b/gn/standalone/BUILDCONFIG.gn
index b1d103f..272eb58 100644
--- a/gn/standalone/BUILDCONFIG.gn
+++ b/gn/standalone/BUILDCONFIG.gn
@@ -50,6 +50,7 @@
   "//gn/standalone:extra_warnings",
   "//gn/standalone:no_exceptions",
   "//gn/standalone:no_rtti",
+  "//gn/standalone:visibility_hidden",
   "//gn/standalone/libc++:config",
   "//gn/standalone/sanitizers:sanitizers_cflags",
 ]
diff --git a/include/perfetto/base/logging.h b/include/perfetto/base/logging.h
index 14460d4..2081238 100644
--- a/include/perfetto/base/logging.h
+++ b/include/perfetto/base/logging.h
@@ -18,6 +18,7 @@
 #define INCLUDE_PERFETTO_BASE_LOGGING_H_
 
 #include <errno.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 
@@ -25,39 +26,87 @@
 #define PERFETTO_DCHECK_IS_ON() 0
 #else
 #define PERFETTO_DCHECK_IS_ON() 1
-#include <stdio.h>   // For fprintf.
 #include <string.h>  // For strerror.
 #endif
 
 #include "perfetto/base/utils.h"
 
+namespace perfetto {
+namespace base {
+
+// Constexpr functions to extract basename(__FILE__), e.g.: ../foo/f.c -> f.c .
+constexpr const char* StrEnd(const char* s) {
+  return *s ? StrEnd(s + 1) : s;
+}
+
+constexpr const char* BasenameRecursive(const char* s,
+                                        const char* begin,
+                                        const char* end) {
+  return (*s == '/' && s < end)
+             ? (s + 1)
+             : ((s > begin) ? BasenameRecursive(s - 1, begin, end) : s);
+}
+
+constexpr const char* Basename(const char* str) {
+  return BasenameRecursive(StrEnd(str), str, StrEnd(str));
+}
+
+enum LogLev { kLogDebug = 0, kLogInfo, kLogImportant, kLogError };
+constexpr const char* kLogFmt[] = {"\x1b[2m", "\x1b[39m", "\x1b[32m\x1b[1m",
+                                   "\x1b[31m"};
+
+#define PERFETTO_LOG_LINE__(x) #x
+#define PERFETTO_LOG_LINE_(x) PERFETTO_LOG_LINE__(x)
+#define PERFETTO_LOG_LINE PERFETTO_LOG_LINE_(__LINE__)
+
+#define PERFETTO_XLOG(level, fmt, ...)                                \
+  fprintf(stderr, "\x1b[90m%-24.24s\x1b[0m %s" fmt "\x1b[0m\n",       \
+          ::perfetto::base::Basename(__FILE__ ":" PERFETTO_LOG_LINE), \
+          ::perfetto::base::kLogFmt[::perfetto::base::LogLev::level], \
+          ##__VA_ARGS__)
+
+#define PERFETTO_LOG(fmt, ...) PERFETTO_XLOG(kLogInfo, fmt, ##__VA_ARGS__)
+#define PERFETTO_ILOG(fmt, ...) PERFETTO_XLOG(kLogImportant, fmt, ##__VA_ARGS__)
+#define PERFETTO_ELOG(fmt, ...) PERFETTO_XLOG(kLogError, fmt, ##__VA_ARGS__)
+
 #if PERFETTO_DCHECK_IS_ON()
-#define PERFETTO_DLOG(fmt, ...)                                               \
-  fprintf(stderr, "\n[%s:%d, errno: %d %s]\n" fmt "\n\n", __FILE__, __LINE__, \
-          errno, errno ? strerror(errno) : "", ##__VA_ARGS__)
-#define PERFETTO_DPLOG(...) PERFETTO_DLOG(__VA_ARGS__)
+
+#define PERFETTO_DLOG(fmt, ...) PERFETTO_XLOG(kLogDebug, fmt, ##__VA_ARGS__)
+
+#define PERFETTO_DPLOG(x) \
+  PERFETTO_DLOG("%s (errno: %d, %s)", (x), errno, strerror(errno))
+
 #define PERFETTO_DCHECK(x)                             \
   do {                                                 \
     if (!__builtin_expect(!!(x), true)) {              \
-      PERFETTO_DPLOG("%s", "PERFETTO_CHECK(" #x ")");  \
+      PERFETTO_DPLOG("PERFETTO_CHECK(" #x ")");        \
       *(reinterpret_cast<volatile int*>(0x10)) = 0x42; \
       __builtin_unreachable();                         \
     }                                                  \
   } while (0)
+
 #else
+
 #define PERFETTO_DLOG(...) ::perfetto::base::ignore_result(__VA_ARGS__)
 #define PERFETTO_DPLOG(...) ::perfetto::base::ignore_result(__VA_ARGS__)
 #define PERFETTO_DCHECK(x) ::perfetto::base::ignore_result(x)
+
 #endif  // PERFETTO_DCHECK_IS_ON()
 
 #if PERFETTO_DCHECK_IS_ON()
 #define PERFETTO_CHECK(x) PERFETTO_DCHECK(x)
 #else
-#define PERFETTO_CHECK(x)               \
-  do {                                  \
-    if (!__builtin_expect(!!(x), true)) \
-      abort();                          \
+#define PERFETTO_CHECK(x)                            \
+  do {                                               \
+    if (!__builtin_expect(!!(x), true)) {            \
+      PERFETTO_ELOG("%s", "PERFETTO_CHECK(" #x ")"); \
+      abort();                                       \
+    }                                                \
   } while (0)
+
 #endif  // PERFETTO_DCHECK_IS_ON()
 
+}  // namespace base
+}  // namespace perfetto
+
 #endif  // INCLUDE_PERFETTO_BASE_LOGGING_H_
diff --git a/src/base/android_task_runner.cc b/src/base/android_task_runner.cc
index 6374369..3d5ff6d 100644
--- a/src/base/android_task_runner.cc
+++ b/src/base/android_task_runner.cc
@@ -16,6 +16,7 @@
 
 #include "perfetto/base/android_task_runner.h"
 
+#include <errno.h>
 #include <sys/eventfd.h>
 #include <sys/timerfd.h>
 
@@ -111,6 +112,7 @@
   // run for fairness.
   if (has_next)
     ScheduleImmediateWakeUp();
+  errno = 0;
   immediate_task();
 }
 
@@ -136,6 +138,7 @@
   }
   if (next_wake_up)
     ScheduleDelayedWakeUp(next_wake_up);
+  errno = 0;
   delayed_task();
 }
 
@@ -217,6 +220,7 @@
       return false;
     task = it->second;
   }
+  errno = 0;
   task();
   return true;
 }
diff --git a/src/base/debug_crash_stack_trace.cc b/src/base/debug_crash_stack_trace.cc
index c70225c..931452e 100644
--- a/src/base/debug_crash_stack_trace.cc
+++ b/src/base/debug_crash_stack_trace.cc
@@ -127,7 +127,6 @@
     PrintHex(i);
     Print("  ");
     const char* sym_name = res ? sym_info.dli_sname : nullptr;
-
     if (sym_name) {
       int ignored;
       size_t len = kDemangledNameLen;
@@ -142,7 +141,11 @@
       }
       write(STDERR_FILENO, sym_name, strlen(sym_name));
     } else {
-      Print("???");
+      if (res && sym_info.dli_fname) {
+        write(STDERR_FILENO, sym_info.dli_fname, strlen(sym_info.dli_fname));
+        Print(" ");
+      }
+      PrintHex(frames[i] - reinterpret_cast<uintptr_t>(sym_info.dli_fbase));
     }
     Print("\n");
   }
diff --git a/src/base/unix_task_runner.cc b/src/base/unix_task_runner.cc
index cfac561..262039a 100644
--- a/src/base/unix_task_runner.cc
+++ b/src/base/unix_task_runner.cc
@@ -18,6 +18,7 @@
 
 #include "perfetto/base/build_config.h"
 
+#include <errno.h>
 #include <fcntl.h>
 #include <stdlib.h>
 #include <unistd.h>
@@ -135,8 +136,12 @@
       }
     }
   }
+
+  errno = 0;
   if (immediate_task)
     immediate_task();
+
+  errno = 0;
   if (delayed_task)
     delayed_task();
 }
@@ -189,6 +194,7 @@
     poll_fds_[fd_index].fd = fd;
     task = it->second.callback;
   }
+  errno = 0;
   task();
 }