GN standalone: extra_{target,host}_cflags + fstack-protector-strong

- Switch to -fstack-protector-strong. CrOS prefers that and there
  doesn't seem to be a good reason for not applying it globally to
  our standalone builds.
- Introduce a new set extra_{target,host}_{c,cxx,ld}flags. This is
  to allow the embedder overriding flags only for one toolchain.
  For context see https://chromium-review.googlesource.com/c/chromiumos/overlays/chromiumos-overlay/+/2251681
- Allow the embedder to disable the stacktrace reporting on
  debug builds, as that require a further dependency on
  libbacktrace.

Bug: 147789115
Change-Id: I1c1f9c8853bac9e97702c060db51fefdb9ed963e
diff --git a/docs/contributing/build-instructions.md b/docs/contributing/build-instructions.md
index 2bc82ae..109cff3 100644
--- a/docs/contributing/build-instructions.md
+++ b/docs/contributing/build-instructions.md
@@ -165,5 +165,15 @@
 `is_ubsan = true`:  
 Enables [Undefined Behavior Sanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html)
 
+`extra_{cflags,cxxflags, ldflags} = "-fXXX"`:  
+This is the moral equivalent of the common Makefile practice:
+`CFLAGS=...` `CXXFLAGS=...` `LDFLAGS=...`.
+If you want to propagate these env variables into GN, set:
+`extra_cxxflags=\"$CXXFLAGS\"`.
+See the [build_fuzzers](/infra/oss-fuzz/build_fuzzers) script for an example.
+Note that these flags will be appended both to target and host toolchains.
+If you want to append flags only to one toolchain use, respectively,
+`extra_target_{cflags,cxxflags,ldflags}` and
+`extra_host_{cflags,cxxflags,ldflags}`.
 
 [gn-quickstart]: https://gn.googlesource.com/gn/+/master/docs/quick_start.md
diff --git a/gn/perfetto.gni b/gn/perfetto.gni
index 42aa474..dd79c2a 100644
--- a/gn/perfetto.gni
+++ b/gn/perfetto.gni
@@ -203,6 +203,12 @@
   # none ("off"). We disable it by default for embedders to avoid spamming their
   # console.
   perfetto_force_dlog = perfetto_force_dlog_default
+
+  # Installs a signal handler for the most common crash signals which unwinds
+  # the stack and prints the stack trace on stderr. Requires a dependency on
+  # libbacktrace when enabled.
+  enable_perfetto_stderr_crash_dump =
+      is_debug && perfetto_build_standalone && !is_wasm
 }
 
 declare_args() {
diff --git a/gn/standalone/BUILD.gn b/gn/standalone/BUILD.gn
index f11bb5f..40127a6 100644
--- a/gn/standalone/BUILD.gn
+++ b/gn/standalone/BUILD.gn
@@ -93,7 +93,7 @@
 
   cflags += [
     "-fstrict-aliasing",
-    "-fstack-protector",
+    "-fstack-protector-strong",
     "-fPIC",
     "-g",
     "-Wformat",
diff --git a/gn/standalone/BUILDCONFIG.gn b/gn/standalone/BUILDCONFIG.gn
index e6117a4..aa0c2bc 100644
--- a/gn/standalone/BUILDCONFIG.gn
+++ b/gn/standalone/BUILDCONFIG.gn
@@ -18,9 +18,8 @@
   is_system_compiler = false
   is_lto = false
 
-  extra_cflags = ""
-  extra_cxxflags = ""
-  extra_ldflags = ""
+  # This is defined here because it's needed below for determining the value of
+  # |is_cross_compiling|.
   target_triplet = ""
 }
 
diff --git a/gn/standalone/toolchain/BUILD.gn b/gn/standalone/toolchain/BUILD.gn
index 8c3c36d..9f9bd61 100644
--- a/gn/standalone/toolchain/BUILD.gn
+++ b/gn/standalone/toolchain/BUILD.gn
@@ -26,6 +26,21 @@
 
 declare_args() {
   cc_wrapper = ""
+
+  # These apply to both target and host toolchains.
+  extra_cflags = ""
+  extra_cxxflags = ""
+  extra_ldflags = ""
+
+  # These apply only to the target toolchain.
+  extra_target_cflags = ""
+  extra_target_cxxflags = ""
+  extra_target_ldflags = ""
+
+  # These apply only to the host toolchain.
+  extra_host_cflags = ""
+  extra_host_cxxflags = ""
+  extra_host_ldflags = ""
 }
 
 # First of all determine the host toolchain. The user can override this by:
@@ -153,6 +168,9 @@
     lib_switch = "-l"
     lib_dir_switch = "-L"
     ld_arg = ""
+    external_cflags = ""
+    external_cxxflags = ""
+    external_ldflags = ""
     if (defined(invoker.linker) && invoker.linker != "") {
       _invoker_linker = invoker.linker
       ld_arg = "-fuse-ld=$_invoker_linker"
@@ -167,10 +185,19 @@
       _invoker_gcc_toolchain = invoker.gcc_toolchain
       ld_arg = "$ld_arg --gcc-toolchain=$_invoker_gcc_toolchain"
     }
+    if (defined(invoker.external_cflags)) {
+      external_cflags = invoker.external_cflags
+    }
+    if (defined(invoker.external_cxxflags)) {
+      external_cxxflags = invoker.external_cxxflags
+    }
+    if (defined(invoker.external_ldflags)) {
+      external_ldflags = invoker.external_ldflags
+    }
 
     tool("cc") {
       depfile = "{{output}}.d"
-      command = "$cc_wrapper $cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} ${extra_cflags} -c {{source}} -o {{output}}"
+      command = "$cc_wrapper $cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} ${external_cflags} -c {{source}} -o {{output}}"
       depsformat = "gcc"
       outputs =
           [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ]
@@ -179,7 +206,7 @@
 
     tool("cxx") {
       depfile = "{{output}}.d"
-      command = "$cc_wrapper $cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}}  ${extra_cflags} ${extra_cxxflags} -c {{source}} -o {{output}}"
+      command = "$cc_wrapper $cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}}  ${external_cflags} ${external_cxxflags} -c {{source}} -o {{output}}"
       depsformat = "gcc"
       outputs =
           [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ]
@@ -219,7 +246,7 @@
         rpath = "-Wl,-install_name,@rpath/$soname"
       }
 
-      command = "$cc_wrapper $cxx $ld_arg -shared {{ldflags}} ${extra_ldflags} {{inputs}} {{solibs}} {{libs}} $rpath -o {{output}}"
+      command = "$cc_wrapper $cxx $ld_arg -shared {{ldflags}} ${external_ldflags} {{inputs}} {{solibs}} {{libs}} $rpath -o {{output}}"
       outputs = [ "{{root_out_dir}}/$soname" ]
       output_prefix = "lib"
       default_output_extension = ".so"
@@ -227,7 +254,7 @@
     }
 
     tool("link") {
-      command = "$cc_wrapper $cxx $ld_arg {{ldflags}} ${extra_ldflags} {{inputs}} {{solibs}} {{libs}} -o {{output}}"
+      command = "$cc_wrapper $cxx $ld_arg {{ldflags}} ${external_ldflags} {{inputs}} {{solibs}} {{libs}} -o {{output}}"
       outputs =
           [ "{{root_out_dir}}/{{target_output_name}}{{output_extension}}" ]
       description = "link {{output}}"
@@ -259,6 +286,21 @@
   linker = target_linker
   sysroot = target_sysroot
   gcc_toolchain = target_gcc_toolchain
+  external_cflags = string_join(" ",
+                                [
+                                  extra_cflags,
+                                  extra_target_cflags,
+                                ])
+  external_cxxflags = string_join(" ",
+                                  [
+                                    extra_cxxflags,
+                                    extra_target_cxxflags,
+                                  ])
+  external_ldflags = string_join(" ",
+                                 [
+                                   extra_ldflags,
+                                   extra_target_ldflags,
+                                 ])
 }
 
 gcc_like_toolchain("gcc_like_host") {
@@ -270,6 +312,21 @@
   linker = linker
   sysroot = sysroot
   gcc_toolchain = gcc_toolchain
+  external_cflags = string_join(" ",
+                                [
+                                  extra_cflags,
+                                  extra_host_cflags,
+                                ])
+  external_cxxflags = string_join(" ",
+                                  [
+                                    extra_cxxflags,
+                                    extra_host_cxxflags,
+                                  ])
+  external_ldflags = string_join(" ",
+                                 [
+                                   extra_ldflags,
+                                   extra_host_ldflags,
+                                 ])
 }
 
 gcc_like_toolchain("wasm") {
diff --git a/src/base/BUILD.gn b/src/base/BUILD.gn
index 083faf3..055d70d 100644
--- a/src/base/BUILD.gn
+++ b/src/base/BUILD.gn
@@ -17,8 +17,6 @@
 import("../../gn/test.gni")
 import("../../gn/wasm.gni")
 
-enable_stack_trace = is_debug && perfetto_build_standalone && !is_wasm
-
 source_set("base") {
   deps = [ "../../gn:default_deps" ]
   public_deps = [
@@ -53,12 +51,12 @@
     ]
   }
 
-  if (enable_stack_trace) {
+  if (enable_perfetto_stderr_crash_dump) {
     deps += [ ":debug_crash_stack_trace" ]
   }
 }
 
-if (enable_stack_trace) {
+if (enable_perfetto_stderr_crash_dump) {
   source_set("debug_crash_stack_trace") {
     sources = [ "debug_crash_stack_trace.cc" ]
     deps = [