diff options
author | Josh Gao <jmgao@google.com> | 2017-03-24 16:26:03 -0700 |
---|---|---|
committer | Josh Gao <jmgao@google.com> | 2017-03-27 16:11:38 -0700 |
commit | ae9d7676a50875a58742797ac79b597017d492e8 (patch) | |
tree | 76b15c7a8424e9603656cf385fe2dfa24bab6b51 /debuggerd/client/debuggerd_client_test.cpp | |
parent | c0ca39c41ae2255ba86517ebe11c72b1fc44700d (diff) |
debuggerd_client: properly wait for completion.
Use an intermediate pipe to detect and report when a requested dump has
completed.
Bug: http://b/35241370
Bug: http://b/35813071
Test: debuggerd_test
Test: manually triggered a background ANR
Change-Id: If14aedf6071288360f1a7853d5a2ee79db121759
Diffstat (limited to 'debuggerd/client/debuggerd_client_test.cpp')
-rw-r--r-- | debuggerd/client/debuggerd_client_test.cpp | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/debuggerd/client/debuggerd_client_test.cpp b/debuggerd/client/debuggerd_client_test.cpp new file mode 100644 index 000000000..86d03149b --- /dev/null +++ b/debuggerd/client/debuggerd_client_test.cpp @@ -0,0 +1,91 @@ +/* + * Copyright 2017, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <debuggerd/client.h> + +#include <fcntl.h> +#include <stdio.h> +#include <unistd.h> + +#include <chrono> +#include <thread> +#include <vector> + +#include <gtest/gtest.h> + +#include <android-base/file.h> +#include <android-base/stringprintf.h> +#include <android-base/strings.h> +#include <android-base/unique_fd.h> + +#include <debuggerd/util.h> + +using namespace std::chrono_literals; +using android::base::unique_fd; + +TEST(debuggerd_client, race) { + static constexpr int THREAD_COUNT = 1024; + pid_t forkpid = fork(); + + ASSERT_NE(-1, forkpid); + + if (forkpid == 0) { + // Spawn a bunch of threads, to make crash_dump take longer. + std::vector<std::thread> threads; + for (int i = 0; i < THREAD_COUNT; ++i) { + threads.emplace_back([]() { + while (true) { + std::this_thread::sleep_for(60s); + } + }); + } + + std::this_thread::sleep_for(60s); + exit(0); + } + + unique_fd pipe_read, pipe_write; + ASSERT_TRUE(Pipe(&pipe_read, &pipe_write)); + + // 64 kB should be enough for everyone. + constexpr int PIPE_SIZE = 64 * 1024 * 1024; + ASSERT_EQ(PIPE_SIZE, fcntl(pipe_read.get(), F_SETPIPE_SZ, PIPE_SIZE)); + + // Wait for a bit to let the child spawn all of its threads. + std::this_thread::sleep_for(250ms); + + ASSERT_TRUE(debuggerd_trigger_dump(forkpid, std::move(pipe_write), kDebuggerdBacktrace, 10000)); + // Immediately kill the forked child, to make sure that the dump didn't return early. + ASSERT_EQ(0, kill(forkpid, SIGKILL)) << strerror(errno); + + // Check the output. + std::string result; + ASSERT_TRUE(android::base::ReadFdToString(pipe_read.get(), &result)); + + // Look for "----- end <PID> -----" + int found_end = 0; + + std::string expected_end = android::base::StringPrintf("----- end %d -----", forkpid); + + std::vector<std::string> lines = android::base::Split(result, "\n"); + for (const std::string& line : lines) { + if (line == expected_end) { + ++found_end; + } + } + + EXPECT_EQ(1, found_end) << "\nOutput: \n" << result; +} |