“Promote” test::Paths::Executable() to Paths::Executable()

This supports the “double handler” or “double handler with low
probability” models from https://crashpad.chromium.org/bug/143.

For crashpad_handler to be become its own client, it needs access to its
own executable path to pass to CrashpadClient::StartHandler(). This was
formerly available in the test-only test::Paths::Executable(). Bring
that function’s implementation to the non-test Paths::Executable() in
util/misc, and rename test::Paths to test::TestPaths to avoid future
confusion.

test::TestPaths must still be used to access TestDataRoot(), which does
not make any sense to non-test code.

test::TestPaths::Executable() is retained for use by tests, which most
likely prefer the fatal semantics of that function. Paths::Executable()
is not fatal because for the purposes of implementing the double
handler, a failure to locate the executable path (which may happen on
some systems in deeply-nested directory hierarchies) shouldn’t cause the
initial crashpad_handler to abort, even if it does prevent a second
crashpad_handler from being started.

Bug: crashpad:143
Test: crashpad_util_test Paths.*, crashpad_test_test TestPaths.*
Change-Id: I9f75bf61839ce51e33c9f7c0d7031cebead6a156
Reviewed-on: https://chromium-review.googlesource.com/466346
Reviewed-by: Scott Graham <scottmg@chromium.org>
Commit-Queue: Mark Mentovai <mark@chromium.org>
This commit is contained in:
Mark Mentovai 2017-04-03 13:53:11 -04:00 committed by Commit Bot
parent c39e4dc976
commit 4688351623
30 changed files with 205 additions and 121 deletions

View File

@ -24,10 +24,10 @@
#include "base/logging.h"
#include "gtest/gtest.h"
#include "test/errors.h"
#include "test/paths.h"
#include "test/scoped_temp_dir.h"
#include "util/win/process_info.h"
#include "test/test_paths.h"
#include "test/win/win_multiprocess.h"
#include "util/win/process_info.h"
#include "util/win/scoped_handle.h"
#include "util/win/termination_codes.h"
@ -189,7 +189,7 @@ void WaitForAllChildProcessesOf(HANDLE parent) {
}
void StartAndUseHandler(const base::FilePath& temp_dir) {
base::FilePath handler_path = Paths::Executable().DirName().Append(
base::FilePath handler_path = TestPaths::Executable().DirName().Append(
FILE_PATH_LITERAL("crashpad_handler.com"));
CrashpadClient client;
@ -280,7 +280,7 @@ TEST(CrashpadClient, StartWithSameStdoutStderr) {
void StartAndUseBrokenHandler(CrashpadClient* client) {
ScopedTempDir temp_dir;
base::FilePath handler_path = Paths::Executable().DirName().Append(
base::FilePath handler_path = TestPaths::Executable().DirName().Append(
FILE_PATH_LITERAL("fake_handler_that_crashes_at_startup.exe"));
ASSERT_TRUE(client->StartHandler(handler_path,
temp_dir.path(),

View File

@ -214,9 +214,9 @@ $ adb push \
/data/local/tmp/
[100%] /data/local/tmp/crashpad_test_test_multiprocess_exec_test_child
$ adb shell mkdir -p /data/local/tmp/crashpad_test_data_root/test
$ adb push test/paths_test_data_root.txt \
$ adb push test/test_paths_test_data_root.txt \
/data/local/tmp/crashpad_test_data_root/test/
[100%] /data/local/tmp/crashpad_test_data_root/test/paths_test_data_root.txt
[100%] /data/local/tmp/crashpad_test_data_root/test/test_paths_test_data_root.txt
$ adb shell
device:/ $ cd /data/local/tmp
device:/data/local/tmp $ CRASHPAD_TEST_DATA_ROOT=crashpad_test_data_root \

View File

@ -20,7 +20,7 @@
#include "base/logging.h"
#include "base/strings/stringprintf.h"
#include "client/crashpad_client.h"
#include "test/paths.h"
#include "test/test_paths.h"
#include "test/win/child_launcher.h"
#include "util/file/file_io.h"
#include "util/win/scoped_handle.h"
@ -88,7 +88,7 @@ int CrashOtherProgram(int argc, wchar_t* argv[]) {
}
// Launch another process that hangs.
base::FilePath test_executable = Paths::Executable();
base::FilePath test_executable = TestPaths::Executable();
std::wstring child_test_executable =
test_executable.DirName().Append(L"hanging_program.exe").value();
ChildLauncher child(child_test_executable, argv[1]);

View File

@ -19,7 +19,7 @@
#include "base/logging.h"
#include "build/build_config.h"
#include "client/crashpad_client.h"
#include "test/paths.h"
#include "test/test_paths.h"
#if !defined(ARCH_CPU_X86)
#error This test is only supported on x86.
@ -43,7 +43,7 @@ int CrashyLoadZ7Main(int argc, wchar_t* argv[]) {
// The DLL has /Z7 symbols embedded in the binary (rather than in a .pdb).
// There's only an x86 version of this dll as newer x64 toolchains can't
// generate this format any more.
base::FilePath z7_path = test::Paths::TestDataRoot().Append(
base::FilePath z7_path = test::TestPaths::TestDataRoot().Append(
FILE_PATH_LITERAL("handler/win/z7_test.dll"));
HMODULE z7_test = LoadLibrary(z7_path.value().c_str());
if (!z7_test) {

View File

@ -21,7 +21,7 @@
#include "client/crashpad_info.h"
#include "gtest/gtest.h"
#include "test/errors.h"
#include "test/paths.h"
#include "test/test_paths.h"
#if defined(OS_MACOSX)
#include <dlfcn.h>
@ -187,7 +187,7 @@ TEST(CrashpadInfoClientOptions, TwoModules) {
#elif defined(OS_WIN)
const base::FilePath::StringType kDlExtension = FILE_PATH_LITERAL(".dll");
#endif
base::FilePath module_path = Paths::Executable().DirName().Append(
base::FilePath module_path = TestPaths::Executable().DirName().Append(
FILE_PATH_LITERAL("crashpad_snapshot_test_module") + kDlExtension);
#if defined(OS_MACOSX)
ScopedDlHandle dl_handle(

View File

@ -35,7 +35,7 @@
#include "test/errors.h"
#include "test/mac/mach_errors.h"
#include "test/mac/mach_multiprocess.h"
#include "test/paths.h"
#include "test/test_paths.h"
#include "util/file/file_io.h"
#include "util/mac/mac_util.h"
#include "util/mach/exc_server_variants.h"
@ -50,12 +50,12 @@ namespace {
// \return The path to crashpad_snapshot_test_module_crashy_initializer.so
std::string ModuleWithCrashyInitializer() {
return Paths::Executable().value() + "_module_crashy_initializer.so";
return TestPaths::Executable().value() + "_module_crashy_initializer.so";
}
//! \return The path to the crashpad_snapshot_test_no_op executable.
base::FilePath NoOpExecutable() {
return base::FilePath(Paths::Executable().value() + "_no_op");
return base::FilePath(TestPaths::Executable().value() + "_no_op");
}
class TestMachOImageAnnotationsReader final

View File

@ -23,7 +23,7 @@
#include "gtest/gtest.h"
#include "snapshot/win/process_snapshot_win.h"
#include "test/errors.h"
#include "test/paths.h"
#include "test/test_paths.h"
#include "test/win/child_launcher.h"
#include "util/file/file_io.h"
#include "util/thread/thread.h"
@ -140,7 +140,7 @@ void TestCrashingChild(const base::string16& directory_modification) {
<< ErrorMessage("WaitForSingleObject");
// Spawn a child process, passing it the pipe name to connect to.
base::FilePath test_executable = Paths::Executable();
base::FilePath test_executable = TestPaths::Executable();
std::wstring child_test_executable =
test_executable.DirName()
.Append(directory_modification)
@ -248,7 +248,7 @@ void TestDumpWithoutCrashingChild(
<< ErrorMessage("WaitForSingleObject");
// Spawn a child process, passing it the pipe name to connect to.
base::FilePath test_executable = Paths::Executable();
base::FilePath test_executable = TestPaths::Executable();
std::wstring child_test_executable =
test_executable.DirName()
.Append(directory_modification)

View File

@ -25,7 +25,7 @@
#include "client/simple_address_range_bag.h"
#include "gtest/gtest.h"
#include "snapshot/win/process_snapshot_win.h"
#include "test/paths.h"
#include "test/test_paths.h"
#include "test/win/child_launcher.h"
#include "util/file/file_io.h"
#include "util/win/process_info.h"
@ -45,7 +45,7 @@ enum TestType {
void TestExtraMemoryRanges(TestType type,
const base::string16& directory_modification) {
// Spawn a child process, passing it the pipe name to connect to.
base::FilePath test_executable = Paths::Executable();
base::FilePath test_executable = TestPaths::Executable();
std::wstring child_test_executable =
test_executable.DirName()
.Append(directory_modification)

View File

@ -29,7 +29,7 @@
#include "gtest/gtest.h"
#include "snapshot/win/pe_image_reader.h"
#include "snapshot/win/process_reader_win.h"
#include "test/paths.h"
#include "test/test_paths.h"
#include "test/win/child_launcher.h"
#include "util/file/file_io.h"
#include "util/win/process_info.h"
@ -49,7 +49,7 @@ enum TestType {
void TestAnnotationsOnCrash(TestType type,
const base::string16& directory_modification) {
// Spawn a child process, passing it the pipe name to connect to.
base::FilePath test_executable = Paths::Executable();
base::FilePath test_executable = TestPaths::Executable();
std::wstring child_test_executable =
test_executable.DirName()
.Append(directory_modification)

View File

@ -21,7 +21,7 @@
#include "snapshot/win/pe_image_reader.h"
#include "snapshot/win/process_reader_win.h"
#include "test/errors.h"
#include "test/paths.h"
#include "test/test_paths.h"
#include "test/win/child_launcher.h"
#include "util/file/file_io.h"
#include "util/win/scoped_handle.h"
@ -38,7 +38,7 @@ void TestImageReaderChild(const base::string16& directory_modification) {
CreateEvent(nullptr, true, false, done_uuid.ToString16().c_str()));
ASSERT_TRUE(done.is_valid()) << ErrorMessage("CreateEvent");
base::FilePath test_executable = Paths::Executable();
base::FilePath test_executable = TestPaths::Executable();
std::wstring child_test_executable =
test_executable.DirName()
.Append(directory_modification)

View File

@ -18,7 +18,7 @@
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "gtest/gtest.h"
#include "test/paths.h"
#include "test/test_paths.h"
#include "util/file/file_io.h"
namespace crashpad {
@ -48,7 +48,7 @@ class TestMultiprocessExec final : public MultiprocessExec {
TEST(MultiprocessExec, MultiprocessExec) {
TestMultiprocessExec multiprocess_exec;
base::FilePath test_executable = Paths::Executable();
base::FilePath test_executable = TestPaths::Executable();
#if defined(OS_POSIX)
std::string child_test_executable = test_executable.value();
#elif defined(OS_WIN)

View File

@ -49,15 +49,12 @@
'multiprocess_exec_posix.cc',
'multiprocess_exec_win.cc',
'multiprocess_posix.cc',
'paths.cc',
'paths.h',
'paths_linux.cc',
'paths_mac.cc',
'paths_win.cc',
'scoped_temp_dir.cc',
'scoped_temp_dir.h',
'scoped_temp_dir_posix.cc',
'scoped_temp_dir_win.cc',
'test_paths.cc',
'test_paths.h',
'win/child_launcher.cc',
'win/child_launcher.h',
'win/win_child_process.cc',
@ -86,13 +83,6 @@
},
}],
],
'target_conditions': [
['OS=="android"', {
'sources/': [
['include', '^paths_linux\\.cc$'],
],
}],
],
},
{
'target_name': 'crashpad_gtest_main',

View File

@ -12,13 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "test/paths.h"
#include "test/test_paths.h"
#include <stdlib.h>
#include <sys/stat.h>
#include "base/logging.h"
#include "build/build_config.h"
#include "util/misc/paths.h"
namespace crashpad {
namespace test {
@ -28,7 +29,7 @@ namespace {
bool IsTestDataRoot(const base::FilePath& candidate) {
const base::FilePath marker_path =
candidate.Append(FILE_PATH_LITERAL("test"))
.Append(FILE_PATH_LITERAL("paths_test_data_root.txt"));
.Append(FILE_PATH_LITERAL("test_paths_test_data_root.txt"));
#if !defined(OS_WIN)
struct stat stat_buf;
@ -59,23 +60,25 @@ base::FilePath TestDataRootInternal() {
// In a standalone build, the test executable is usually at
// out/{Debug,Release} relative to the Crashpad root.
const base::FilePath executable = Paths::Executable();
base::FilePath candidate =
base::FilePath(executable.DirName()
.Append(base::FilePath::kParentDirectory)
.Append(base::FilePath::kParentDirectory));
if (IsTestDataRoot(candidate)) {
return candidate;
}
base::FilePath executable_path;
if (Paths::Executable(&executable_path)) {
base::FilePath candidate =
base::FilePath(executable_path.DirName()
.Append(base::FilePath::kParentDirectory)
.Append(base::FilePath::kParentDirectory));
if (IsTestDataRoot(candidate)) {
return candidate;
}
// In an in-Chromium build, the test executable is usually at
// out/{Debug,Release} relative to the Chromium root, and the Crashpad root is
// at third_party/crashpad/crashpad relative to the Chromium root.
candidate = candidate.Append(FILE_PATH_LITERAL("third_party"))
.Append(FILE_PATH_LITERAL("crashpad"))
.Append(FILE_PATH_LITERAL("crashpad"));
if (IsTestDataRoot(candidate)) {
return candidate;
// In an in-Chromium build, the test executable is usually at
// out/{Debug,Release} relative to the Chromium root, and the Crashpad root
// is at third_party/crashpad/crashpad relative to the Chromium root.
candidate = candidate.Append(FILE_PATH_LITERAL("third_party"))
.Append(FILE_PATH_LITERAL("crashpad"))
.Append(FILE_PATH_LITERAL("crashpad"));
if (IsTestDataRoot(candidate)) {
return candidate;
}
}
// If nothing else worked, use the current directory, issuing a warning if it
@ -90,7 +93,14 @@ base::FilePath TestDataRootInternal() {
} // namespace
// static
base::FilePath Paths::TestDataRoot() {
base::FilePath TestPaths::Executable() {
base::FilePath executable_path;
CHECK(Paths::Executable(&executable_path));
return executable_path;
}
// static
base::FilePath TestPaths::TestDataRoot() {
static base::FilePath* test_data_root =
new base::FilePath(TestDataRootInternal());
return *test_data_root;

View File

@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef CRASHPAD_TEST_PATHS_H_
#define CRASHPAD_TEST_PATHS_H_
#ifndef CRASHPAD_TEST_TEST_PATHS_H_
#define CRASHPAD_TEST_TEST_PATHS_H_
#include "base/files/file_path.h"
#include "base/macros.h"
@ -22,9 +22,11 @@ namespace crashpad {
namespace test {
//! \brief Functions to obtain paths from within tests.
class Paths {
class TestPaths {
public:
//! \brief Returns the pathname of the currently-running test executable.
//!
//! On failure, aborts execution.
static base::FilePath Executable();
//! \brief Returns the pathname of the test data root.
@ -40,10 +42,10 @@ class Paths {
//! files.
static base::FilePath TestDataRoot();
DISALLOW_IMPLICIT_CONSTRUCTORS(Paths);
DISALLOW_IMPLICIT_CONSTRUCTORS(TestPaths);
};
} // namespace test
} // namespace crashpad
#endif // CRASHPAD_TEST_PATHS_H_
#endif // CRASHPAD_TEST_TEST_PATHS_H_

View File

@ -12,10 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "test/paths.h"
#include "test/test_paths.h"
#include "base/files/file_path.h"
#include "build/build_config.h"
#include "gtest/gtest.h"
#include "util/file/file_io.h"
@ -23,22 +22,11 @@ namespace crashpad {
namespace test {
namespace {
TEST(Paths, Executable) {
base::FilePath executable_path = Paths::Executable();
base::FilePath executable_name = executable_path.BaseName();
#if defined(OS_WIN)
EXPECT_EQ(FILE_PATH_LITERAL("crashpad_test_test.exe"),
executable_name.value());
#else
EXPECT_EQ("crashpad_test_test", executable_name.value());
#endif // OS_WIN
}
TEST(Paths, TestDataRoot) {
base::FilePath test_data_root = Paths::TestDataRoot();
TEST(TestPaths, TestDataRoot) {
base::FilePath test_data_root = TestPaths::TestDataRoot();
ScopedFileHandle file(LoggingOpenFileForRead(
test_data_root.Append(FILE_PATH_LITERAL("test"))
.Append(FILE_PATH_LITERAL("paths_test_data_root.txt"))));
.Append(FILE_PATH_LITERAL("test_paths_test_data_root.txt"))));
EXPECT_TRUE(file.is_valid());
}

View File

@ -12,5 +12,5 @@
# See the License for the specific language governing permissions and
# limitations under the License.
This file is used by Paths::TestDataRoot() to locate the test data root. It
This file is used by TestPaths::TestDataRoot() to locate the test data root. It
is present at a known path from the test data root.

View File

@ -39,8 +39,8 @@
'main_arguments_test.cc',
'multiprocess_exec_test.cc',
'multiprocess_posix_test.cc',
'paths_test.cc',
'scoped_temp_dir_test.cc',
'test_paths_test.cc',
'win/win_child_process_test.cc',
'win/win_multiprocess_test.cc',
],

View File

@ -24,11 +24,11 @@
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "gtest/gtest.h"
#include "test/test_paths.h"
#include "util/stdlib/string_number_conversion.h"
#include "util/string/split_string.h"
#include "util/win/handle.h"
#include "util/win/scoped_local_alloc.h"
#include "test/paths.h"
namespace crashpad {
namespace test {
@ -70,7 +70,7 @@ ScopedKernelHANDLE LaunchCommandLine(wchar_t* command_line) {
startup_info.hStdError = GetStdHandle(STD_ERROR_HANDLE);
startup_info.dwFlags = STARTF_USESTDHANDLES;
PROCESS_INFORMATION process_info;
if (!CreateProcess(Paths::Executable().value().c_str(),
if (!CreateProcess(TestPaths::Executable().value().c_str(),
&command_line[0], // This cannot be constant, per MSDN.
nullptr,
nullptr,
@ -186,7 +186,7 @@ std::unique_ptr<WinChildProcess::Handles> WinChildProcess::Launch() {
const ::testing::TestInfo* const test_info =
::testing::UnitTest::GetInstance()->current_test_info();
std::wstring command_line =
Paths::Executable().value() + L" " +
TestPaths::Executable().value() + L" " +
base::UTF8ToUTF16(base::StringPrintf("--gtest_filter=%s.%s %s=0x%x|0x%x",
test_info->test_case_name(),
test_info->name(),

View File

@ -22,7 +22,6 @@
#include "base/strings/utf_string_conversions.h"
#include "util/stdlib/string_number_conversion.h"
#include "util/string/split_string.h"
#include "test/paths.h"
namespace crashpad {
namespace test {

40
util/misc/paths.h Normal file
View File

@ -0,0 +1,40 @@
// Copyright 2017 The Crashpad Authors. All rights reserved.
//
// 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.
#ifndef CRASHPAD_UTIL_PATHS_H_
#define CRASHPAD_UTIL_PATHS_H_
#include "base/files/file_path.h"
#include "base/macros.h"
namespace crashpad {
//! \brief Functions to obtain paths.
class Paths {
public:
//! \brief Obtains the pathname of the currently-running executable.
//!
//! \param[out] path The pathname of the currently-running executable.
//!
//! \return `true` on success. `false` on failure, with a message logged.
//!
//! \note In test code, use test::TestPaths::Executable() instead.
static bool Executable(base::FilePath* path);
DISALLOW_IMPLICIT_CONSTRUCTORS(Paths);
};
} // namespace crashpad
#endif // CRASHPAD_UTIL_TEST_PATHS_H_

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "test/paths.h"
#include "util/misc/paths.h"
#include <limits.h>
#include <unistd.h>
@ -21,42 +21,41 @@
#include <string>
#include "base/logging.h"
#include "util/misc/implicit_cast.h"
namespace crashpad {
namespace test {
// static
base::FilePath Paths::Executable() {
bool Paths::Executable(base::FilePath* path) {
// Linux does not provide a straightforward way to size the buffer before
// calling readlink(). Normally, the st_size field returned by lstat() could
// be used, but this is usually zero for things in /proc.
//
// The /proc filesystem does not provide any way to read “exe” links for
// pathnames longer than a page. See linux-4.4.27/fs/proc/base.c
// pathnames longer than a page. See linux-4.9.20/fs/proc/base.c
// do_proc_readlink(), which allocates a single page to receive the path
// string. Coincidentally, the page size and PATH_MAX are normally the same
// value, although neither is strictly a limit on the length of a pathname.
//
// On Android, the smaller of the page size and PATH_MAX actually does serve
// as an effective limit on the length of an executables pathname. See
// Android 7.0.0 bionic/linker/linker.cpp get_executable_path(), which aborts
// Android 7.1.1 bionic/linker/linker.cpp get_executable_path(), which aborts
// via __libc_fatal() if the “exe” link cant be read into a PATH_MAX-sized
// buffer.
std::string exe_path(std::max(implicit_cast<size_t>(sysconf(_SC_PAGESIZE)),
implicit_cast<size_t>(PATH_MAX)),
std::string exe_path(std::max(getpagesize(), PATH_MAX),
std::string::value_type());
ssize_t exe_path_len =
readlink("/proc/self/exe", &exe_path[0], exe_path.size());
if (exe_path_len < 0) {
PLOG(FATAL) << "readlink";
PLOG(ERROR) << "readlink";
return false;
} else if (static_cast<size_t>(exe_path_len) >= exe_path.size()) {
LOG(FATAL) << "readlink";
LOG(ERROR) << "readlink";
return false;
}
exe_path.resize(exe_path_len);
return base::FilePath(exe_path);
*path = base::FilePath(exe_path);
return true;
}
} // namespace test
} // namespace crashpad

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "test/paths.h"
#include "util/misc/paths.h"
#include <mach-o/dyld.h>
#include <stdint.h>
@ -20,20 +20,25 @@
#include "base/logging.h"
namespace crashpad {
namespace test {
// static
base::FilePath Paths::Executable() {
bool Paths::Executable(base::FilePath* path) {
uint32_t executable_length = 0;
_NSGetExecutablePath(nullptr, &executable_length);
CHECK_GT(executable_length, 1u);
if (executable_length <= 1) {
LOG(ERROR) << "_NSGetExecutablePath";
return false;
}
std::string executable_path(executable_length - 1, std::string::value_type());
int rv = _NSGetExecutablePath(&executable_path[0], &executable_length);
CHECK_EQ(rv, 0);
if (rv != 0) {
LOG(ERROR) << "_NSGetExecutablePath";
return false;
}
return base::FilePath(executable_path);
*path = base::FilePath(executable_path);
return true;
}
} // namespace test
} // namespace crashpad

39
util/misc/paths_test.cc Normal file
View File

@ -0,0 +1,39 @@
// Copyright 2014 The Crashpad Authors. All rights reserved.
//
// 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 "util/misc/paths.h"
#include "base/files/file_path.h"
#include "build/build_config.h"
#include "gtest/gtest.h"
namespace crashpad {
namespace test {
namespace {
TEST(Paths, Executable) {
base::FilePath executable_path;
ASSERT_TRUE(Paths::Executable(&executable_path));
const base::FilePath executable_name(executable_path.BaseName());
#if defined(OS_WIN)
EXPECT_EQ(FILE_PATH_LITERAL("crashpad_util_test.exe"),
executable_name.value());
#else
EXPECT_EQ("crashpad_util_test", executable_name.value());
#endif // OS_WIN
}
} // namespace
} // namespace test
} // namespace crashpad

View File

@ -12,23 +12,29 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "test/paths.h"
#include "util/misc/paths.h"
#include <windows.h>
#include "base/logging.h"
namespace crashpad {
namespace test {
// static
base::FilePath Paths::Executable() {
bool Paths::Executable(base::FilePath* path) {
wchar_t executable_path[_MAX_PATH];
unsigned int len =
GetModuleFileName(nullptr, executable_path, arraysize(executable_path));
PCHECK(len != 0 && len < arraysize(executable_path)) << "GetModuleFileName";
return base::FilePath(executable_path);
if (len == 0) {
PLOG(ERROR) << "GetModuleFileName";
return false;
} else if (len >= arraysize(executable_path)) {
LOG(ERROR) << "GetModuleFileName";
return false;
}
*path = base::FilePath(executable_path);
return true;
}
} // namespace test
} // namespace crashpad

View File

@ -17,7 +17,7 @@
#include <string.h>
#include "gtest/gtest.h"
#include "test/paths.h"
#include "test/test_paths.h"
#include "util/misc/implicit_cast.h"
#include "util/net/http_body_test_util.h"
@ -97,7 +97,7 @@ TEST(StringHTTPBodyStream, MultipleReads) {
}
TEST(FileHTTPBodyStream, ReadASCIIFile) {
base::FilePath path = Paths::TestDataRoot().Append(
base::FilePath path = TestPaths::TestDataRoot().Append(
FILE_PATH_LITERAL("util/net/testdata/ascii_http_body.txt"));
FileHTTPBodyStream stream(path);
std::string contents = ReadStreamToString(&stream, 32);
@ -115,7 +115,7 @@ TEST(FileHTTPBodyStream, ReadASCIIFile) {
TEST(FileHTTPBodyStream, ReadBinaryFile) {
// HEX contents of file: |FEEDFACE A11A15|.
base::FilePath path = Paths::TestDataRoot().Append(
base::FilePath path = TestPaths::TestDataRoot().Append(
FILE_PATH_LITERAL("util/net/testdata/binary_http_body.dat"));
// This buffer size was chosen so that reading the file takes multiple reads.
uint8_t buf[4];
@ -199,7 +199,7 @@ TEST_P(CompositeHTTPBodyStreamBufferSize, StringsAndFile) {
std::vector<HTTPBodyStream*> parts;
parts.push_back(new StringHTTPBodyStream(string1));
base::FilePath path = Paths::TestDataRoot().Append(
base::FilePath path = TestPaths::TestDataRoot().Append(
FILE_PATH_LITERAL("util/net/testdata/ascii_http_body.txt"));
parts.push_back(new FileHTTPBodyStream(path));
parts.push_back(new StringHTTPBodyStream(string2));

View File

@ -20,7 +20,7 @@
#include "gtest/gtest.h"
#include "test/gtest_death_check.h"
#include "test/paths.h"
#include "test/test_paths.h"
#include "util/net/http_body.h"
#include "util/net/http_body_test_util.h"
@ -100,7 +100,7 @@ TEST(HTTPMultipartBuilder, ThreeStringFields) {
TEST(HTTPMultipartBuilder, ThreeFileAttachments) {
HTTPMultipartBuilder builder;
base::FilePath ascii_http_body_path = Paths::TestDataRoot().Append(
base::FilePath ascii_http_body_path = TestPaths::TestDataRoot().Append(
FILE_PATH_LITERAL("util/net/testdata/ascii_http_body.txt"));
builder.SetFileAttachment("first",
"minidump.dmp",
@ -186,7 +186,7 @@ TEST(HTTPMultipartBuilder, OverwriteFileAttachment) {
const char kValue[] = "1 2 3 test";
builder.SetFormData("a key", kValue);
base::FilePath testdata_path =
Paths::TestDataRoot().Append(FILE_PATH_LITERAL("util/net/testdata"));
TestPaths::TestDataRoot().Append(FILE_PATH_LITERAL("util/net/testdata"));
builder.SetFileAttachment("minidump",
"minidump.dmp",
testdata_path.Append(FILE_PATH_LITERAL(
@ -242,7 +242,7 @@ TEST(HTTPMultipartBuilder, SharedFormDataAndAttachmentKeyNamespace) {
HTTPMultipartBuilder builder;
const char kValue1[] = "11111";
builder.SetFormData("one", kValue1);
base::FilePath ascii_http_body_path = Paths::TestDataRoot().Append(
base::FilePath ascii_http_body_path = TestPaths::TestDataRoot().Append(
FILE_PATH_LITERAL("util/net/testdata/ascii_http_body.txt"));
builder.SetFileAttachment("minidump",
"minidump.dmp",

View File

@ -31,7 +31,7 @@
#include "build/build_config.h"
#include "gtest/gtest.h"
#include "test/multiprocess_exec.h"
#include "test/paths.h"
#include "test/test_paths.h"
#include "util/file/file_io.h"
#include "util/misc/random_string.h"
#include "util/net/http_body.h"
@ -56,7 +56,7 @@ class HTTPTransportTestFixture : public MultiprocessExec {
body_stream_(std::move(body_stream)),
response_code_(http_response_code),
request_validator_(request_validator) {
base::FilePath server_path = Paths::TestDataRoot().Append(
base::FilePath server_path = TestPaths::TestDataRoot().Append(
FILE_PATH_LITERAL("util/net/http_transport_test_server.py"));
#if defined(OS_POSIX)
SetChildCommand(server_path.value(), nullptr);

View File

@ -99,6 +99,10 @@
'misc/initialization_state_dcheck.h',
'misc/metrics.cc',
'misc/metrics.h',
'misc/paths.h',
'misc/paths_mac.cc',
'misc/paths_linux.cc',
'misc/paths_win.cc',
'misc/pdb_structures.cc',
'misc/pdb_structures.h',
'misc/random_string.cc',
@ -321,6 +325,7 @@
'target_conditions': [
['OS=="android"', {
'sources/': [
['include', '^misc/paths_linux\\.cc$'],
['include', '^posix/process_info_linux\\.cc$'],
],
}],

View File

@ -62,6 +62,7 @@
'misc/clock_test.cc',
'misc/initialization_state_dcheck_test.cc',
'misc/initialization_state_test.cc',
'misc/paths_test.cc',
'misc/scoped_forbid_return_test.cc',
'misc/random_string_test.cc',
'misc/uuid_test.cc',

View File

@ -26,8 +26,8 @@
#include "build/build_config.h"
#include "gtest/gtest.h"
#include "test/errors.h"
#include "test/paths.h"
#include "test/scoped_temp_dir.h"
#include "test/test_paths.h"
#include "test/win/child_launcher.h"
#include "util/file/file_io.h"
#include "util/misc/random_string.h"
@ -139,7 +139,7 @@ void TestOtherProcess(const base::string16& directory_modification) {
CreateEvent(nullptr, true, false, done_uuid.ToString16().c_str()));
ASSERT_TRUE(done.get()) << ErrorMessage("CreateEvent");
base::FilePath test_executable = Paths::Executable();
base::FilePath test_executable = TestPaths::Executable();
std::wstring child_test_executable =
test_executable.DirName()