| Index: third_party/crashpad/crashpad/util/posix/process_info_test.cc
|
| diff --git a/third_party/crashpad/crashpad/util/posix/process_info_test.cc b/third_party/crashpad/crashpad/util/posix/process_info_test.cc
|
| index c07b1ef750b85e78882c74fada400d36c0203359..6a1a132b5e615d188b095d76f8762bb261344dee 100644
|
| --- a/third_party/crashpad/crashpad/util/posix/process_info_test.cc
|
| +++ b/third_party/crashpad/crashpad/util/posix/process_info_test.cc
|
| @@ -14,32 +14,27 @@
|
|
|
| #include "util/posix/process_info.h"
|
|
|
| +#include <signal.h>
|
| #include <time.h>
|
| -#include <stdio.h>
|
| #include <unistd.h>
|
|
|
| +#include <algorithm>
|
| #include <set>
|
| #include <string>
|
| #include <vector>
|
|
|
| -#include "base/files/scoped_file.h"
|
| +#include "base/strings/stringprintf.h"
|
| #include "build/build_config.h"
|
| #include "gtest/gtest.h"
|
| #include "test/errors.h"
|
| +#include "test/main_arguments.h"
|
| #include "util/misc/implicit_cast.h"
|
|
|
| -#if defined(OS_MACOSX)
|
| -#include <crt_externs.h>
|
| -#endif
|
| -
|
| namespace crashpad {
|
| namespace test {
|
| namespace {
|
|
|
| -void TestSelfProcess(const ProcessInfo& process_info) {
|
| - EXPECT_EQ(getpid(), process_info.ProcessID());
|
| - EXPECT_EQ(getppid(), process_info.ParentProcessID());
|
| -
|
| +void TestProcessSelfOrClone(const ProcessInfo& process_info) {
|
| // There’s no system call to obtain the saved set-user ID or saved set-group
|
| // ID in an easy way. Normally, they are the same as the effective user ID and
|
| // effective group ID, so just check against those.
|
| @@ -47,6 +42,7 @@ void TestSelfProcess(const ProcessInfo& process_info) {
|
| const uid_t euid = geteuid();
|
| EXPECT_EQ(euid, process_info.EffectiveUserID());
|
| EXPECT_EQ(euid, process_info.SavedUserID());
|
| +
|
| const gid_t gid = getgid();
|
| EXPECT_EQ(gid, process_info.RealGroupID());
|
| const gid_t egid = getegid();
|
| @@ -78,15 +74,18 @@ void TestSelfProcess(const ProcessInfo& process_info) {
|
| // The test executable isn’t expected to change privileges.
|
| EXPECT_FALSE(process_info.DidChangePrivileges());
|
|
|
| + bool is_64_bit;
|
| + ASSERT_TRUE(process_info.Is64Bit(&is_64_bit));
|
| #if defined(ARCH_CPU_64_BITS)
|
| - EXPECT_TRUE(process_info.Is64Bit());
|
| + EXPECT_TRUE(is_64_bit);
|
| #else
|
| - EXPECT_FALSE(process_info.Is64Bit());
|
| + EXPECT_FALSE(is_64_bit);
|
| #endif
|
|
|
| // Test StartTime(). This program must have started at some time in the past.
|
| timeval start_time;
|
| - process_info.StartTime(&start_time);
|
| + ASSERT_TRUE(process_info.StartTime(&start_time));
|
| + EXPECT_FALSE(start_time.tv_sec == 0 && start_time.tv_usec == 0);
|
| time_t now;
|
| time(&now);
|
| EXPECT_LE(start_time.tv_sec, now);
|
| @@ -94,54 +93,38 @@ void TestSelfProcess(const ProcessInfo& process_info) {
|
| std::vector<std::string> argv;
|
| ASSERT_TRUE(process_info.Arguments(&argv));
|
|
|
| - // gtest argv processing scrambles argv, but it leaves argc and argv[0]
|
| - // intact, so test those.
|
| -
|
| -#if defined(OS_MACOSX)
|
| - int expect_argc = *_NSGetArgc();
|
| - char** expect_argv = *_NSGetArgv();
|
| -#elif defined(OS_LINUX) || defined(OS_ANDROID)
|
| - std::vector<std::string> expect_arg_vector;
|
| - {
|
| - base::ScopedFILE cmdline(fopen("/proc/self/cmdline", "re"));
|
| - ASSERT_NE(nullptr, cmdline.get()) << ErrnoMessage("fopen");
|
| -
|
| - int expect_arg_char;
|
| - std::string expect_arg_string;
|
| - while ((expect_arg_char = fgetc(cmdline.get())) != EOF) {
|
| - if (expect_arg_char != '\0') {
|
| - expect_arg_string.append(1, expect_arg_char);
|
| - } else {
|
| - expect_arg_vector.push_back(expect_arg_string);
|
| - expect_arg_string.clear();
|
| - }
|
| - }
|
| - ASSERT_EQ(0, ferror(cmdline.get())) << ErrnoMessage("fgetc");
|
| - ASSERT_TRUE(expect_arg_string.empty());
|
| + const std::vector<std::string>& expect_argv = GetMainArguments();
|
| +
|
| + // expect_argv always contains the initial view of the arguments at the time
|
| + // the program was invoked. argv may contain this view, or it may contain the
|
| + // current view of arguments after gtest argv processing. argv may be a subset
|
| + // of expect_argv.
|
| + //
|
| + // gtest argv processing always leaves argv[0] intact, so this can be checked
|
| + // directly.
|
| + ASSERT_FALSE(expect_argv.empty());
|
| + ASSERT_FALSE(argv.empty());
|
| + EXPECT_EQ(expect_argv[0], argv[0]);
|
| +
|
| + EXPECT_LE(argv.size(), expect_argv.size());
|
| +
|
| + // Everything else in argv should have a match in expect_argv too, but things
|
| + // may have moved around.
|
| + for (size_t arg_index = 1; arg_index < argv.size(); ++arg_index) {
|
| + const std::string& arg = argv[arg_index];
|
| + SCOPED_TRACE(
|
| + base::StringPrintf("arg_index %zu, arg %s", arg_index, arg.c_str()));
|
| + EXPECT_NE(expect_argv.end(), std::find(argv.begin(), argv.end(), arg));
|
| }
|
| +}
|
|
|
| - std::vector<const char*> expect_argv_storage;
|
| - for (const std::string& expect_arg_string : expect_arg_vector) {
|
| - expect_argv_storage.push_back(expect_arg_string.c_str());
|
| - }
|
| -
|
| - int expect_argc = expect_argv_storage.size();
|
| - const char* const* expect_argv =
|
| - !expect_argv_storage.empty() ? &expect_argv_storage[0] : nullptr;
|
| -#else
|
| -#error Obtain expect_argc and expect_argv correctly on your system.
|
| -#endif
|
| -
|
| - int argc = implicit_cast<int>(argv.size());
|
| - EXPECT_EQ(expect_argc, argc);
|
| -
|
| - ASSERT_GE(expect_argc, 1);
|
| - ASSERT_GE(argc, 1);
|
| +void TestSelfProcess(const ProcessInfo& process_info) {
|
| + EXPECT_EQ(getpid(), process_info.ProcessID());
|
| + EXPECT_EQ(getppid(), process_info.ParentProcessID());
|
|
|
| - EXPECT_EQ(std::string(expect_argv[0]), argv[0]);
|
| + TestProcessSelfOrClone(process_info);
|
| }
|
|
|
| -
|
| TEST(ProcessInfo, Self) {
|
| ProcessInfo process_info;
|
| ASSERT_TRUE(process_info.Initialize(getpid()));
|
| @@ -173,6 +156,24 @@ TEST(ProcessInfo, Pid1) {
|
| EXPECT_FALSE(process_info.AllGroups().empty());
|
| }
|
|
|
| +TEST(ProcessInfo, Forked) {
|
| + pid_t pid = fork();
|
| + if (pid == 0) {
|
| + raise(SIGSTOP);
|
| + _exit(0);
|
| + }
|
| + ASSERT_GE(pid, 0) << ErrnoMessage("fork");
|
| +
|
| + ProcessInfo process_info;
|
| + ASSERT_TRUE(process_info.Initialize(pid));
|
| +
|
| + EXPECT_EQ(pid, process_info.ProcessID());
|
| + EXPECT_EQ(getpid(), process_info.ParentProcessID());
|
| +
|
| + TestProcessSelfOrClone(process_info);
|
| + kill(pid, SIGKILL);
|
| +}
|
| +
|
| } // namespace
|
| } // namespace test
|
| } // namespace crashpad
|
|
|