mirror of
https://github.com/chromium/crashpad.git
synced 2024-12-30 01:06:56 +08:00
161bfed35a
If the file just needs the CHECK/CHECK_OP/NOTREACHED macros, use the appropriate header for that instead. Or if logging.h is not needed at all, remove it. This is both a nice cleanup (logging.h is a big header, and including it unnecessarily has compile-time costs), and part of the final step towards making logging.h no longer include check.h and the others. Bug: chromium:1031540 Change-Id: Ia46806bd95fe498bcf3cf6d2c13ffa4081678043 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/2255361 Reviewed-by: Mark Mentovai <mark@chromium.org> Commit-Queue: Hans Wennborg <hans@chromium.org>
162 lines
3.9 KiB
C++
162 lines
3.9 KiB
C++
// Copyright 2019 The Crashpad Authors. All rights reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#include "util/linux/proc_task_reader.h"
|
|
|
|
#include "base/macros.h"
|
|
#include "base/strings/stringprintf.h"
|
|
#include "gtest/gtest.h"
|
|
#include "test/multiprocess_exec.h"
|
|
#include "third_party/lss/lss.h"
|
|
#include "util/synchronization/semaphore.h"
|
|
#include "util/thread/thread.h"
|
|
|
|
namespace crashpad {
|
|
namespace test {
|
|
namespace {
|
|
|
|
bool FindThreadID(pid_t tid, const std::vector<pid_t>& threads) {
|
|
for (const auto& thread : threads) {
|
|
if (thread == tid) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
class ScopedBlockingThread : public Thread {
|
|
public:
|
|
ScopedBlockingThread() : tid_sem_(0), join_sem_(0), tid_(-1) {}
|
|
|
|
~ScopedBlockingThread() {
|
|
join_sem_.Signal();
|
|
Join();
|
|
}
|
|
|
|
pid_t ThreadID() {
|
|
tid_sem_.Wait();
|
|
return tid_;
|
|
}
|
|
|
|
private:
|
|
void ThreadMain() override {
|
|
tid_ = sys_gettid();
|
|
tid_sem_.Signal();
|
|
join_sem_.Wait();
|
|
}
|
|
|
|
Semaphore tid_sem_;
|
|
Semaphore join_sem_;
|
|
pid_t tid_;
|
|
};
|
|
|
|
TEST(ProcTaskReader, Self) {
|
|
std::vector<pid_t> tids;
|
|
ASSERT_TRUE(ReadThreadIDs(getpid(), &tids));
|
|
EXPECT_TRUE(FindThreadID(getpid(), tids));
|
|
EXPECT_TRUE(FindThreadID(sys_gettid(), tids));
|
|
|
|
ScopedBlockingThread thread1;
|
|
thread1.Start();
|
|
|
|
ScopedBlockingThread thread2;
|
|
thread2.Start();
|
|
|
|
pid_t thread1_tid = thread1.ThreadID();
|
|
pid_t thread2_tid = thread2.ThreadID();
|
|
|
|
tids.clear();
|
|
ASSERT_TRUE(ReadThreadIDs(getpid(), &tids));
|
|
EXPECT_TRUE(FindThreadID(getpid(), tids));
|
|
EXPECT_TRUE(FindThreadID(thread1_tid, tids));
|
|
EXPECT_TRUE(FindThreadID(thread2_tid, tids));
|
|
}
|
|
|
|
TEST(ProcTaskReader, BadPID) {
|
|
std::vector<pid_t> tids;
|
|
EXPECT_FALSE(ReadThreadIDs(-1, &tids));
|
|
|
|
tids.clear();
|
|
EXPECT_FALSE(ReadThreadIDs(0, &tids));
|
|
}
|
|
|
|
CRASHPAD_CHILD_TEST_MAIN(ProcTaskTestChild) {
|
|
FileHandle in = StdioFileHandle(StdioStream::kStandardInput);
|
|
FileHandle out = StdioFileHandle(StdioStream::kStandardOutput);
|
|
|
|
pid_t tid = getpid();
|
|
CheckedWriteFile(out, &tid, sizeof(tid));
|
|
|
|
tid = sys_gettid();
|
|
CheckedWriteFile(out, &tid, sizeof(tid));
|
|
|
|
ScopedBlockingThread thread1;
|
|
thread1.Start();
|
|
|
|
ScopedBlockingThread thread2;
|
|
thread2.Start();
|
|
|
|
tid = thread1.ThreadID();
|
|
CheckedWriteFile(out, &tid, sizeof(tid));
|
|
|
|
tid = thread2.ThreadID();
|
|
CheckedWriteFile(out, &tid, sizeof(tid));
|
|
|
|
CheckedReadFileAtEOF(in);
|
|
return 0;
|
|
}
|
|
|
|
class ProcTaskTest : public MultiprocessExec {
|
|
public:
|
|
ProcTaskTest() : MultiprocessExec() {
|
|
SetChildTestMainFunction("ProcTaskTestChild");
|
|
}
|
|
|
|
private:
|
|
bool ReadIDFromChild(std::vector<pid_t>* threads) {
|
|
pid_t tid;
|
|
if (!LoggingReadFileExactly(ReadPipeHandle(), &tid, sizeof(tid))) {
|
|
return false;
|
|
}
|
|
threads->push_back(tid);
|
|
return true;
|
|
}
|
|
|
|
void MultiprocessParent() override {
|
|
std::vector<pid_t> ids_to_find;
|
|
for (size_t id_count = 0; id_count < 4; ++id_count) {
|
|
ASSERT_TRUE(ReadIDFromChild(&ids_to_find));
|
|
}
|
|
|
|
std::vector<pid_t> threads;
|
|
ASSERT_TRUE(ReadThreadIDs(ChildPID(), &threads));
|
|
for (size_t index = 0; index < ids_to_find.size(); ++index) {
|
|
SCOPED_TRACE(
|
|
base::StringPrintf("index %zd, tid %d", index, ids_to_find[index]));
|
|
EXPECT_TRUE(FindThreadID(ids_to_find[index], threads));
|
|
}
|
|
}
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(ProcTaskTest);
|
|
};
|
|
|
|
TEST(ProcTaskReader, ReadChild) {
|
|
ProcTaskTest test;
|
|
test.Run();
|
|
}
|
|
|
|
} // namespace
|
|
} // namespace test
|
|
} // namespace crashpad
|