bazel syntax: avoid perror(3) in async signal handler

I forgot how much I loathe string manipulation in pure C.

Fixes https://github.com/bazelbuild/bazel/issues/10726

PiperOrigin-RevId: 294225300
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/CpuProfiler.java b/src/main/java/com/google/devtools/build/lib/syntax/CpuProfiler.java
index 689df67..52e863f 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/CpuProfiler.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/CpuProfiler.java
@@ -71,12 +71,12 @@
 // thread's stack sampling, during which Starlark execution may have
 // moved on to another function. Assuming uniform delay, this is
 // equivalent to shifting the phase but not the frequency of CPU ticks.
-// Nonetheless it may may bias the profile because, for example,
+// Nonetheless it may bias the profile because, for example,
 // it would cause a Starlark 'sleep' function to accrue a nonzero
 // number of CPU ticks that properly belong to the preceding computation.
 //
 // When a Starlark thread leaves any function, it reads and clears
-// it counter of CPU ticks. If the counter was nonzero, the thread
+// its counter of CPU ticks. If the counter was nonzero, the thread
 // writes a copy of its stack to the profiler log in pprof form,
 // which is a gzip-compressed stream of protocol messages.
 //
@@ -240,8 +240,7 @@
   // Returns false if SIGPROF is already in use.
   private static native boolean startTimer(long periodMicros);
 
-  // Stops the operating system's interval timer
-  // and closes the write end of the pipe.
+  // Stops the operating system's interval timer.
   private static native void stopTimer();
 
   // Returns the operating system's identifier for the calling thread.
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/cpu_profiler_posix.cc b/src/main/java/com/google/devtools/build/lib/syntax/cpu_profiler_posix.cc
index a67ef63..1d42662 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/cpu_profiler_posix.cc
+++ b/src/main/java/com/google/devtools/build/lib/syntax/cpu_profiler_posix.cc
@@ -76,7 +76,14 @@
           "events\n";
       write(2, msg, strlen(msg));
     } else {
-      perror("write");
+      // We shouldn't use perror in a signal handler.
+      // Strictly, we shouldn't use strerror either,
+      // but for all errors returned by write it merely
+      // returns a constant.
+      char buf[1024] = "write: ";
+      strncat(buf, strerror(errno), sizeof buf - strlen(buf) - 1);
+      strncat(buf, "\n", sizeof buf - strlen(buf) - 1);
+      write(2, buf, strlen(buf));
       abort();
     }
   }