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 |