Fix CFI initialization crash on x86.

Third try.

Bug: 34752378
Test: bionic tests
Change-Id: I247c127489a8ee38404e104f28d916a704e35f36
diff --git a/tests/utils.h b/tests/utils.h
index 79eed10..eac6f31 100644
--- a/tests/utils.h
+++ b/tests/utils.h
@@ -125,8 +125,13 @@
 static inline void AssertChildExited(int pid, int expected_exit_status) {
   int status;
   ASSERT_EQ(pid, waitpid(pid, &status, 0));
-  ASSERT_TRUE(WIFEXITED(status));
-  ASSERT_EQ(expected_exit_status, WEXITSTATUS(status));
+  if (expected_exit_status >= 0) {
+    ASSERT_TRUE(WIFEXITED(status));
+    ASSERT_EQ(expected_exit_status, WEXITSTATUS(status));
+  } else {
+    ASSERT_TRUE(WIFSIGNALED(status));
+    ASSERT_EQ(-expected_exit_status, WTERMSIG(status));
+  }
 }
 
 // The absolute path to the executable
@@ -142,4 +147,62 @@
 char** get_argv();
 char** get_envp();
 
+// ExecTestHelper is only used in bionic and glibc tests.
+#ifndef __APPLE__
+class ExecTestHelper {
+ public:
+  char** GetArgs() {
+    return const_cast<char**>(args_.data());
+  }
+  char** GetEnv() {
+    return const_cast<char**>(env_.data());
+  }
+
+  void SetArgs(const std::vector<const char*> args) {
+    args_ = args;
+  }
+  void SetEnv(const std::vector<const char*> env) {
+    env_ = env;
+  }
+
+  void Run(const std::function<void()>& child_fn, int expected_exit_status,
+           const char* expected_output) {
+    int fds[2];
+    ASSERT_NE(pipe(fds), -1);
+
+    pid_t pid = fork();
+    ASSERT_NE(pid, -1);
+
+    if (pid == 0) {
+      // Child.
+      close(fds[0]);
+      dup2(fds[1], STDOUT_FILENO);
+      dup2(fds[1], STDERR_FILENO);
+      if (fds[1] != STDOUT_FILENO && fds[1] != STDERR_FILENO) close(fds[1]);
+      child_fn();
+      FAIL();
+    }
+
+    // Parent.
+    close(fds[1]);
+    std::string output;
+    char buf[BUFSIZ];
+    ssize_t bytes_read;
+    while ((bytes_read = TEMP_FAILURE_RETRY(read(fds[0], buf, sizeof(buf)))) > 0) {
+      output.append(buf, bytes_read);
+    }
+    close(fds[0]);
+
+    AssertChildExited(pid, expected_exit_status);
+    if (expected_output != nullptr) {
+      ASSERT_EQ(expected_output, output);
+    }
+  }
+
+ private:
+  std::vector<const char*> args_;
+  std::vector<const char*> env_;
+};
+#endif
+
 #endif