2022-09-06 19:14:07 -04:00
|
|
|
|
// Copyright 2014 The Crashpad Authors
|
2014-08-25 17:51:09 -04:00
|
|
|
|
//
|
|
|
|
|
// 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.
|
|
|
|
|
|
2018-02-22 12:12:26 -08:00
|
|
|
|
#include "snapshot/mac/process_reader_mac.h"
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
mac: Switch from <AvailabilityMacros.h> to <Availability.h>
The macOS 11.0 SDK, as of Xcode 12b6 12A8189n, has not updated
<AvailabilityMacros.h> with a MAC_OS_X_VERSION_11_0 or
MAC_OS_X_VERSION_10_16 constant. However, the <Availability.h> interface
has been updated to provide both __MAC_11_0 and __MAC_10_16.
<AvailabilityMacros.h>’s MAC_OS_X_VERSION_MAX_ALLOWED, which is supposed
to identify the SDK version, is broken in the 11.0 SDK in that whenever
the deployment target is set to 10.15 or earlier, the SDK will be
mis-identified through this interface as 10.15. When using the
<Availability.h> equivalent, __MAC_OS_X_VERSION_MAX_ALLOWED, the 11.0
SDK is identified as 10.16 (arguably it should be internally versioned
as 11.0, but at least this interface allows it to be detected
unambiguously.) It’s clear that the <AvailabilityMacros.h> interface
provides no meaningful support for the macOS 11.0 SDK at all, but
<Availability.h> does.
<Availability.h> was introduced in the Mac OS X 10.5 SDK, so there is no
relevant SDK version compatibility problem with this interface.
Key differences between these interfaces for the purposes used by
Crashpad:
- <AvailabilityMacros.h> → <Availability.h>
- MAC_OS_X_VERSION_MIN_REQUIRED (DT) → __MAC_OS_X_VERSION_MIN_REQUIRED
- MAC_OS_X_VERSION_MAX_ALLOWED (SDK) → __MAC_OS_X_VERSION_MAX_ALLOWED
- MAC_OS_X_VERSION_x_y → __MAC_x_y
- <Availability.h> __MAC_OS_X_VERSION_* SDK/DT macros are only
available when targeting macOS, while <AvailabilityMacros.h>
MAC_OS_X_VERSION_* SDK/DT macros are available on all Apple platforms,
which may be a source of confusion. (<Availability.h> __MAC_* macros
do remain available on all Apple platforms.)
This change was made mostly mechanically by:
sed -i '' -Ee 's/<AvailabilityMacros.h>/<Availability.h>/g' \
$(git grep -E -l '<AvailabilityMacros.h>' |
grep -v AvailabilityMacros.h)
sed -i '' -Ee 's/(MAC_OS_X_VERSION_(MIN_REQUIRED|MAX_ALLOWED))/__\1/g' \
$(git grep -E -l 'MAC_OS_X_VERSION_(MIN_REQUIRED|MAX_ALLOWED)' |
grep -v AvailabilityMacros.h)
sed -i '' -Ee 's/(MAC_OS_X_VERSION_(10_[0-9]+))/__MAC_\2/g' \
$(git grep -E -l 'MAC_OS_X_VERSION_(10_[0-9]+)' |
grep -v AvailabilityMacros.h)
Bug: crashpad:347
Change-Id: Ibdcd7a6215a82f7060b7b67d98691f88454085fc
Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/2382421
Reviewed-by: Robert Sesek <rsesek@chromium.org>
Commit-Queue: Mark Mentovai <mark@chromium.org>
2020-08-28 20:00:15 -04:00
|
|
|
|
#include <Availability.h>
|
2018-02-22 12:12:26 -08:00
|
|
|
|
#include <OpenCL/opencl.h>
|
2020-08-31 13:46:40 -04:00
|
|
|
|
#include <dlfcn.h>
|
mac: Switch from <AvailabilityMacros.h> to <Availability.h>
The macOS 11.0 SDK, as of Xcode 12b6 12A8189n, has not updated
<AvailabilityMacros.h> with a MAC_OS_X_VERSION_11_0 or
MAC_OS_X_VERSION_10_16 constant. However, the <Availability.h> interface
has been updated to provide both __MAC_11_0 and __MAC_10_16.
<AvailabilityMacros.h>’s MAC_OS_X_VERSION_MAX_ALLOWED, which is supposed
to identify the SDK version, is broken in the 11.0 SDK in that whenever
the deployment target is set to 10.15 or earlier, the SDK will be
mis-identified through this interface as 10.15. When using the
<Availability.h> equivalent, __MAC_OS_X_VERSION_MAX_ALLOWED, the 11.0
SDK is identified as 10.16 (arguably it should be internally versioned
as 11.0, but at least this interface allows it to be detected
unambiguously.) It’s clear that the <AvailabilityMacros.h> interface
provides no meaningful support for the macOS 11.0 SDK at all, but
<Availability.h> does.
<Availability.h> was introduced in the Mac OS X 10.5 SDK, so there is no
relevant SDK version compatibility problem with this interface.
Key differences between these interfaces for the purposes used by
Crashpad:
- <AvailabilityMacros.h> → <Availability.h>
- MAC_OS_X_VERSION_MIN_REQUIRED (DT) → __MAC_OS_X_VERSION_MIN_REQUIRED
- MAC_OS_X_VERSION_MAX_ALLOWED (SDK) → __MAC_OS_X_VERSION_MAX_ALLOWED
- MAC_OS_X_VERSION_x_y → __MAC_x_y
- <Availability.h> __MAC_OS_X_VERSION_* SDK/DT macros are only
available when targeting macOS, while <AvailabilityMacros.h>
MAC_OS_X_VERSION_* SDK/DT macros are available on all Apple platforms,
which may be a source of confusion. (<Availability.h> __MAC_* macros
do remain available on all Apple platforms.)
This change was made mostly mechanically by:
sed -i '' -Ee 's/<AvailabilityMacros.h>/<Availability.h>/g' \
$(git grep -E -l '<AvailabilityMacros.h>' |
grep -v AvailabilityMacros.h)
sed -i '' -Ee 's/(MAC_OS_X_VERSION_(MIN_REQUIRED|MAX_ALLOWED))/__\1/g' \
$(git grep -E -l 'MAC_OS_X_VERSION_(MIN_REQUIRED|MAX_ALLOWED)' |
grep -v AvailabilityMacros.h)
sed -i '' -Ee 's/(MAC_OS_X_VERSION_(10_[0-9]+))/__MAC_\2/g' \
$(git grep -E -l 'MAC_OS_X_VERSION_(10_[0-9]+)' |
grep -v AvailabilityMacros.h)
Bug: crashpad:347
Change-Id: Ibdcd7a6215a82f7060b7b67d98691f88454085fc
Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/2382421
Reviewed-by: Robert Sesek <rsesek@chromium.org>
Commit-Queue: Mark Mentovai <mark@chromium.org>
2020-08-28 20:00:15 -04:00
|
|
|
|
#include <errno.h>
|
2014-09-05 13:43:51 -04:00
|
|
|
|
#include <mach-o/dyld.h>
|
|
|
|
|
#include <mach-o/dyld_images.h>
|
2014-08-25 17:51:09 -04:00
|
|
|
|
#include <mach/mach.h>
|
2022-08-18 14:09:51 -04:00
|
|
|
|
#include <pthread.h>
|
2014-08-25 17:51:09 -04:00
|
|
|
|
#include <string.h>
|
2014-09-05 13:43:51 -04:00
|
|
|
|
#include <sys/stat.h>
|
2020-08-31 13:46:40 -04:00
|
|
|
|
#include <sys/types.h>
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
2022-02-28 20:57:19 -08:00
|
|
|
|
#include <iterator>
|
2014-08-25 17:51:09 -04:00
|
|
|
|
#include <map>
|
2017-10-19 00:26:38 -04:00
|
|
|
|
#include <utility>
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
2020-06-22 11:14:31 +02:00
|
|
|
|
#include "base/check_op.h"
|
2020-08-31 13:46:40 -04:00
|
|
|
|
#include "base/logging.h"
|
2018-11-05 13:34:51 -05:00
|
|
|
|
#include "base/mac/mach_logging.h"
|
2014-08-25 17:51:09 -04:00
|
|
|
|
#include "base/posix/eintr_wrapper.h"
|
2014-09-05 13:43:51 -04:00
|
|
|
|
#include "base/strings/stringprintf.h"
|
2014-08-25 17:51:09 -04:00
|
|
|
|
#include "build/build_config.h"
|
|
|
|
|
#include "gtest/gtest.h"
|
2014-10-17 13:41:45 -04:00
|
|
|
|
#include "snapshot/mac/mach_o_image_reader.h"
|
2018-07-18 11:16:21 -04:00
|
|
|
|
#include "snapshot/mac/mach_o_image_segment_reader.h"
|
test: Move util/test to its own top-level directory, test.
After 9e79ea1da719, it no longer makes sense for crashpad_util_test_lib
to “hide” in util/util_test.gyp. All of util/test is moved to its own
top-level directory, test, which all other test code is allowed to
depend on. test, too, is allowed to depend on all other non-test code.
In a future change, when crashpad_util_test_lib gains a dependency on
crashpad_client, it won’t look so weird for something in util (even
though it’s in util/test) to depend on something in client, because the
thing that needs to depend on client will live in test, not util.
BUG=crashpad:33
R=scottmg@chromium.org
Review URL: https://codereview.chromium.org/1051533002
2015-03-31 17:44:14 -04:00
|
|
|
|
#include "test/errors.h"
|
|
|
|
|
#include "test/mac/dyld.h"
|
|
|
|
|
#include "test/mac/mach_errors.h"
|
|
|
|
|
#include "test/mac/mach_multiprocess.h"
|
2022-06-13 14:44:24 -06:00
|
|
|
|
#include "test/scoped_set_thread_name.h"
|
2014-12-17 14:35:18 -08:00
|
|
|
|
#include "util/file/file_io.h"
|
2015-03-23 16:27:42 -04:00
|
|
|
|
#include "util/mac/mac_util.h"
|
2014-09-16 09:48:01 -04:00
|
|
|
|
#include "util/mach/mach_extensions.h"
|
2017-04-28 10:08:35 -04:00
|
|
|
|
#include "util/misc/from_pointer_cast.h"
|
2014-09-24 13:32:31 -04:00
|
|
|
|
#include "util/synchronization/semaphore.h"
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
2014-10-07 17:28:50 -04:00
|
|
|
|
namespace crashpad {
|
|
|
|
|
namespace test {
|
2014-08-25 17:51:09 -04:00
|
|
|
|
namespace {
|
|
|
|
|
|
2017-07-25 13:34:04 -04:00
|
|
|
|
constexpr char kDyldPath[] = "/usr/lib/dyld";
|
2016-06-17 22:03:01 -04:00
|
|
|
|
|
2018-02-22 12:12:26 -08:00
|
|
|
|
TEST(ProcessReaderMac, SelfBasic) {
|
|
|
|
|
ProcessReaderMac process_reader;
|
2014-08-25 17:51:09 -04:00
|
|
|
|
ASSERT_TRUE(process_reader.Initialize(mach_task_self()));
|
|
|
|
|
|
|
|
|
|
#if !defined(ARCH_CPU_64_BITS)
|
|
|
|
|
EXPECT_FALSE(process_reader.Is64Bit());
|
|
|
|
|
#else
|
|
|
|
|
EXPECT_TRUE(process_reader.Is64Bit());
|
|
|
|
|
#endif
|
|
|
|
|
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
EXPECT_EQ(process_reader.ProcessID(), getpid());
|
|
|
|
|
EXPECT_EQ(process_reader.ParentProcessID(), getppid());
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
2017-07-25 13:34:04 -04:00
|
|
|
|
static constexpr char kTestMemory[] = "Some test memory";
|
2022-02-28 20:57:19 -08:00
|
|
|
|
char buffer[std::size(kTestMemory)];
|
2014-08-25 17:51:09 -04:00
|
|
|
|
ASSERT_TRUE(process_reader.Memory()->Read(
|
2017-04-28 10:08:35 -04:00
|
|
|
|
FromPointerCast<mach_vm_address_t>(kTestMemory),
|
2014-08-25 17:51:09 -04:00
|
|
|
|
sizeof(kTestMemory),
|
|
|
|
|
&buffer));
|
|
|
|
|
EXPECT_STREQ(kTestMemory, buffer);
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-25 13:34:04 -04:00
|
|
|
|
constexpr char kTestMemory[] = "Read me from another process";
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
|
|
|
|
class ProcessReaderChild final : public MachMultiprocess {
|
|
|
|
|
public:
|
|
|
|
|
ProcessReaderChild() : MachMultiprocess() {}
|
|
|
|
|
|
2021-09-20 12:55:12 -07:00
|
|
|
|
ProcessReaderChild(const ProcessReaderChild&) = delete;
|
|
|
|
|
ProcessReaderChild& operator=(const ProcessReaderChild&) = delete;
|
|
|
|
|
|
2014-08-25 17:51:09 -04:00
|
|
|
|
~ProcessReaderChild() {}
|
|
|
|
|
|
2014-08-26 17:10:19 -04:00
|
|
|
|
private:
|
|
|
|
|
void MachMultiprocessParent() override {
|
2018-02-22 12:12:26 -08:00
|
|
|
|
ProcessReaderMac process_reader;
|
2014-08-25 17:51:09 -04:00
|
|
|
|
ASSERT_TRUE(process_reader.Initialize(ChildTask()));
|
|
|
|
|
|
|
|
|
|
#if !defined(ARCH_CPU_64_BITS)
|
|
|
|
|
EXPECT_FALSE(process_reader.Is64Bit());
|
|
|
|
|
#else
|
|
|
|
|
EXPECT_TRUE(process_reader.Is64Bit());
|
|
|
|
|
#endif
|
|
|
|
|
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
EXPECT_EQ(process_reader.ParentProcessID(), getpid());
|
|
|
|
|
EXPECT_EQ(process_reader.ProcessID(), ChildPID());
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
2015-01-28 14:49:42 -08:00
|
|
|
|
FileHandle read_handle = ReadPipeHandle();
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
|
|
|
|
mach_vm_address_t address;
|
Make file_io reads more rational and predictable
ReadFile() attempted to continue reading after a short read. In most
cases, this is fine. However, ReadFile() would keep trying to fill a
partially-filled buffer until experiencing a 0-length read(), signaling
end-of-file. For certain weird file descriptors like terminal input, EOF
is an ephemeral condition, and attempting to read beyond EOF doesn’t
actually return 0 (EOF) provided that they remain open, it will block
waiting for more input. Consequently, ReadFile() and anything based on
ReadFile() had an undocumented and quirky interface, which was that any
short read that it returned (not an underlying short read) actually
indicated EOF.
This facet of ReadFile() was unexpected, so it’s being removed. The new
behavior is that ReadFile() will return an underlying short read. The
behavior of FileReaderInterface::Read() is updated in accordance with
this change.
Upon experiencing a short read, the caller can determine the best
action. Most callers were already prepared for this behavior. Outside of
util/file, only crashpad_database_util properly implemented EOF
detection according to previous semantics, and adapting it to new
semantics is trivial.
Callers who require an exact-length read can use the new
ReadFileExactly(), or the newly renamed LoggingReadFileExactly() or
CheckedReadFileExactly(). These functions will retry following a short
read. The renamed functions were previously called LoggingReadFile() and
CheckedReadFile(), but those names implied that they were simply
wrapping ReadFile(), which is not the case. They wrapped ReadFile() and
further, insisted on a full read. Since ReadFile()’s semantics are now
changing but these functions’ are not, they’re now even more distinct
from ReadFile(), and must be renamed to avoid confusion.
Test: *
Change-Id: I06b77e0d6ad8719bd2eb67dab93a8740542dd908
Reviewed-on: https://chromium-review.googlesource.com/456676
Reviewed-by: Robert Sesek <rsesek@chromium.org>
2017-03-16 13:36:38 -04:00
|
|
|
|
CheckedReadFileExactly(read_handle, &address, sizeof(address));
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
|
|
|
|
std::string read_string;
|
|
|
|
|
ASSERT_TRUE(process_reader.Memory()->ReadCString(address, &read_string));
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
EXPECT_EQ(read_string, kTestMemory);
|
2014-08-25 17:51:09 -04:00
|
|
|
|
}
|
|
|
|
|
|
2014-08-26 17:10:19 -04:00
|
|
|
|
void MachMultiprocessChild() override {
|
2015-01-28 14:49:42 -08:00
|
|
|
|
FileHandle write_handle = WritePipeHandle();
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
2017-04-28 10:08:35 -04:00
|
|
|
|
mach_vm_address_t address = FromPointerCast<mach_vm_address_t>(kTestMemory);
|
2015-01-28 14:49:42 -08:00
|
|
|
|
CheckedWriteFile(write_handle, &address, sizeof(address));
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
2014-09-18 15:03:49 -04:00
|
|
|
|
// Wait for the parent to signal that it’s OK to exit by closing its end of
|
|
|
|
|
// the pipe.
|
2015-01-28 14:49:42 -08:00
|
|
|
|
CheckedReadFileAtEOF(ReadPipeHandle());
|
2014-08-25 17:51:09 -04:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2018-02-22 12:12:26 -08:00
|
|
|
|
TEST(ProcessReaderMac, ChildBasic) {
|
2014-08-25 17:51:09 -04:00
|
|
|
|
ProcessReaderChild process_reader_child;
|
|
|
|
|
process_reader_child.Run();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Returns a thread ID given a pthread_t. This wraps pthread_threadid_np() but
|
|
|
|
|
// that function has a cumbersome interface because it returns a success value.
|
|
|
|
|
// This function CHECKs success and returns the thread ID directly.
|
|
|
|
|
uint64_t PthreadToThreadID(pthread_t pthread) {
|
|
|
|
|
uint64_t thread_id;
|
2018-11-05 13:34:51 -05:00
|
|
|
|
errno = pthread_threadid_np(pthread, &thread_id);
|
|
|
|
|
PCHECK(errno == 0) << "pthread_threadid_np";
|
2014-08-25 17:51:09 -04:00
|
|
|
|
return thread_id;
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-22 12:12:26 -08:00
|
|
|
|
TEST(ProcessReaderMac, SelfOneThread) {
|
2022-06-13 14:44:24 -06:00
|
|
|
|
const ScopedSetThreadName scoped_set_thread_name(
|
|
|
|
|
"ProcessReaderMac/SelfOneThread");
|
|
|
|
|
|
2018-02-22 12:12:26 -08:00
|
|
|
|
ProcessReaderMac process_reader;
|
2014-08-25 17:51:09 -04:00
|
|
|
|
ASSERT_TRUE(process_reader.Initialize(mach_task_self()));
|
|
|
|
|
|
2018-02-22 12:12:26 -08:00
|
|
|
|
const std::vector<ProcessReaderMac::Thread>& threads =
|
|
|
|
|
process_reader.Threads();
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
|
|
|
|
// If other tests ran in this process previously, threads may have been
|
|
|
|
|
// created and may still be running. This check must look for at least one
|
|
|
|
|
// thread, not exactly one thread.
|
|
|
|
|
ASSERT_GE(threads.size(), 1u);
|
|
|
|
|
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
EXPECT_EQ(threads[0].id, PthreadToThreadID(pthread_self()));
|
2022-06-13 14:44:24 -06:00
|
|
|
|
EXPECT_EQ(threads[0].name, "ProcessReaderMac/SelfOneThread");
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
2014-09-18 13:53:43 -04:00
|
|
|
|
thread_t thread_self = MachThreadSelf();
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
EXPECT_EQ(threads[0].port, thread_self);
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
EXPECT_EQ(threads[0].suspend_count, 0);
|
2014-08-25 17:51:09 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class TestThreadPool {
|
|
|
|
|
public:
|
|
|
|
|
struct ThreadExpectation {
|
2022-08-18 14:09:51 -04:00
|
|
|
|
// The stack's base (highest) address.
|
|
|
|
|
mach_vm_address_t stack_base;
|
|
|
|
|
|
|
|
|
|
// The stack's maximum size.
|
|
|
|
|
mach_vm_size_t stack_size;
|
|
|
|
|
|
2014-08-25 17:51:09 -04:00
|
|
|
|
int suspend_count;
|
2022-06-13 14:44:24 -06:00
|
|
|
|
std::string thread_name;
|
2014-08-25 17:51:09 -04:00
|
|
|
|
};
|
|
|
|
|
|
2022-06-13 14:44:24 -06:00
|
|
|
|
TestThreadPool(const std::string& thread_name_prefix)
|
|
|
|
|
: thread_infos_(), thread_name_prefix_(thread_name_prefix) {}
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
2021-09-20 12:55:12 -07:00
|
|
|
|
TestThreadPool(const TestThreadPool&) = delete;
|
|
|
|
|
TestThreadPool& operator=(const TestThreadPool&) = delete;
|
|
|
|
|
|
2014-08-25 17:51:09 -04:00
|
|
|
|
// Resumes suspended threads, signals each thread’s exit semaphore asking it
|
|
|
|
|
// to exit, and joins each thread, blocking until they have all exited.
|
|
|
|
|
~TestThreadPool() {
|
2017-10-19 00:26:38 -04:00
|
|
|
|
for (const auto& thread_info : thread_infos_) {
|
2014-09-18 13:53:43 -04:00
|
|
|
|
thread_t thread_port = pthread_mach_thread_np(thread_info->pthread);
|
2014-08-25 17:51:09 -04:00
|
|
|
|
while (thread_info->suspend_count > 0) {
|
|
|
|
|
kern_return_t kr = thread_resume(thread_port);
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
EXPECT_EQ(kr, KERN_SUCCESS) << MachErrorMessage(kr, "thread_resume");
|
2014-08-25 17:51:09 -04:00
|
|
|
|
--thread_info->suspend_count;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-19 00:26:38 -04:00
|
|
|
|
for (const auto& thread_info : thread_infos_) {
|
2014-09-24 13:32:31 -04:00
|
|
|
|
thread_info->exit_semaphore.Signal();
|
2014-08-25 17:51:09 -04:00
|
|
|
|
}
|
|
|
|
|
|
2017-10-19 00:26:38 -04:00
|
|
|
|
for (const auto& thread_info : thread_infos_) {
|
2014-10-14 11:10:45 -04:00
|
|
|
|
int rv = pthread_join(thread_info->pthread, nullptr);
|
2014-08-25 17:51:09 -04:00
|
|
|
|
CHECK_EQ(0, rv);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Starts |thread_count| threads and waits on each thread’s ready semaphore,
|
|
|
|
|
// so that when this function returns, all threads have been started and have
|
|
|
|
|
// all run to the point that they’ve signalled that they are ready.
|
|
|
|
|
void StartThreads(size_t thread_count) {
|
|
|
|
|
ASSERT_TRUE(thread_infos_.empty());
|
|
|
|
|
|
|
|
|
|
for (size_t thread_index = 0; thread_index < thread_count; ++thread_index) {
|
2022-06-13 14:44:24 -06:00
|
|
|
|
std::string thread_name = base::StringPrintf(
|
|
|
|
|
"%s-%zu", thread_name_prefix_.c_str(), thread_index);
|
|
|
|
|
thread_infos_.push_back(
|
|
|
|
|
std::make_unique<ThreadInfo>(std::move(thread_name)));
|
2017-10-19 00:26:38 -04:00
|
|
|
|
ThreadInfo* thread_info = thread_infos_.back().get();
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
2018-02-22 12:12:26 -08:00
|
|
|
|
int rv = pthread_create(
|
|
|
|
|
&thread_info->pthread, nullptr, ThreadMain, thread_info);
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
ASSERT_EQ(rv, 0);
|
2014-08-25 17:51:09 -04:00
|
|
|
|
}
|
|
|
|
|
|
2017-10-19 00:26:38 -04:00
|
|
|
|
for (const auto& thread_info : thread_infos_) {
|
2014-09-24 13:32:31 -04:00
|
|
|
|
thread_info->ready_semaphore.Wait();
|
2014-08-25 17:51:09 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If present, suspend the thread at indices 1 through 3 the same number of
|
|
|
|
|
// times as their index. This tests reporting of suspend counts.
|
|
|
|
|
for (size_t thread_index = 1;
|
|
|
|
|
thread_index < thread_infos_.size() && thread_index < 4;
|
|
|
|
|
++thread_index) {
|
2014-09-18 13:53:43 -04:00
|
|
|
|
thread_t thread_port =
|
2014-08-25 17:51:09 -04:00
|
|
|
|
pthread_mach_thread_np(thread_infos_[thread_index]->pthread);
|
2018-02-22 12:12:26 -08:00
|
|
|
|
for (size_t suspend_count = 0; suspend_count < thread_index;
|
2014-08-25 17:51:09 -04:00
|
|
|
|
++suspend_count) {
|
|
|
|
|
kern_return_t kr = thread_suspend(thread_port);
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
EXPECT_EQ(kr, KERN_SUCCESS) << MachErrorMessage(kr, "thread_suspend");
|
2014-08-25 17:51:09 -04:00
|
|
|
|
if (kr == KERN_SUCCESS) {
|
|
|
|
|
++thread_infos_[thread_index]->suspend_count;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-22 12:12:26 -08:00
|
|
|
|
uint64_t GetThreadInfo(size_t thread_index, ThreadExpectation* expectation) {
|
2014-08-25 17:51:09 -04:00
|
|
|
|
CHECK_LT(thread_index, thread_infos_.size());
|
|
|
|
|
|
2017-10-19 00:26:38 -04:00
|
|
|
|
const auto& thread_info = thread_infos_[thread_index];
|
2022-08-18 14:09:51 -04:00
|
|
|
|
expectation->stack_base = thread_info->stack_base;
|
|
|
|
|
expectation->stack_size = thread_info->stack_size;
|
2014-08-25 17:51:09 -04:00
|
|
|
|
expectation->suspend_count = thread_info->suspend_count;
|
2022-06-13 14:44:24 -06:00
|
|
|
|
expectation->thread_name = thread_info->thread_name;
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
|
|
|
|
return PthreadToThreadID(thread_info->pthread);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
struct ThreadInfo {
|
2022-06-13 14:44:24 -06:00
|
|
|
|
ThreadInfo(const std::string& thread_name)
|
2014-10-14 11:10:45 -04:00
|
|
|
|
: pthread(nullptr),
|
2022-08-18 14:09:51 -04:00
|
|
|
|
stack_base(0),
|
|
|
|
|
stack_size(0),
|
2014-09-24 13:32:31 -04:00
|
|
|
|
ready_semaphore(0),
|
|
|
|
|
exit_semaphore(0),
|
2022-06-13 14:44:24 -06:00
|
|
|
|
suspend_count(0),
|
|
|
|
|
thread_name(thread_name) {}
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
2014-09-24 13:32:31 -04:00
|
|
|
|
~ThreadInfo() {}
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
|
|
|
|
// The thread’s ID, set at the time the thread is created.
|
|
|
|
|
pthread_t pthread;
|
|
|
|
|
|
2022-08-18 14:09:51 -04:00
|
|
|
|
// The base address of thread’s stack. The thread sets this in
|
2014-08-25 17:51:09 -04:00
|
|
|
|
// its ThreadMain().
|
2022-08-18 14:09:51 -04:00
|
|
|
|
mach_vm_address_t stack_base;
|
|
|
|
|
|
|
|
|
|
// The stack's maximum size. The thread sets this in its ThreadMain().
|
|
|
|
|
mach_vm_size_t stack_size;
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
|
|
|
|
// The worker thread signals ready_semaphore to indicate that it’s done
|
|
|
|
|
// setting up its ThreadInfo structure. The main thread waits on this
|
|
|
|
|
// semaphore before using any data that the worker thread is responsible for
|
|
|
|
|
// setting.
|
2014-09-24 13:32:31 -04:00
|
|
|
|
Semaphore ready_semaphore;
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
|
|
|
|
// The worker thread waits on exit_semaphore to determine when it’s safe to
|
|
|
|
|
// exit. The main thread signals exit_semaphore when it no longer needs the
|
|
|
|
|
// worker thread.
|
2014-09-24 13:32:31 -04:00
|
|
|
|
Semaphore exit_semaphore;
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
|
|
|
|
// The thread’s suspend count.
|
|
|
|
|
int suspend_count;
|
2022-06-13 14:44:24 -06:00
|
|
|
|
|
|
|
|
|
// The thread's name.
|
|
|
|
|
const std::string thread_name;
|
2014-08-25 17:51:09 -04:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void* ThreadMain(void* argument) {
|
|
|
|
|
ThreadInfo* thread_info = static_cast<ThreadInfo*>(argument);
|
2022-06-13 14:44:24 -06:00
|
|
|
|
const ScopedSetThreadName scoped_set_thread_name(thread_info->thread_name);
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
2022-08-18 14:09:51 -04:00
|
|
|
|
pthread_t thread = pthread_self();
|
|
|
|
|
thread_info->stack_base =
|
|
|
|
|
FromPointerCast<mach_vm_address_t>(pthread_get_stackaddr_np(thread));
|
|
|
|
|
thread_info->stack_size = pthread_get_stacksize_np(thread);
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
2014-09-24 13:32:31 -04:00
|
|
|
|
thread_info->ready_semaphore.Signal();
|
|
|
|
|
thread_info->exit_semaphore.Wait();
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
|
|
|
|
// Check this here after everything’s known to be synchronized, otherwise
|
|
|
|
|
// there’s a race between the parent thread storing this thread’s pthread_t
|
|
|
|
|
// in thread_info_pthread and this thread starting and attempting to access
|
|
|
|
|
// it.
|
|
|
|
|
CHECK_EQ(pthread_self(), thread_info->pthread);
|
|
|
|
|
|
2014-10-14 11:10:45 -04:00
|
|
|
|
return nullptr;
|
2014-08-25 17:51:09 -04:00
|
|
|
|
}
|
|
|
|
|
|
2017-10-19 00:26:38 -04:00
|
|
|
|
// This is a vector of pointers because the address of a ThreadInfo object is
|
2014-08-25 17:51:09 -04:00
|
|
|
|
// passed to each thread’s ThreadMain(), so they cannot move around in memory.
|
2017-10-19 00:26:38 -04:00
|
|
|
|
std::vector<std::unique_ptr<ThreadInfo>> thread_infos_;
|
2022-06-13 14:44:24 -06:00
|
|
|
|
|
|
|
|
|
// Prefix to use for each thread's name, suffixed with "-$threadindex".
|
|
|
|
|
const std::string thread_name_prefix_;
|
2014-08-25 17:51:09 -04:00
|
|
|
|
};
|
|
|
|
|
|
2014-11-05 14:09:01 -05:00
|
|
|
|
using ThreadMap = std::map<uint64_t, TestThreadPool::ThreadExpectation>;
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
2018-02-22 12:12:26 -08:00
|
|
|
|
// Verifies that all of the threads in |threads|, obtained from
|
|
|
|
|
// ProcessReaderMac, agree with the expectation in |thread_map|. If
|
|
|
|
|
// |tolerate_extra_threads| is true, |threads| is allowed to contain threads
|
|
|
|
|
// that are not listed in |thread_map|. This is useful when testing situations
|
|
|
|
|
// where code outside of the test’s control (such as system libraries) may start
|
|
|
|
|
// threads, or may have started threads prior to a test’s execution.
|
2014-08-25 17:51:09 -04:00
|
|
|
|
void ExpectSeveralThreads(ThreadMap* thread_map,
|
2018-02-22 12:12:26 -08:00
|
|
|
|
const std::vector<ProcessReaderMac::Thread>& threads,
|
2014-08-25 17:51:09 -04:00
|
|
|
|
const bool tolerate_extra_threads) {
|
|
|
|
|
if (tolerate_extra_threads) {
|
|
|
|
|
ASSERT_GE(threads.size(), thread_map->size());
|
|
|
|
|
} else {
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
ASSERT_EQ(threads.size(), thread_map->size());
|
2014-08-25 17:51:09 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (size_t thread_index = 0; thread_index < threads.size(); ++thread_index) {
|
2018-02-22 12:12:26 -08:00
|
|
|
|
const ProcessReaderMac::Thread& thread = threads[thread_index];
|
2014-08-25 17:51:09 -04:00
|
|
|
|
mach_vm_address_t thread_stack_region_end =
|
|
|
|
|
thread.stack_region_address + thread.stack_region_size;
|
|
|
|
|
|
|
|
|
|
const auto& iterator = thread_map->find(thread.id);
|
|
|
|
|
if (!tolerate_extra_threads) {
|
|
|
|
|
// Make sure that the thread is in the expectation map.
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
ASSERT_NE(iterator, thread_map->end());
|
2014-08-25 17:51:09 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (iterator != thread_map->end()) {
|
2022-08-18 14:09:51 -04:00
|
|
|
|
mach_vm_address_t expected_stack_region_end = iterator->second.stack_base;
|
|
|
|
|
if (thread_index > 0) {
|
|
|
|
|
// Non-main threads use the stack region to store thread data. See
|
2022-08-19 15:54:28 -04:00
|
|
|
|
// macOS 12 libpthread-486.100.11 src/pthread.c _pthread_allocate().
|
|
|
|
|
#if defined(ARCH_CPU_ARM64)
|
|
|
|
|
// arm64 has an additional offset for alignment. See macOS 12
|
|
|
|
|
// libpthread-486.100.11 src/pthread.c _pthread_allocate() and
|
|
|
|
|
// PTHREAD_T_OFFSET (defined in src/types_internal.h).
|
|
|
|
|
expected_stack_region_end += sizeof(_opaque_pthread_t) + 0x3000;
|
|
|
|
|
#else
|
2022-08-18 14:09:51 -04:00
|
|
|
|
expected_stack_region_end += sizeof(_opaque_pthread_t);
|
2022-08-19 15:54:28 -04:00
|
|
|
|
#endif
|
2022-08-18 14:09:51 -04:00
|
|
|
|
}
|
|
|
|
|
EXPECT_LT(iterator->second.stack_base - iterator->second.stack_size,
|
|
|
|
|
thread.stack_region_address);
|
|
|
|
|
EXPECT_EQ(expected_stack_region_end, thread_stack_region_end);
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
EXPECT_EQ(thread.suspend_count, iterator->second.suspend_count);
|
2022-06-13 14:44:24 -06:00
|
|
|
|
EXPECT_EQ(thread.name, iterator->second.thread_name);
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
|
|
|
|
// Remove the thread from the expectation map since it’s already been
|
|
|
|
|
// found. This makes it easy to check for duplicate thread IDs, and makes
|
|
|
|
|
// it easy to check that all expected threads were found.
|
|
|
|
|
thread_map->erase(iterator);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Make sure that this thread’s ID, stack region, and port don’t conflict
|
|
|
|
|
// with any other thread’s. Each thread should have a unique value for its
|
|
|
|
|
// ID and port, and each should have its own stack that doesn’t touch any
|
|
|
|
|
// other thread’s stack.
|
2018-02-22 12:12:26 -08:00
|
|
|
|
for (size_t other_thread_index = 0; other_thread_index < threads.size();
|
2014-08-25 17:51:09 -04:00
|
|
|
|
++other_thread_index) {
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
if (other_thread_index == thread_index) {
|
2014-08-25 17:51:09 -04:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-22 12:12:26 -08:00
|
|
|
|
const ProcessReaderMac::Thread& other_thread =
|
|
|
|
|
threads[other_thread_index];
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
EXPECT_NE(other_thread.id, thread.id);
|
|
|
|
|
EXPECT_NE(other_thread.port, thread.port);
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
|
|
|
|
mach_vm_address_t other_thread_stack_region_end =
|
|
|
|
|
other_thread.stack_region_address + other_thread.stack_region_size;
|
2018-02-22 12:12:26 -08:00
|
|
|
|
EXPECT_FALSE(thread.stack_region_address >=
|
|
|
|
|
other_thread.stack_region_address &&
|
|
|
|
|
thread.stack_region_address < other_thread_stack_region_end);
|
|
|
|
|
EXPECT_FALSE(thread_stack_region_end >
|
|
|
|
|
other_thread.stack_region_address &&
|
|
|
|
|
thread_stack_region_end <= other_thread_stack_region_end);
|
2014-08-25 17:51:09 -04:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Make sure that each expected thread was found.
|
|
|
|
|
EXPECT_TRUE(thread_map->empty());
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-22 12:12:26 -08:00
|
|
|
|
TEST(ProcessReaderMac, SelfSeveralThreads) {
|
|
|
|
|
// Set up the ProcessReaderMac here, before any other threads are running.
|
|
|
|
|
// This tests that the threads it returns are lazily initialized as a snapshot
|
|
|
|
|
// of the threads at the time of the first call to Threads(), and not at the
|
2014-08-25 17:51:09 -04:00
|
|
|
|
// time the ProcessReader was created or initialized.
|
2018-02-22 12:12:26 -08:00
|
|
|
|
ProcessReaderMac process_reader;
|
2014-08-25 17:51:09 -04:00
|
|
|
|
ASSERT_TRUE(process_reader.Initialize(mach_task_self()));
|
|
|
|
|
|
2022-06-13 14:44:24 -06:00
|
|
|
|
TestThreadPool thread_pool("SelfSeveralThreads");
|
2017-07-25 19:15:48 -04:00
|
|
|
|
constexpr size_t kChildThreads = 16;
|
2014-10-09 15:08:54 -04:00
|
|
|
|
ASSERT_NO_FATAL_FAILURE(thread_pool.StartThreads(kChildThreads));
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
|
|
|
|
// Build a map of all expected threads, keyed by each thread’s ID. The values
|
|
|
|
|
// are addresses that should lie somewhere within each thread’s stack.
|
|
|
|
|
ThreadMap thread_map;
|
|
|
|
|
const uint64_t self_thread_id = PthreadToThreadID(pthread_self());
|
|
|
|
|
TestThreadPool::ThreadExpectation expectation;
|
2022-08-18 16:38:57 -04:00
|
|
|
|
expectation.stack_base = FromPointerCast<mach_vm_address_t>(
|
|
|
|
|
pthread_get_stackaddr_np(pthread_self()));
|
|
|
|
|
expectation.stack_size = pthread_get_stacksize_np(pthread_self());
|
2014-08-25 17:51:09 -04:00
|
|
|
|
expectation.suspend_count = 0;
|
|
|
|
|
thread_map[self_thread_id] = expectation;
|
|
|
|
|
for (size_t thread_index = 0; thread_index < kChildThreads; ++thread_index) {
|
|
|
|
|
uint64_t thread_id = thread_pool.GetThreadInfo(thread_index, &expectation);
|
|
|
|
|
|
|
|
|
|
// There can’t be any duplicate thread IDs.
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
EXPECT_EQ(thread_map.count(thread_id), 0u);
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
2022-06-13 14:44:24 -06:00
|
|
|
|
expectation.thread_name =
|
|
|
|
|
base::StringPrintf("SelfSeveralThreads-%zu", thread_index);
|
2014-08-25 17:51:09 -04:00
|
|
|
|
thread_map[thread_id] = expectation;
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-22 12:12:26 -08:00
|
|
|
|
const std::vector<ProcessReaderMac::Thread>& threads =
|
|
|
|
|
process_reader.Threads();
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
|
|
|
|
// Other tests that have run previously may have resulted in the creation of
|
|
|
|
|
// threads that still exist, so pass true for |tolerate_extra_threads|.
|
|
|
|
|
ExpectSeveralThreads(&thread_map, threads, true);
|
|
|
|
|
|
|
|
|
|
// When testing in-process, verify that when this thread shows up in the
|
|
|
|
|
// vector, it has the expected thread port, and that this thread port only
|
|
|
|
|
// shows up once.
|
2014-09-18 13:53:43 -04:00
|
|
|
|
thread_t thread_self = MachThreadSelf();
|
2014-08-25 17:51:09 -04:00
|
|
|
|
bool found_thread_self = false;
|
2018-02-22 12:12:26 -08:00
|
|
|
|
for (const ProcessReaderMac::Thread& thread : threads) {
|
2014-08-25 17:51:09 -04:00
|
|
|
|
if (thread.port == thread_self) {
|
|
|
|
|
EXPECT_FALSE(found_thread_self);
|
|
|
|
|
found_thread_self = true;
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
EXPECT_EQ(thread.id, self_thread_id);
|
2014-08-25 17:51:09 -04:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
EXPECT_TRUE(found_thread_self);
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-05 13:34:51 -05:00
|
|
|
|
uint64_t GetThreadID() {
|
|
|
|
|
thread_identifier_info info;
|
|
|
|
|
mach_msg_type_number_t info_count = THREAD_IDENTIFIER_INFO_COUNT;
|
|
|
|
|
kern_return_t kr = thread_info(MachThreadSelf(),
|
|
|
|
|
THREAD_IDENTIFIER_INFO,
|
|
|
|
|
reinterpret_cast<thread_info_t>(&info),
|
|
|
|
|
&info_count);
|
|
|
|
|
MACH_CHECK(kr == KERN_SUCCESS, kr) << "thread_info";
|
|
|
|
|
|
|
|
|
|
return info.thread_id;
|
|
|
|
|
}
|
|
|
|
|
|
2014-08-25 17:51:09 -04:00
|
|
|
|
class ProcessReaderThreadedChild final : public MachMultiprocess {
|
|
|
|
|
public:
|
2022-06-13 14:44:24 -06:00
|
|
|
|
explicit ProcessReaderThreadedChild(const std::string thread_name_prefix,
|
|
|
|
|
size_t thread_count)
|
|
|
|
|
: MachMultiprocess(),
|
|
|
|
|
thread_name_prefix_(thread_name_prefix),
|
|
|
|
|
thread_count_(thread_count) {}
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
2021-09-20 12:55:12 -07:00
|
|
|
|
ProcessReaderThreadedChild(const ProcessReaderThreadedChild&) = delete;
|
|
|
|
|
ProcessReaderThreadedChild& operator=(const ProcessReaderThreadedChild&) =
|
|
|
|
|
delete;
|
|
|
|
|
|
2014-08-25 17:51:09 -04:00
|
|
|
|
~ProcessReaderThreadedChild() {}
|
|
|
|
|
|
2014-08-26 17:10:19 -04:00
|
|
|
|
private:
|
|
|
|
|
void MachMultiprocessParent() override {
|
2018-02-22 12:12:26 -08:00
|
|
|
|
ProcessReaderMac process_reader;
|
2014-08-25 17:51:09 -04:00
|
|
|
|
ASSERT_TRUE(process_reader.Initialize(ChildTask()));
|
|
|
|
|
|
2015-01-28 14:49:42 -08:00
|
|
|
|
FileHandle read_handle = ReadPipeHandle();
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
|
|
|
|
// Build a map of all expected threads, keyed by each thread’s ID, and with
|
|
|
|
|
// addresses that should lie somewhere within each thread’s stack as values.
|
|
|
|
|
// These IDs and addresses all come from the child process via the pipe.
|
|
|
|
|
ThreadMap thread_map;
|
2018-02-22 12:12:26 -08:00
|
|
|
|
for (size_t thread_index = 0; thread_index < thread_count_ + 1;
|
2014-08-25 17:51:09 -04:00
|
|
|
|
++thread_index) {
|
|
|
|
|
uint64_t thread_id;
|
Make file_io reads more rational and predictable
ReadFile() attempted to continue reading after a short read. In most
cases, this is fine. However, ReadFile() would keep trying to fill a
partially-filled buffer until experiencing a 0-length read(), signaling
end-of-file. For certain weird file descriptors like terminal input, EOF
is an ephemeral condition, and attempting to read beyond EOF doesn’t
actually return 0 (EOF) provided that they remain open, it will block
waiting for more input. Consequently, ReadFile() and anything based on
ReadFile() had an undocumented and quirky interface, which was that any
short read that it returned (not an underlying short read) actually
indicated EOF.
This facet of ReadFile() was unexpected, so it’s being removed. The new
behavior is that ReadFile() will return an underlying short read. The
behavior of FileReaderInterface::Read() is updated in accordance with
this change.
Upon experiencing a short read, the caller can determine the best
action. Most callers were already prepared for this behavior. Outside of
util/file, only crashpad_database_util properly implemented EOF
detection according to previous semantics, and adapting it to new
semantics is trivial.
Callers who require an exact-length read can use the new
ReadFileExactly(), or the newly renamed LoggingReadFileExactly() or
CheckedReadFileExactly(). These functions will retry following a short
read. The renamed functions were previously called LoggingReadFile() and
CheckedReadFile(), but those names implied that they were simply
wrapping ReadFile(), which is not the case. They wrapped ReadFile() and
further, insisted on a full read. Since ReadFile()’s semantics are now
changing but these functions’ are not, they’re now even more distinct
from ReadFile(), and must be renamed to avoid confusion.
Test: *
Change-Id: I06b77e0d6ad8719bd2eb67dab93a8740542dd908
Reviewed-on: https://chromium-review.googlesource.com/456676
Reviewed-by: Robert Sesek <rsesek@chromium.org>
2017-03-16 13:36:38 -04:00
|
|
|
|
CheckedReadFileExactly(read_handle, &thread_id, sizeof(thread_id));
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
|
|
|
|
TestThreadPool::ThreadExpectation expectation;
|
2022-08-18 14:09:51 -04:00
|
|
|
|
CheckedReadFileExactly(
|
|
|
|
|
read_handle, &expectation.stack_base, sizeof(expectation.stack_base));
|
|
|
|
|
CheckedReadFileExactly(
|
|
|
|
|
read_handle, &expectation.stack_size, sizeof(expectation.stack_size));
|
Make file_io reads more rational and predictable
ReadFile() attempted to continue reading after a short read. In most
cases, this is fine. However, ReadFile() would keep trying to fill a
partially-filled buffer until experiencing a 0-length read(), signaling
end-of-file. For certain weird file descriptors like terminal input, EOF
is an ephemeral condition, and attempting to read beyond EOF doesn’t
actually return 0 (EOF) provided that they remain open, it will block
waiting for more input. Consequently, ReadFile() and anything based on
ReadFile() had an undocumented and quirky interface, which was that any
short read that it returned (not an underlying short read) actually
indicated EOF.
This facet of ReadFile() was unexpected, so it’s being removed. The new
behavior is that ReadFile() will return an underlying short read. The
behavior of FileReaderInterface::Read() is updated in accordance with
this change.
Upon experiencing a short read, the caller can determine the best
action. Most callers were already prepared for this behavior. Outside of
util/file, only crashpad_database_util properly implemented EOF
detection according to previous semantics, and adapting it to new
semantics is trivial.
Callers who require an exact-length read can use the new
ReadFileExactly(), or the newly renamed LoggingReadFileExactly() or
CheckedReadFileExactly(). These functions will retry following a short
read. The renamed functions were previously called LoggingReadFile() and
CheckedReadFile(), but those names implied that they were simply
wrapping ReadFile(), which is not the case. They wrapped ReadFile() and
further, insisted on a full read. Since ReadFile()’s semantics are now
changing but these functions’ are not, they’re now even more distinct
from ReadFile(), and must be renamed to avoid confusion.
Test: *
Change-Id: I06b77e0d6ad8719bd2eb67dab93a8740542dd908
Reviewed-on: https://chromium-review.googlesource.com/456676
Reviewed-by: Robert Sesek <rsesek@chromium.org>
2017-03-16 13:36:38 -04:00
|
|
|
|
CheckedReadFileExactly(read_handle,
|
|
|
|
|
&expectation.suspend_count,
|
|
|
|
|
sizeof(expectation.suspend_count));
|
2022-06-13 14:44:24 -06:00
|
|
|
|
std::string::size_type expected_thread_name_length;
|
|
|
|
|
CheckedReadFileExactly(read_handle,
|
|
|
|
|
&expected_thread_name_length,
|
|
|
|
|
sizeof(expected_thread_name_length));
|
|
|
|
|
std::string expected_thread_name(expected_thread_name_length, '\0');
|
|
|
|
|
CheckedReadFileExactly(read_handle,
|
|
|
|
|
expected_thread_name.data(),
|
|
|
|
|
expected_thread_name_length);
|
|
|
|
|
expectation.thread_name = expected_thread_name;
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
|
|
|
|
// There can’t be any duplicate thread IDs.
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
EXPECT_EQ(thread_map.count(thread_id), 0u);
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
|
|
|
|
thread_map[thread_id] = expectation;
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-22 12:12:26 -08:00
|
|
|
|
const std::vector<ProcessReaderMac::Thread>& threads =
|
|
|
|
|
process_reader.Threads();
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
|
|
|
|
// The child shouldn’t have any threads other than its main thread and the
|
|
|
|
|
// ones it created in its pool, so pass false for |tolerate_extra_threads|.
|
|
|
|
|
ExpectSeveralThreads(&thread_map, threads, false);
|
|
|
|
|
}
|
|
|
|
|
|
2014-08-26 17:10:19 -04:00
|
|
|
|
void MachMultiprocessChild() override {
|
2022-06-13 14:44:24 -06:00
|
|
|
|
TestThreadPool thread_pool(thread_name_prefix_);
|
2014-10-09 15:08:54 -04:00
|
|
|
|
ASSERT_NO_FATAL_FAILURE(thread_pool.StartThreads(thread_count_));
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
2022-06-13 14:44:24 -06:00
|
|
|
|
const std::string current_thread_name(base::StringPrintf(
|
|
|
|
|
"%s-MachMultiprocessChild", thread_name_prefix_.c_str()));
|
|
|
|
|
const ScopedSetThreadName scoped_set_thread_name(current_thread_name);
|
|
|
|
|
|
2015-01-28 14:49:42 -08:00
|
|
|
|
FileHandle write_handle = WritePipeHandle();
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
|
|
|
|
// This thread isn’t part of the thread pool, but the parent will be able
|
|
|
|
|
// to inspect it. Write an entry for it.
|
2018-11-05 13:34:51 -05:00
|
|
|
|
uint64_t thread_id = GetThreadID();
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
2015-01-28 14:49:42 -08:00
|
|
|
|
CheckedWriteFile(write_handle, &thread_id, sizeof(thread_id));
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
|
|
|
|
TestThreadPool::ThreadExpectation expectation;
|
2022-08-18 14:09:51 -04:00
|
|
|
|
pthread_t thread = pthread_self();
|
|
|
|
|
expectation.stack_base =
|
|
|
|
|
FromPointerCast<mach_vm_address_t>(pthread_get_stackaddr_np(thread));
|
|
|
|
|
expectation.stack_size = pthread_get_stacksize_np(thread);
|
2014-08-25 17:51:09 -04:00
|
|
|
|
expectation.suspend_count = 0;
|
|
|
|
|
|
2022-08-18 14:09:51 -04:00
|
|
|
|
CheckedWriteFile(
|
|
|
|
|
write_handle, &expectation.stack_base, sizeof(expectation.stack_base));
|
|
|
|
|
CheckedWriteFile(
|
|
|
|
|
write_handle, &expectation.stack_size, sizeof(expectation.stack_size));
|
2015-01-28 14:49:42 -08:00
|
|
|
|
CheckedWriteFile(write_handle,
|
2014-12-17 14:35:18 -08:00
|
|
|
|
&expectation.suspend_count,
|
|
|
|
|
sizeof(expectation.suspend_count));
|
2022-06-13 14:44:24 -06:00
|
|
|
|
const std::string::size_type current_thread_name_length =
|
|
|
|
|
current_thread_name.length();
|
|
|
|
|
CheckedWriteFile(write_handle,
|
|
|
|
|
¤t_thread_name_length,
|
|
|
|
|
sizeof(current_thread_name_length));
|
|
|
|
|
CheckedWriteFile(
|
|
|
|
|
write_handle, current_thread_name.data(), current_thread_name_length);
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
|
|
|
|
// Write an entry for everything in the thread pool.
|
2018-02-22 12:12:26 -08:00
|
|
|
|
for (size_t thread_index = 0; thread_index < thread_count_;
|
2014-08-25 17:51:09 -04:00
|
|
|
|
++thread_index) {
|
2021-10-25 07:23:09 -07:00
|
|
|
|
thread_id = thread_pool.GetThreadInfo(thread_index, &expectation);
|
2014-08-25 17:51:09 -04:00
|
|
|
|
|
2015-01-28 14:49:42 -08:00
|
|
|
|
CheckedWriteFile(write_handle, &thread_id, sizeof(thread_id));
|
|
|
|
|
CheckedWriteFile(write_handle,
|
2022-08-18 14:09:51 -04:00
|
|
|
|
&expectation.stack_base,
|
|
|
|
|
sizeof(expectation.stack_base));
|
|
|
|
|
CheckedWriteFile(write_handle,
|
|
|
|
|
&expectation.stack_size,
|
|
|
|
|
sizeof(expectation.stack_size));
|
2015-01-28 14:49:42 -08:00
|
|
|
|
CheckedWriteFile(write_handle,
|
2014-12-17 14:35:18 -08:00
|
|
|
|
&expectation.suspend_count,
|
|
|
|
|
sizeof(expectation.suspend_count));
|
2022-06-13 14:44:24 -06:00
|
|
|
|
const std::string thread_pool_thread_name = base::StringPrintf(
|
|
|
|
|
"%s-%zu", thread_name_prefix_.c_str(), thread_index);
|
|
|
|
|
const std::string::size_type thread_pool_thread_name_length =
|
|
|
|
|
thread_pool_thread_name.length();
|
|
|
|
|
CheckedWriteFile(write_handle,
|
|
|
|
|
&thread_pool_thread_name_length,
|
|
|
|
|
sizeof(thread_pool_thread_name_length));
|
|
|
|
|
CheckedWriteFile(write_handle,
|
|
|
|
|
thread_pool_thread_name.data(),
|
|
|
|
|
thread_pool_thread_name_length);
|
2014-08-25 17:51:09 -04:00
|
|
|
|
}
|
|
|
|
|
|
2014-09-18 15:03:49 -04:00
|
|
|
|
// Wait for the parent to signal that it’s OK to exit by closing its end of
|
|
|
|
|
// the pipe.
|
2015-01-28 14:49:42 -08:00
|
|
|
|
CheckedReadFileAtEOF(ReadPipeHandle());
|
2014-08-25 17:51:09 -04:00
|
|
|
|
}
|
|
|
|
|
|
2022-06-13 14:44:24 -06:00
|
|
|
|
const std::string thread_name_prefix_;
|
2014-08-25 17:51:09 -04:00
|
|
|
|
size_t thread_count_;
|
|
|
|
|
};
|
|
|
|
|
|
2018-02-22 12:12:26 -08:00
|
|
|
|
TEST(ProcessReaderMac, ChildOneThread) {
|
2014-08-25 17:51:09 -04:00
|
|
|
|
// The main thread plus zero child threads equals one thread.
|
2017-07-25 19:15:48 -04:00
|
|
|
|
constexpr size_t kChildThreads = 0;
|
2022-06-13 14:44:24 -06:00
|
|
|
|
ProcessReaderThreadedChild process_reader_threaded_child("ChildOneThread",
|
|
|
|
|
kChildThreads);
|
2014-08-25 17:51:09 -04:00
|
|
|
|
process_reader_threaded_child.Run();
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-22 12:12:26 -08:00
|
|
|
|
TEST(ProcessReaderMac, ChildSeveralThreads) {
|
2017-07-25 19:15:48 -04:00
|
|
|
|
constexpr size_t kChildThreads = 64;
|
2022-06-13 14:44:24 -06:00
|
|
|
|
ProcessReaderThreadedChild process_reader_threaded_child(
|
|
|
|
|
"ChildSeveralThreads", kChildThreads);
|
2014-08-25 17:51:09 -04:00
|
|
|
|
process_reader_threaded_child.Run();
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-31 13:46:40 -04:00
|
|
|
|
template <typename T>
|
|
|
|
|
T GetDyldFunction(const char* symbol) {
|
|
|
|
|
static void* dl_handle = []() -> void* {
|
|
|
|
|
Dl_info dl_info;
|
|
|
|
|
if (!dladdr(reinterpret_cast<void*>(dlopen), &dl_info)) {
|
|
|
|
|
LOG(ERROR) << "dladdr: failed";
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void* dl_handle =
|
|
|
|
|
dlopen(dl_info.dli_fname, RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD);
|
|
|
|
|
DCHECK(dl_handle) << "dlopen: " << dlerror();
|
|
|
|
|
|
|
|
|
|
return dl_handle;
|
|
|
|
|
}();
|
|
|
|
|
|
|
|
|
|
if (!dl_handle) {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return reinterpret_cast<T>(dlsym(dl_handle, symbol));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VerifyImageExistenceAndTimestamp(const char* path, time_t timestamp) {
|
|
|
|
|
const char* stat_path;
|
|
|
|
|
bool timestamp_may_be_0;
|
|
|
|
|
|
|
|
|
|
#if __MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_16
|
|
|
|
|
static auto _dyld_shared_cache_contains_path =
|
|
|
|
|
GetDyldFunction<bool (*)(const char*)>(
|
|
|
|
|
"_dyld_shared_cache_contains_path");
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#pragma clang diagnostic push
|
|
|
|
|
#pragma clang diagnostic ignored "-Wunguarded-availability"
|
|
|
|
|
if (_dyld_shared_cache_contains_path &&
|
|
|
|
|
_dyld_shared_cache_contains_path(path)) {
|
|
|
|
|
#pragma clang diagnostic pop
|
|
|
|
|
// The timestamp will either match the timestamp of the dyld_shared_cache
|
|
|
|
|
// file in use, or be 0.
|
|
|
|
|
static const char* dyld_shared_cache_file_path = []() -> const char* {
|
|
|
|
|
auto dyld_shared_cache_file_path_f =
|
|
|
|
|
GetDyldFunction<const char* (*)()>("dyld_shared_cache_file_path");
|
|
|
|
|
|
|
|
|
|
// dyld_shared_cache_file_path should always be present if
|
|
|
|
|
// _dyld_shared_cache_contains_path is.
|
|
|
|
|
DCHECK(dyld_shared_cache_file_path_f);
|
|
|
|
|
|
|
|
|
|
const char* dyld_shared_cache_file_path = dyld_shared_cache_file_path_f();
|
|
|
|
|
DCHECK(dyld_shared_cache_file_path);
|
|
|
|
|
|
|
|
|
|
return dyld_shared_cache_file_path;
|
|
|
|
|
}();
|
|
|
|
|
|
|
|
|
|
stat_path = dyld_shared_cache_file_path;
|
|
|
|
|
timestamp_may_be_0 = true;
|
|
|
|
|
} else {
|
|
|
|
|
stat_path = path;
|
|
|
|
|
timestamp_may_be_0 = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct stat stat_buf;
|
|
|
|
|
int rv = stat(stat_path, &stat_buf);
|
|
|
|
|
EXPECT_EQ(rv, 0) << ErrnoMessage("stat");
|
|
|
|
|
if (rv == 0 && (!timestamp_may_be_0 || timestamp != 0)) {
|
|
|
|
|
EXPECT_EQ(timestamp, stat_buf.st_mtime);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-23 16:27:42 -04:00
|
|
|
|
// cl_kernels images (OpenCL kernels) are weird. They’re not ld output and don’t
|
2015-08-05 17:13:11 -04:00
|
|
|
|
// exist as files on disk. On OS X 10.10 and 10.11, their Mach-O structure isn’t
|
2015-03-23 16:27:42 -04:00
|
|
|
|
// perfect. They show up loaded into many executables, so these quirks should be
|
|
|
|
|
// tolerated.
|
|
|
|
|
//
|
|
|
|
|
// Create an object of this class to ensure that at least one cl_kernels image
|
|
|
|
|
// is present in a process, to be able to test that all of the process-reading
|
|
|
|
|
// machinery tolerates them. On systems where cl_kernels modules have known
|
|
|
|
|
// quirks, the image that an object of this class produces will also have those
|
|
|
|
|
// quirks.
|
|
|
|
|
//
|
|
|
|
|
// https://openradar.appspot.com/20239912
|
|
|
|
|
class ScopedOpenCLNoOpKernel {
|
|
|
|
|
public:
|
|
|
|
|
ScopedOpenCLNoOpKernel()
|
2020-09-01 01:19:06 -04:00
|
|
|
|
: context_(nullptr),
|
|
|
|
|
program_(nullptr),
|
|
|
|
|
kernel_(nullptr),
|
|
|
|
|
success_(false) {}
|
2015-03-23 16:27:42 -04:00
|
|
|
|
|
2021-09-20 12:55:12 -07:00
|
|
|
|
ScopedOpenCLNoOpKernel(const ScopedOpenCLNoOpKernel&) = delete;
|
|
|
|
|
ScopedOpenCLNoOpKernel& operator=(const ScopedOpenCLNoOpKernel&) = delete;
|
|
|
|
|
|
2015-03-23 16:27:42 -04:00
|
|
|
|
~ScopedOpenCLNoOpKernel() {
|
|
|
|
|
if (kernel_) {
|
|
|
|
|
cl_int rv = clReleaseKernel(kernel_);
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
EXPECT_EQ(rv, CL_SUCCESS) << "clReleaseKernel";
|
2015-03-23 16:27:42 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (program_) {
|
|
|
|
|
cl_int rv = clReleaseProgram(program_);
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
EXPECT_EQ(rv, CL_SUCCESS) << "clReleaseProgram";
|
2015-03-23 16:27:42 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (context_) {
|
|
|
|
|
cl_int rv = clReleaseContext(context_);
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
EXPECT_EQ(rv, CL_SUCCESS) << "clReleaseContext";
|
2015-03-23 16:27:42 -04:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SetUp() {
|
|
|
|
|
cl_platform_id platform_id;
|
|
|
|
|
cl_int rv = clGetPlatformIDs(1, &platform_id, nullptr);
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
ASSERT_EQ(rv, CL_SUCCESS) << "clGetPlatformIDs";
|
2015-03-23 16:27:42 -04:00
|
|
|
|
|
mac: Switch from <AvailabilityMacros.h> to <Availability.h>
The macOS 11.0 SDK, as of Xcode 12b6 12A8189n, has not updated
<AvailabilityMacros.h> with a MAC_OS_X_VERSION_11_0 or
MAC_OS_X_VERSION_10_16 constant. However, the <Availability.h> interface
has been updated to provide both __MAC_11_0 and __MAC_10_16.
<AvailabilityMacros.h>’s MAC_OS_X_VERSION_MAX_ALLOWED, which is supposed
to identify the SDK version, is broken in the 11.0 SDK in that whenever
the deployment target is set to 10.15 or earlier, the SDK will be
mis-identified through this interface as 10.15. When using the
<Availability.h> equivalent, __MAC_OS_X_VERSION_MAX_ALLOWED, the 11.0
SDK is identified as 10.16 (arguably it should be internally versioned
as 11.0, but at least this interface allows it to be detected
unambiguously.) It’s clear that the <AvailabilityMacros.h> interface
provides no meaningful support for the macOS 11.0 SDK at all, but
<Availability.h> does.
<Availability.h> was introduced in the Mac OS X 10.5 SDK, so there is no
relevant SDK version compatibility problem with this interface.
Key differences between these interfaces for the purposes used by
Crashpad:
- <AvailabilityMacros.h> → <Availability.h>
- MAC_OS_X_VERSION_MIN_REQUIRED (DT) → __MAC_OS_X_VERSION_MIN_REQUIRED
- MAC_OS_X_VERSION_MAX_ALLOWED (SDK) → __MAC_OS_X_VERSION_MAX_ALLOWED
- MAC_OS_X_VERSION_x_y → __MAC_x_y
- <Availability.h> __MAC_OS_X_VERSION_* SDK/DT macros are only
available when targeting macOS, while <AvailabilityMacros.h>
MAC_OS_X_VERSION_* SDK/DT macros are available on all Apple platforms,
which may be a source of confusion. (<Availability.h> __MAC_* macros
do remain available on all Apple platforms.)
This change was made mostly mechanically by:
sed -i '' -Ee 's/<AvailabilityMacros.h>/<Availability.h>/g' \
$(git grep -E -l '<AvailabilityMacros.h>' |
grep -v AvailabilityMacros.h)
sed -i '' -Ee 's/(MAC_OS_X_VERSION_(MIN_REQUIRED|MAX_ALLOWED))/__\1/g' \
$(git grep -E -l 'MAC_OS_X_VERSION_(MIN_REQUIRED|MAX_ALLOWED)' |
grep -v AvailabilityMacros.h)
sed -i '' -Ee 's/(MAC_OS_X_VERSION_(10_[0-9]+))/__MAC_\2/g' \
$(git grep -E -l 'MAC_OS_X_VERSION_(10_[0-9]+)' |
grep -v AvailabilityMacros.h)
Bug: crashpad:347
Change-Id: Ibdcd7a6215a82f7060b7b67d98691f88454085fc
Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/2382421
Reviewed-by: Robert Sesek <rsesek@chromium.org>
Commit-Queue: Mark Mentovai <mark@chromium.org>
2020-08-28 20:00:15 -04:00
|
|
|
|
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_10 && \
|
|
|
|
|
__MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_10
|
|
|
|
|
// cl_device_id is really available in OpenCL.framework back to 10.5, but in
|
|
|
|
|
// the 10.10 SDK and later, OpenCL.framework includes <OpenGL/CGLDevice.h>,
|
|
|
|
|
// which has its own cl_device_id that was introduced in 10.10. That
|
|
|
|
|
// triggers erroneous availability warnings.
|
2017-10-31 14:56:28 -04:00
|
|
|
|
#pragma clang diagnostic push
|
|
|
|
|
#pragma clang diagnostic ignored "-Wunguarded-availability"
|
|
|
|
|
#define DISABLED_WUNGUARDED_AVAILABILITY
|
|
|
|
|
#endif // SDK >= 10.10 && DT < 10.10
|
2015-03-23 16:27:42 -04:00
|
|
|
|
// Use CL_DEVICE_TYPE_CPU to ensure that the kernel would execute on the
|
|
|
|
|
// CPU. This is the only device type that a cl_kernels image will be created
|
|
|
|
|
// for.
|
|
|
|
|
cl_device_id device_id;
|
2017-10-31 14:56:28 -04:00
|
|
|
|
#if defined(DISABLED_WUNGUARDED_AVAILABILITY)
|
|
|
|
|
#pragma clang diagnostic pop
|
|
|
|
|
#undef DISABLED_WUNGUARDED_AVAILABILITY
|
|
|
|
|
#endif // DISABLED_WUNGUARDED_AVAILABILITY
|
2015-03-23 16:27:42 -04:00
|
|
|
|
rv =
|
|
|
|
|
clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_CPU, 1, &device_id, nullptr);
|
2020-09-01 01:19:06 -04:00
|
|
|
|
#if defined(ARCH_CPU_ARM64)
|
|
|
|
|
// CL_DEVICE_TYPE_CPU doesn’t seem to work at all on arm64, meaning that
|
|
|
|
|
// these weird OpenCL modules probably don’t show up there at all. Keep this
|
|
|
|
|
// test even on arm64 in case this ever does start working.
|
|
|
|
|
if (rv == CL_INVALID_VALUE) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
#endif // ARCH_CPU_ARM64
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
ASSERT_EQ(rv, CL_SUCCESS) << "clGetDeviceIDs";
|
2015-03-23 16:27:42 -04:00
|
|
|
|
|
|
|
|
|
context_ = clCreateContext(nullptr, 1, &device_id, nullptr, nullptr, &rv);
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
ASSERT_EQ(rv, CL_SUCCESS) << "clCreateContext";
|
2015-03-23 16:27:42 -04:00
|
|
|
|
|
|
|
|
|
// The goal of the program in |sources| is to produce a cl_kernels image
|
2016-11-07 09:01:20 -05:00
|
|
|
|
// that doesn’t strictly conform to Mach-O expectations. On OS X 10.10,
|
2015-03-23 16:27:42 -04:00
|
|
|
|
// cl_kernels modules show up with an __LD,__compact_unwind section, showing
|
|
|
|
|
// up in the __TEXT segment. MachOImageSegmentReader would normally reject
|
|
|
|
|
// modules for this problem, but a special exception is made when this
|
|
|
|
|
// occurs in cl_kernels images. This portion of the test is aimed at making
|
|
|
|
|
// sure that this exception works correctly.
|
|
|
|
|
//
|
|
|
|
|
// A true no-op program doesn’t actually produce unwind data, so there would
|
|
|
|
|
// be no errant __LD,__compact_unwind section on 10.10, and the test
|
|
|
|
|
// wouldn’t be complete. This simple no-op, which calls a built-in function,
|
|
|
|
|
// does produce unwind data provided optimization is disabled.
|
|
|
|
|
// "-cl-opt-disable" is given to clBuildProgram() below.
|
|
|
|
|
const char* sources[] = {
|
|
|
|
|
"__kernel void NoOp(void) {barrier(CLK_LOCAL_MEM_FENCE);}",
|
|
|
|
|
};
|
|
|
|
|
const size_t source_lengths[] = {
|
|
|
|
|
strlen(sources[0]),
|
|
|
|
|
};
|
2022-02-28 20:57:19 -08:00
|
|
|
|
static_assert(std::size(sources) == std::size(source_lengths),
|
2015-03-23 16:27:42 -04:00
|
|
|
|
"arrays must be parallel");
|
|
|
|
|
|
|
|
|
|
program_ = clCreateProgramWithSource(
|
2022-02-28 20:57:19 -08:00
|
|
|
|
context_, std::size(sources), sources, source_lengths, &rv);
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
ASSERT_EQ(rv, CL_SUCCESS) << "clCreateProgramWithSource";
|
2015-03-23 16:27:42 -04:00
|
|
|
|
|
|
|
|
|
rv = clBuildProgram(
|
|
|
|
|
program_, 1, &device_id, "-cl-opt-disable", nullptr, nullptr);
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
ASSERT_EQ(rv, CL_SUCCESS) << "clBuildProgram";
|
2015-03-23 16:27:42 -04:00
|
|
|
|
|
|
|
|
|
kernel_ = clCreateKernel(program_, "NoOp", &rv);
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
ASSERT_EQ(rv, CL_SUCCESS) << "clCreateKernel";
|
2020-09-01 01:19:06 -04:00
|
|
|
|
|
|
|
|
|
success_ = true;
|
2015-03-23 16:27:42 -04:00
|
|
|
|
}
|
|
|
|
|
|
2020-09-01 01:19:06 -04:00
|
|
|
|
bool success() const { return success_; }
|
|
|
|
|
|
2015-03-23 16:27:42 -04:00
|
|
|
|
private:
|
|
|
|
|
cl_context context_;
|
|
|
|
|
cl_program program_;
|
|
|
|
|
cl_kernel kernel_;
|
2020-09-01 01:19:06 -04:00
|
|
|
|
bool success_;
|
2015-03-23 16:27:42 -04:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Although Mac OS X 10.6 has OpenCL and can compile and execute OpenCL code,
|
|
|
|
|
// OpenCL kernels that run on the CPU do not result in cl_kernels images
|
|
|
|
|
// appearing on that OS version.
|
|
|
|
|
bool ExpectCLKernels() {
|
2020-09-01 17:09:37 -04:00
|
|
|
|
return __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_7 ||
|
|
|
|
|
MacOSVersionNumber() >= 10'07'00;
|
2015-03-23 16:27:42 -04:00
|
|
|
|
}
|
|
|
|
|
|
2018-02-22 12:12:26 -08:00
|
|
|
|
TEST(ProcessReaderMac, SelfModules) {
|
2015-03-23 16:27:42 -04:00
|
|
|
|
ScopedOpenCLNoOpKernel ensure_cl_kernels;
|
|
|
|
|
ASSERT_NO_FATAL_FAILURE(ensure_cl_kernels.SetUp());
|
|
|
|
|
|
2018-02-22 12:12:26 -08:00
|
|
|
|
ProcessReaderMac process_reader;
|
2014-09-05 13:43:51 -04:00
|
|
|
|
ASSERT_TRUE(process_reader.Initialize(mach_task_self()));
|
|
|
|
|
|
|
|
|
|
uint32_t dyld_image_count = _dyld_image_count();
|
2018-02-22 12:12:26 -08:00
|
|
|
|
const std::vector<ProcessReaderMac::Module>& modules =
|
|
|
|
|
process_reader.Modules();
|
2014-09-05 13:43:51 -04:00
|
|
|
|
|
|
|
|
|
// There needs to be at least an entry for the main executable, for a dylib,
|
|
|
|
|
// and for dyld.
|
|
|
|
|
ASSERT_GE(modules.size(), 3u);
|
|
|
|
|
|
|
|
|
|
// dyld_image_count doesn’t include an entry for dyld itself, but |modules|
|
|
|
|
|
// does.
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
ASSERT_EQ(modules.size(), dyld_image_count + 1);
|
2014-09-05 13:43:51 -04:00
|
|
|
|
|
2015-03-23 16:27:42 -04:00
|
|
|
|
bool found_cl_kernels = false;
|
2014-09-05 13:43:51 -04:00
|
|
|
|
for (uint32_t index = 0; index < dyld_image_count; ++index) {
|
|
|
|
|
SCOPED_TRACE(base::StringPrintf(
|
|
|
|
|
"index %u, name %s", index, modules[index].name.c_str()));
|
|
|
|
|
|
|
|
|
|
const char* dyld_image_name = _dyld_get_image_name(index);
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
EXPECT_EQ(modules[index].name, dyld_image_name);
|
2015-03-08 21:02:42 -04:00
|
|
|
|
ASSERT_TRUE(modules[index].reader);
|
2014-09-05 13:43:51 -04:00
|
|
|
|
EXPECT_EQ(
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
modules[index].reader->Address(),
|
2017-04-28 10:08:35 -04:00
|
|
|
|
FromPointerCast<mach_vm_address_t>(_dyld_get_image_header(index)));
|
2014-09-05 13:43:51 -04:00
|
|
|
|
|
2018-07-18 11:16:21 -04:00
|
|
|
|
bool expect_timestamp;
|
2022-08-17 14:25:10 -04:00
|
|
|
|
if (index == 0 && MacOSVersionNumber() < 12'00'00) {
|
|
|
|
|
// Pre-dyld4, dyld didn’t set the main executable's timestamp, and it was
|
|
|
|
|
// reported as 0.
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
EXPECT_EQ(modules[index].timestamp, 0);
|
2018-07-18 11:16:21 -04:00
|
|
|
|
} else if (IsMalformedCLKernelsModule(modules[index].reader->FileType(),
|
|
|
|
|
modules[index].name,
|
|
|
|
|
&expect_timestamp)) {
|
|
|
|
|
// cl_kernels doesn’t exist as a file, but may still have a timestamp.
|
|
|
|
|
if (!expect_timestamp) {
|
|
|
|
|
EXPECT_EQ(modules[index].timestamp, 0);
|
|
|
|
|
} else {
|
|
|
|
|
EXPECT_NE(modules[index].timestamp, 0);
|
|
|
|
|
}
|
2015-03-23 16:27:42 -04:00
|
|
|
|
found_cl_kernels = true;
|
2014-09-05 13:43:51 -04:00
|
|
|
|
} else {
|
|
|
|
|
// Hope that the module didn’t change on disk.
|
2020-08-31 13:46:40 -04:00
|
|
|
|
VerifyImageExistenceAndTimestamp(dyld_image_name,
|
|
|
|
|
modules[index].timestamp);
|
2014-09-05 13:43:51 -04:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-01 01:19:06 -04:00
|
|
|
|
EXPECT_EQ(found_cl_kernels, ExpectCLKernels() && ensure_cl_kernels.success());
|
2015-03-23 16:27:42 -04:00
|
|
|
|
|
2014-09-05 13:43:51 -04:00
|
|
|
|
size_t index = modules.size() - 1;
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
EXPECT_EQ(modules[index].name, kDyldPath);
|
2014-09-05 13:43:51 -04:00
|
|
|
|
|
|
|
|
|
// dyld didn’t load itself either, so it couldn’t record its timestamp, and it
|
|
|
|
|
// is also reported as 0.
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
EXPECT_EQ(modules[index].timestamp, 0);
|
2014-09-05 13:43:51 -04:00
|
|
|
|
|
mac: Handle _dyld_get_all_image_infos() not being available on 10.13
_dyld_get_all_image_infos() was only used in test code in Crashpad.
This addresses two related problems.
When running on 10.13 or later, _dyld_get_all_image_infos() is not
available. It appears to still be implemented in dyld, but its symbol is
now private. This was always known to be an “internal” interface. When
it’s not available, fall back to obtaining the address of the process’
dyld_all_image_infos structure by calling task_info(…, TASK_DYLD_INFO,
…). Note that this is the same thing that the code being tested does,
although the tests are not rendered entirely pointless because the code
being tested consumes dyld_all_image_infos through its own
implementation of an out-of-process reader interface, while the
dyld_all_image_infos data obtained by _dyld_get_all_image_infos() is
handled strictly in-process by ordinary memory reads. This is covered by
bug 187.
When building with the 10.13 SDK, no _dyld_get_all_image_infos symbol is
available to link against. In this case, access the symbol strictly at
runtime via dlopen() if it may be available, or when expecting to only
run on 10.13 and later, don’t even bother looking for this symbol. This
is covered by part of bug 188.
Bug: crashpad:185, crashpad:187, crashpad:188
Change-Id: Ib283e070faf5d1ec35deee420213b53ec24fb1d3
Reviewed-on: https://chromium-review.googlesource.com/534633
Reviewed-by: Robert Sesek <rsesek@chromium.org>
2017-06-14 10:48:30 -04:00
|
|
|
|
const dyld_all_image_infos* dyld_image_infos = DyldGetAllImageInfos();
|
2014-09-05 13:43:51 -04:00
|
|
|
|
if (dyld_image_infos->version >= 2) {
|
2015-03-08 21:02:42 -04:00
|
|
|
|
ASSERT_TRUE(modules[index].reader);
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
EXPECT_EQ(modules[index].reader->Address(),
|
2017-04-28 10:08:35 -04:00
|
|
|
|
FromPointerCast<mach_vm_address_t>(
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
dyld_image_infos->dyldImageLoadAddress));
|
2014-09-05 13:43:51 -04:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class ProcessReaderModulesChild final : public MachMultiprocess {
|
|
|
|
|
public:
|
2020-09-01 01:19:06 -04:00
|
|
|
|
explicit ProcessReaderModulesChild(bool ensure_cl_kernels_success)
|
|
|
|
|
: MachMultiprocess(),
|
|
|
|
|
ensure_cl_kernels_success_(ensure_cl_kernels_success) {}
|
2014-09-05 13:43:51 -04:00
|
|
|
|
|
2021-09-20 12:55:12 -07:00
|
|
|
|
ProcessReaderModulesChild(const ProcessReaderModulesChild&) = delete;
|
|
|
|
|
ProcessReaderModulesChild& operator=(const ProcessReaderModulesChild&) =
|
|
|
|
|
delete;
|
|
|
|
|
|
2014-09-05 13:43:51 -04:00
|
|
|
|
~ProcessReaderModulesChild() {}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
void MachMultiprocessParent() override {
|
2018-02-22 12:12:26 -08:00
|
|
|
|
ProcessReaderMac process_reader;
|
2014-09-05 13:43:51 -04:00
|
|
|
|
ASSERT_TRUE(process_reader.Initialize(ChildTask()));
|
|
|
|
|
|
2018-02-22 12:12:26 -08:00
|
|
|
|
const std::vector<ProcessReaderMac::Module>& modules =
|
2014-09-05 16:35:16 -04:00
|
|
|
|
process_reader.Modules();
|
2014-09-05 13:43:51 -04:00
|
|
|
|
|
|
|
|
|
// There needs to be at least an entry for the main executable, for a dylib,
|
|
|
|
|
// and for dyld.
|
|
|
|
|
ASSERT_GE(modules.size(), 3u);
|
|
|
|
|
|
2015-01-28 14:49:42 -08:00
|
|
|
|
FileHandle read_handle = ReadPipeHandle();
|
2014-09-05 13:43:51 -04:00
|
|
|
|
|
|
|
|
|
uint32_t expect_modules;
|
Make file_io reads more rational and predictable
ReadFile() attempted to continue reading after a short read. In most
cases, this is fine. However, ReadFile() would keep trying to fill a
partially-filled buffer until experiencing a 0-length read(), signaling
end-of-file. For certain weird file descriptors like terminal input, EOF
is an ephemeral condition, and attempting to read beyond EOF doesn’t
actually return 0 (EOF) provided that they remain open, it will block
waiting for more input. Consequently, ReadFile() and anything based on
ReadFile() had an undocumented and quirky interface, which was that any
short read that it returned (not an underlying short read) actually
indicated EOF.
This facet of ReadFile() was unexpected, so it’s being removed. The new
behavior is that ReadFile() will return an underlying short read. The
behavior of FileReaderInterface::Read() is updated in accordance with
this change.
Upon experiencing a short read, the caller can determine the best
action. Most callers were already prepared for this behavior. Outside of
util/file, only crashpad_database_util properly implemented EOF
detection according to previous semantics, and adapting it to new
semantics is trivial.
Callers who require an exact-length read can use the new
ReadFileExactly(), or the newly renamed LoggingReadFileExactly() or
CheckedReadFileExactly(). These functions will retry following a short
read. The renamed functions were previously called LoggingReadFile() and
CheckedReadFile(), but those names implied that they were simply
wrapping ReadFile(), which is not the case. They wrapped ReadFile() and
further, insisted on a full read. Since ReadFile()’s semantics are now
changing but these functions’ are not, they’re now even more distinct
from ReadFile(), and must be renamed to avoid confusion.
Test: *
Change-Id: I06b77e0d6ad8719bd2eb67dab93a8740542dd908
Reviewed-on: https://chromium-review.googlesource.com/456676
Reviewed-by: Robert Sesek <rsesek@chromium.org>
2017-03-16 13:36:38 -04:00
|
|
|
|
CheckedReadFileExactly(
|
|
|
|
|
read_handle, &expect_modules, sizeof(expect_modules));
|
2014-09-05 13:43:51 -04:00
|
|
|
|
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
ASSERT_EQ(modules.size(), expect_modules);
|
2014-09-05 13:43:51 -04:00
|
|
|
|
|
2015-03-23 16:27:42 -04:00
|
|
|
|
bool found_cl_kernels = false;
|
2014-09-05 13:43:51 -04:00
|
|
|
|
for (size_t index = 0; index < modules.size(); ++index) {
|
|
|
|
|
SCOPED_TRACE(base::StringPrintf(
|
|
|
|
|
"index %zu, name %s", index, modules[index].name.c_str()));
|
|
|
|
|
|
|
|
|
|
uint32_t expect_name_length;
|
Make file_io reads more rational and predictable
ReadFile() attempted to continue reading after a short read. In most
cases, this is fine. However, ReadFile() would keep trying to fill a
partially-filled buffer until experiencing a 0-length read(), signaling
end-of-file. For certain weird file descriptors like terminal input, EOF
is an ephemeral condition, and attempting to read beyond EOF doesn’t
actually return 0 (EOF) provided that they remain open, it will block
waiting for more input. Consequently, ReadFile() and anything based on
ReadFile() had an undocumented and quirky interface, which was that any
short read that it returned (not an underlying short read) actually
indicated EOF.
This facet of ReadFile() was unexpected, so it’s being removed. The new
behavior is that ReadFile() will return an underlying short read. The
behavior of FileReaderInterface::Read() is updated in accordance with
this change.
Upon experiencing a short read, the caller can determine the best
action. Most callers were already prepared for this behavior. Outside of
util/file, only crashpad_database_util properly implemented EOF
detection according to previous semantics, and adapting it to new
semantics is trivial.
Callers who require an exact-length read can use the new
ReadFileExactly(), or the newly renamed LoggingReadFileExactly() or
CheckedReadFileExactly(). These functions will retry following a short
read. The renamed functions were previously called LoggingReadFile() and
CheckedReadFile(), but those names implied that they were simply
wrapping ReadFile(), which is not the case. They wrapped ReadFile() and
further, insisted on a full read. Since ReadFile()’s semantics are now
changing but these functions’ are not, they’re now even more distinct
from ReadFile(), and must be renamed to avoid confusion.
Test: *
Change-Id: I06b77e0d6ad8719bd2eb67dab93a8740542dd908
Reviewed-on: https://chromium-review.googlesource.com/456676
Reviewed-by: Robert Sesek <rsesek@chromium.org>
2017-03-16 13:36:38 -04:00
|
|
|
|
CheckedReadFileExactly(
|
2015-01-28 14:49:42 -08:00
|
|
|
|
read_handle, &expect_name_length, sizeof(expect_name_length));
|
2014-09-05 13:43:51 -04:00
|
|
|
|
|
|
|
|
|
// The NUL terminator is not read.
|
|
|
|
|
std::string expect_name(expect_name_length, '\0');
|
Make file_io reads more rational and predictable
ReadFile() attempted to continue reading after a short read. In most
cases, this is fine. However, ReadFile() would keep trying to fill a
partially-filled buffer until experiencing a 0-length read(), signaling
end-of-file. For certain weird file descriptors like terminal input, EOF
is an ephemeral condition, and attempting to read beyond EOF doesn’t
actually return 0 (EOF) provided that they remain open, it will block
waiting for more input. Consequently, ReadFile() and anything based on
ReadFile() had an undocumented and quirky interface, which was that any
short read that it returned (not an underlying short read) actually
indicated EOF.
This facet of ReadFile() was unexpected, so it’s being removed. The new
behavior is that ReadFile() will return an underlying short read. The
behavior of FileReaderInterface::Read() is updated in accordance with
this change.
Upon experiencing a short read, the caller can determine the best
action. Most callers were already prepared for this behavior. Outside of
util/file, only crashpad_database_util properly implemented EOF
detection according to previous semantics, and adapting it to new
semantics is trivial.
Callers who require an exact-length read can use the new
ReadFileExactly(), or the newly renamed LoggingReadFileExactly() or
CheckedReadFileExactly(). These functions will retry following a short
read. The renamed functions were previously called LoggingReadFile() and
CheckedReadFile(), but those names implied that they were simply
wrapping ReadFile(), which is not the case. They wrapped ReadFile() and
further, insisted on a full read. Since ReadFile()’s semantics are now
changing but these functions’ are not, they’re now even more distinct
from ReadFile(), and must be renamed to avoid confusion.
Test: *
Change-Id: I06b77e0d6ad8719bd2eb67dab93a8740542dd908
Reviewed-on: https://chromium-review.googlesource.com/456676
Reviewed-by: Robert Sesek <rsesek@chromium.org>
2017-03-16 13:36:38 -04:00
|
|
|
|
CheckedReadFileExactly(read_handle, &expect_name[0], expect_name_length);
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
EXPECT_EQ(modules[index].name, expect_name);
|
2014-09-05 13:43:51 -04:00
|
|
|
|
|
|
|
|
|
mach_vm_address_t expect_address;
|
Make file_io reads more rational and predictable
ReadFile() attempted to continue reading after a short read. In most
cases, this is fine. However, ReadFile() would keep trying to fill a
partially-filled buffer until experiencing a 0-length read(), signaling
end-of-file. For certain weird file descriptors like terminal input, EOF
is an ephemeral condition, and attempting to read beyond EOF doesn’t
actually return 0 (EOF) provided that they remain open, it will block
waiting for more input. Consequently, ReadFile() and anything based on
ReadFile() had an undocumented and quirky interface, which was that any
short read that it returned (not an underlying short read) actually
indicated EOF.
This facet of ReadFile() was unexpected, so it’s being removed. The new
behavior is that ReadFile() will return an underlying short read. The
behavior of FileReaderInterface::Read() is updated in accordance with
this change.
Upon experiencing a short read, the caller can determine the best
action. Most callers were already prepared for this behavior. Outside of
util/file, only crashpad_database_util properly implemented EOF
detection according to previous semantics, and adapting it to new
semantics is trivial.
Callers who require an exact-length read can use the new
ReadFileExactly(), or the newly renamed LoggingReadFileExactly() or
CheckedReadFileExactly(). These functions will retry following a short
read. The renamed functions were previously called LoggingReadFile() and
CheckedReadFile(), but those names implied that they were simply
wrapping ReadFile(), which is not the case. They wrapped ReadFile() and
further, insisted on a full read. Since ReadFile()’s semantics are now
changing but these functions’ are not, they’re now even more distinct
from ReadFile(), and must be renamed to avoid confusion.
Test: *
Change-Id: I06b77e0d6ad8719bd2eb67dab93a8740542dd908
Reviewed-on: https://chromium-review.googlesource.com/456676
Reviewed-by: Robert Sesek <rsesek@chromium.org>
2017-03-16 13:36:38 -04:00
|
|
|
|
CheckedReadFileExactly(
|
|
|
|
|
read_handle, &expect_address, sizeof(expect_address));
|
2015-03-08 21:02:42 -04:00
|
|
|
|
ASSERT_TRUE(modules[index].reader);
|
test: Use (actual, [un]expected) in gtest {ASSERT,EXPECT}_{EQ,NE}
gtest used to require (expected, actual) ordering for arguments to
EXPECT_EQ and ASSERT_EQ, and in failed test assertions would identify
each side as “expected” or “actual.” Tests in Crashpad adhered to this
traditional ordering. After a gtest change in February 2016, it is now
agnostic with respect to the order of these arguments.
This change mechanically updates all uses of these macros to (actual,
expected) by reversing them. This provides consistency with our use of
the logging CHECK_EQ and DCHECK_EQ macros, and makes for better
readability by ordinary native speakers. The rough (but working!)
conversion tool is
https://chromium-review.googlesource.com/c/466727/1/rewrite_expectassert_eq.py,
and “git cl format” cleaned up its output.
EXPECT_NE and ASSERT_NE never had a preferred ordering. gtest never made
a judgment that one side or the other needed to provide an “unexpected”
value. Consequently, some code used (unexpected, actual) while other
code used (actual, unexpected). For consistency with the new EXPECT_EQ
and ASSERT_EQ usage, as well as consistency with CHECK_NE and DCHECK_NE,
this change also updates these use sites to (actual, unexpected) where
one side can be called “unexpected” as, for example, std::string::npos
can be. Unfortunately, this portion was a manual conversion.
References:
https://github.com/google/googletest/blob/master/googletest/docs/Primer.md#binary-comparison
https://github.com/google/googletest/commit/77d6b173380332b1c1bc540532641f410ec82d65
https://github.com/google/googletest/pull/713
Change-Id: I978fef7c94183b8b1ef63f12f5ab4d6693626be3
Reviewed-on: https://chromium-review.googlesource.com/466727
Reviewed-by: Scott Graham <scottmg@chromium.org>
2017-04-04 00:35:21 -04:00
|
|
|
|
EXPECT_EQ(modules[index].reader->Address(), expect_address);
|
2014-09-05 13:43:51 -04:00
|
|
|
|
|
2018-07-18 11:16:21 -04:00
|
|
|
|
bool expect_timestamp;
|
2022-08-18 17:51:05 -04:00
|
|
|
|
if ((index == 0 && MacOSVersionNumber() < 12'00'00) ||
|
|
|
|
|
index == modules.size() - 1) {
|
|
|
|
|
// Pre-dyld4, dyld didn’t set the main executable's timestamp, and it
|
|
|
|
|
// was reported as 0.
|
|
|
|
|
// The last module is dyld.
|
|
|
|
|
EXPECT_EQ(modules[index].timestamp, 0);
|
|
|
|
|
} else if (IsMalformedCLKernelsModule(modules[index].reader->FileType(),
|
|
|
|
|
modules[index].name,
|
|
|
|
|
&expect_timestamp)) {
|
2018-07-18 11:16:21 -04:00
|
|
|
|
// cl_kernels doesn’t exist as a file, but may still have a timestamp.
|
|
|
|
|
if (!expect_timestamp) {
|
|
|
|
|
EXPECT_EQ(modules[index].timestamp, 0);
|
|
|
|
|
} else {
|
|
|
|
|
EXPECT_NE(modules[index].timestamp, 0);
|
|
|
|
|
}
|
2015-03-23 16:27:42 -04:00
|
|
|
|
found_cl_kernels = true;
|
2014-09-05 13:43:51 -04:00
|
|
|
|
} else {
|
|
|
|
|
// Hope that the module didn’t change on disk.
|
2020-08-31 13:46:40 -04:00
|
|
|
|
VerifyImageExistenceAndTimestamp(expect_name.c_str(),
|
|
|
|
|
modules[index].timestamp);
|
2014-09-05 13:43:51 -04:00
|
|
|
|
}
|
|
|
|
|
}
|
2015-03-23 16:27:42 -04:00
|
|
|
|
|
2020-09-01 01:19:06 -04:00
|
|
|
|
EXPECT_EQ(found_cl_kernels,
|
|
|
|
|
ExpectCLKernels() && ensure_cl_kernels_success_);
|
2014-09-05 13:43:51 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MachMultiprocessChild() override {
|
2015-01-28 14:49:42 -08:00
|
|
|
|
FileHandle write_handle = WritePipeHandle();
|
2014-09-05 13:43:51 -04:00
|
|
|
|
|
|
|
|
|
uint32_t dyld_image_count = _dyld_image_count();
|
mac: Handle _dyld_get_all_image_infos() not being available on 10.13
_dyld_get_all_image_infos() was only used in test code in Crashpad.
This addresses two related problems.
When running on 10.13 or later, _dyld_get_all_image_infos() is not
available. It appears to still be implemented in dyld, but its symbol is
now private. This was always known to be an “internal” interface. When
it’s not available, fall back to obtaining the address of the process’
dyld_all_image_infos structure by calling task_info(…, TASK_DYLD_INFO,
…). Note that this is the same thing that the code being tested does,
although the tests are not rendered entirely pointless because the code
being tested consumes dyld_all_image_infos through its own
implementation of an out-of-process reader interface, while the
dyld_all_image_infos data obtained by _dyld_get_all_image_infos() is
handled strictly in-process by ordinary memory reads. This is covered by
bug 187.
When building with the 10.13 SDK, no _dyld_get_all_image_infos symbol is
available to link against. In this case, access the symbol strictly at
runtime via dlopen() if it may be available, or when expecting to only
run on 10.13 and later, don’t even bother looking for this symbol. This
is covered by part of bug 188.
Bug: crashpad:185, crashpad:187, crashpad:188
Change-Id: Ib283e070faf5d1ec35deee420213b53ec24fb1d3
Reviewed-on: https://chromium-review.googlesource.com/534633
Reviewed-by: Robert Sesek <rsesek@chromium.org>
2017-06-14 10:48:30 -04:00
|
|
|
|
const dyld_all_image_infos* dyld_image_infos = DyldGetAllImageInfos();
|
2014-09-05 13:43:51 -04:00
|
|
|
|
|
|
|
|
|
uint32_t write_image_count = dyld_image_count;
|
|
|
|
|
if (dyld_image_infos->version >= 2) {
|
|
|
|
|
// dyld_image_count doesn’t include an entry for dyld itself, but one will
|
|
|
|
|
// be written.
|
|
|
|
|
++write_image_count;
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-28 14:49:42 -08:00
|
|
|
|
CheckedWriteFile(
|
|
|
|
|
write_handle, &write_image_count, sizeof(write_image_count));
|
2014-09-05 13:43:51 -04:00
|
|
|
|
|
|
|
|
|
for (size_t index = 0; index < write_image_count; ++index) {
|
|
|
|
|
const char* dyld_image_name;
|
|
|
|
|
mach_vm_address_t dyld_image_address;
|
|
|
|
|
|
|
|
|
|
if (index < dyld_image_count) {
|
|
|
|
|
dyld_image_name = _dyld_get_image_name(index);
|
|
|
|
|
dyld_image_address =
|
2017-04-28 10:08:35 -04:00
|
|
|
|
FromPointerCast<mach_vm_address_t>(_dyld_get_image_header(index));
|
2014-09-05 13:43:51 -04:00
|
|
|
|
} else {
|
2016-06-17 22:03:01 -04:00
|
|
|
|
dyld_image_name = kDyldPath;
|
2017-04-28 10:08:35 -04:00
|
|
|
|
dyld_image_address = FromPointerCast<mach_vm_address_t>(
|
2014-09-05 13:43:51 -04:00
|
|
|
|
dyld_image_infos->dyldImageLoadAddress);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t dyld_image_name_length = strlen(dyld_image_name);
|
2015-01-28 14:49:42 -08:00
|
|
|
|
CheckedWriteFile(write_handle,
|
|
|
|
|
&dyld_image_name_length,
|
|
|
|
|
sizeof(dyld_image_name_length));
|
2014-09-05 13:43:51 -04:00
|
|
|
|
|
|
|
|
|
// The NUL terminator is not written.
|
2015-01-28 14:49:42 -08:00
|
|
|
|
CheckedWriteFile(write_handle, dyld_image_name, dyld_image_name_length);
|
2014-09-05 13:43:51 -04:00
|
|
|
|
|
2014-12-17 14:35:18 -08:00
|
|
|
|
CheckedWriteFile(
|
2015-01-28 14:49:42 -08:00
|
|
|
|
write_handle, &dyld_image_address, sizeof(dyld_image_address));
|
2014-09-05 13:43:51 -04:00
|
|
|
|
}
|
|
|
|
|
|
2014-09-18 15:03:49 -04:00
|
|
|
|
// Wait for the parent to signal that it’s OK to exit by closing its end of
|
|
|
|
|
// the pipe.
|
2015-01-28 14:49:42 -08:00
|
|
|
|
CheckedReadFileAtEOF(ReadPipeHandle());
|
2014-09-05 13:43:51 -04:00
|
|
|
|
}
|
|
|
|
|
|
2020-09-01 01:19:06 -04:00
|
|
|
|
bool ensure_cl_kernels_success_;
|
2014-09-05 13:43:51 -04:00
|
|
|
|
};
|
|
|
|
|
|
2018-02-22 12:12:26 -08:00
|
|
|
|
TEST(ProcessReaderMac, ChildModules) {
|
2015-03-23 16:27:42 -04:00
|
|
|
|
ScopedOpenCLNoOpKernel ensure_cl_kernels;
|
|
|
|
|
ASSERT_NO_FATAL_FAILURE(ensure_cl_kernels.SetUp());
|
|
|
|
|
|
2020-09-01 01:19:06 -04:00
|
|
|
|
ProcessReaderModulesChild process_reader_modules_child(
|
|
|
|
|
ensure_cl_kernels.success());
|
2014-09-05 13:43:51 -04:00
|
|
|
|
process_reader_modules_child.Run();
|
|
|
|
|
}
|
|
|
|
|
|
2014-08-25 17:51:09 -04:00
|
|
|
|
} // namespace
|
2014-10-07 17:28:50 -04:00
|
|
|
|
} // namespace test
|
|
|
|
|
} // namespace crashpad
|