31 #include "gtest/internal/gtest-port.h"
43 # include <sys/stat.h>
50 #endif // GTEST_OS_WINDOWS
53 # include <mach/mach_init.h>
54 # include <mach/task.h>
55 # include <mach/vm_map.h>
56 #endif // GTEST_OS_MAC
58 #if GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD || \
59 GTEST_OS_NETBSD || GTEST_OS_OPENBSD
60 # include <sys/sysctl.h>
61 # if GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD
62 # include <sys/user.h>
69 # include <sys/procfs.h>
70 #endif // GTEST_OS_QNX
73 # include <procinfo.h>
74 # include <sys/types.h>
75 #endif // GTEST_OS_AIX
78 # include <zircon/process.h>
79 # include <zircon/syscalls.h>
80 #endif // GTEST_OS_FUCHSIA
82 #include "gtest/gtest-spi.h"
83 #include "gtest/gtest-message.h"
84 #include "gtest/internal/gtest-internal.h"
85 #include "gtest/internal/gtest-string.h"
86 #include "src/gtest-internal-inl.h"
91 #if defined(_MSC_VER) || defined(__BORLANDC__)
103 template <
typename T>
107 while (
field-- > 0) {
120 return ReadProcFileField<size_t>(
filename, 19);
126 const task_t task = mach_task_self();
127 mach_msg_type_number_t thread_count;
128 thread_act_array_t thread_list;
129 const kern_return_t
status = task_threads(task, &thread_list, &thread_count);
130 if (
status == KERN_SUCCESS) {
134 reinterpret_cast<vm_address_t
>(thread_list),
135 sizeof(thread_t) * thread_count);
136 return static_cast<size_t>(thread_count);
142 #elif GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD || \
147 #define KERN_PROC KERN_PROC2
148 #define kinfo_proc kinfo_proc2
151 #if GTEST_OS_DRAGONFLY
152 #define KP_NLWP(kp) (kp.kp_nthreads)
153 #elif GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD
154 #define KP_NLWP(kp) (kp.ki_numthreads)
155 #elif GTEST_OS_NETBSD
156 #define KP_NLWP(kp) (kp.p_nlwps)
168 sizeof(
struct kinfo_proc),
172 u_int miblen =
sizeof(mib) /
sizeof(mib[0]);
173 struct kinfo_proc info;
174 size_t size =
sizeof(info);
175 if (sysctl(mib, miblen, &info, &
size, NULL, 0)) {
178 return static_cast<size_t>(KP_NLWP(info));
180 #elif GTEST_OS_OPENBSD
188 KERN_PROC_PID | KERN_PROC_SHOW_THREADS,
190 sizeof(
struct kinfo_proc),
193 u_int miblen =
sizeof(mib) /
sizeof(mib[0]);
197 if (sysctl(mib, miblen, NULL, &
size, NULL, 0)) {
200 mib[5] =
size / mib[4];
203 struct kinfo_proc info[mib[5]];
204 if (sysctl(mib, miblen, &info, &
size, NULL, 0)) {
210 for (
int i = 0;
i <
size / mib[4];
i++) {
211 if (info[
i].p_tid != -1)
222 const int fd =
open(
"/proc/self/as", O_RDONLY);
226 procfs_info process_info;
228 devctl(fd, DCMD_PROC_INFO, &process_info,
sizeof(process_info),
nullptr);
231 return static_cast<size_t>(process_info.num_threads);
240 struct procentry64 entry;
241 pid_t pid = getpid();
242 int status = getprocs64(&entry,
sizeof(entry),
nullptr, 0, &pid, 1);
244 return entry.pi_thcount;
250 #elif GTEST_OS_FUCHSIA
255 zx_status_t
status = zx_object_get_info(
257 ZX_INFO_PROCESS_THREADS,
277 #endif // GTEST_OS_LINUX
279 #if GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS
281 void SleepMilliseconds(
int n) {
282 ::Sleep(
static_cast<DWORD
>(
n));
285 AutoHandle::AutoHandle()
288 AutoHandle::AutoHandle(Handle
handle)
291 AutoHandle::~AutoHandle() {
312 <<
"Resetting a valid handle to itself is likely a programmer error "
313 "and thus not allowed.";
317 bool AutoHandle::IsCloseable()
const {
323 Notification::Notification()
324 : event_(::CreateEvent(nullptr,
331 void Notification::Notify() {
335 void Notification::WaitForNotification() {
337 ::WaitForSingleObject(event_.Get(), INFINITE) == WAIT_OBJECT_0);
341 : owner_thread_id_(0),
343 critical_section_init_phase_(0),
344 critical_section_(
new CRITICAL_SECTION) {
345 ::InitializeCriticalSection(critical_section_);
351 if (
type_ == kDynamic) {
352 ::DeleteCriticalSection(critical_section_);
353 delete critical_section_;
354 critical_section_ =
nullptr;
359 ThreadSafeLazyInit();
360 ::EnterCriticalSection(critical_section_);
361 owner_thread_id_ = ::GetCurrentThreadId();
364 void Mutex::Unlock() {
365 ThreadSafeLazyInit();
369 owner_thread_id_ = 0;
370 ::LeaveCriticalSection(critical_section_);
375 void Mutex::AssertHeld() {
376 ThreadSafeLazyInit();
377 GTEST_CHECK_(owner_thread_id_ == ::GetCurrentThreadId())
378 <<
"The current thread is not holding the mutex @" <<
this;
392 class MemoryIsNotDeallocated
395 MemoryIsNotDeallocated() : old_crtdbg_flag_(0) {
396 old_crtdbg_flag_ = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
399 _CrtSetDbgFlag(old_crtdbg_flag_ & ~_CRTDBG_ALLOC_MEM_DF);
402 ~MemoryIsNotDeallocated() {
404 _CrtSetDbgFlag(old_crtdbg_flag_);
408 int old_crtdbg_flag_;
417 void Mutex::ThreadSafeLazyInit() {
419 if (
type_ == kStatic) {
421 ::InterlockedCompareExchange(&critical_section_init_phase_, 1L, 0L)) {
425 owner_thread_id_ = 0;
429 MemoryIsNotDeallocated memory_is_not_deallocated;
431 critical_section_ =
new CRITICAL_SECTION;
433 ::InitializeCriticalSection(critical_section_);
437 &critical_section_init_phase_, 2L, 1L) ==
443 while (::InterlockedCompareExchange(&critical_section_init_phase_,
457 <<
"Unexpected value of critical_section_init_phase_ "
458 <<
"while initializing a static mutex.";
465 class ThreadWithParamSupport :
public ThreadWithParamBase {
467 static HANDLE CreateThread(Runnable* runnable,
468 Notification* thread_can_start) {
469 ThreadMainParam* param =
new ThreadMainParam(runnable, thread_can_start);
471 HANDLE thread_handle = ::CreateThread(
474 &ThreadWithParamSupport::ThreadMain,
479 <<
"CreateThread failed with error " << ::GetLastError() <<
".";
480 if (thread_handle ==
nullptr) {
483 return thread_handle;
487 struct ThreadMainParam {
488 ThreadMainParam(Runnable* runnable, Notification* thread_can_start)
489 : runnable_(runnable),
490 thread_can_start_(thread_can_start) {
492 std::unique_ptr<Runnable> runnable_;
494 Notification* thread_can_start_;
497 static DWORD WINAPI ThreadMain(
void*
ptr) {
499 std::unique_ptr<ThreadMainParam> param(
static_cast<ThreadMainParam*
>(
ptr));
500 if (param->thread_can_start_ !=
nullptr)
501 param->thread_can_start_->WaitForNotification();
502 param->runnable_->Run();
507 ThreadWithParamSupport();
514 ThreadWithParamBase::ThreadWithParamBase(Runnable *runnable,
515 Notification* thread_can_start)
516 :
thread_(ThreadWithParamSupport::CreateThread(runnable,
520 ThreadWithParamBase::~ThreadWithParamBase() {
526 <<
"Failed to join the thread with error " << ::GetLastError() <<
".";
533 class ThreadLocalRegistryImpl {
537 static ThreadLocalValueHolderBase* GetValueOnCurrentThread(
538 const ThreadLocalBase* thread_local_instance) {
539 DWORD current_thread = ::GetCurrentThreadId();
541 ThreadIdToThreadLocals*
const thread_to_thread_locals =
542 GetThreadLocalsMapLocked();
544 thread_to_thread_locals->find(current_thread);
545 if (thread_local_pos == thread_to_thread_locals->end()) {
546 thread_local_pos = thread_to_thread_locals->insert(
547 std::make_pair(current_thread, ThreadLocalValues())).first;
548 StartWatcherThreadFor(current_thread);
550 ThreadLocalValues& thread_local_values = thread_local_pos->second;
552 thread_local_values.find(thread_local_instance);
553 if (value_pos == thread_local_values.end()) {
556 .insert(std::make_pair(
557 thread_local_instance,
558 std::shared_ptr<ThreadLocalValueHolderBase>(
559 thread_local_instance->NewValueForCurrentThread())))
562 return value_pos->second.get();
565 static void OnThreadLocalDestroyed(
566 const ThreadLocalBase* thread_local_instance) {
567 std::vector<std::shared_ptr<ThreadLocalValueHolderBase> > value_holders;
572 ThreadIdToThreadLocals*
const thread_to_thread_locals =
573 GetThreadLocalsMapLocked();
575 thread_to_thread_locals->begin();
576 it != thread_to_thread_locals->end();
578 ThreadLocalValues& thread_local_values =
it->second;
580 thread_local_values.find(thread_local_instance);
581 if (value_pos != thread_local_values.end()) {
582 value_holders.push_back(value_pos->second);
583 thread_local_values.erase(value_pos);
593 static void OnThreadExit(DWORD
thread_id) {
595 std::vector<std::shared_ptr<ThreadLocalValueHolderBase> > value_holders;
600 ThreadIdToThreadLocals*
const thread_to_thread_locals =
601 GetThreadLocalsMapLocked();
603 thread_to_thread_locals->find(
thread_id);
604 if (thread_local_pos != thread_to_thread_locals->end()) {
605 ThreadLocalValues& thread_local_values = thread_local_pos->second;
607 thread_local_values.begin();
608 value_pos != thread_local_values.end();
610 value_holders.push_back(value_pos->second);
612 thread_to_thread_locals->erase(thread_local_pos);
621 typedef std::map<
const ThreadLocalBase*,
622 std::shared_ptr<ThreadLocalValueHolderBase> >
626 typedef std::map<DWORD, ThreadLocalValues> ThreadIdToThreadLocals;
630 typedef std::pair<DWORD, HANDLE> ThreadIdAndHandle;
632 static void StartWatcherThreadFor(DWORD
thread_id) {
635 HANDLE
thread = ::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION,
641 DWORD watcher_thread_id;
642 HANDLE watcher_thread = ::CreateThread(
645 &ThreadLocalRegistryImpl::WatcherThreadFunc,
647 CREATE_SUSPENDED, &watcher_thread_id);
651 ::SetThreadPriority(watcher_thread,
652 ::GetThreadPriority(::GetCurrentThread()));
653 ::ResumeThread(watcher_thread);
654 ::CloseHandle(watcher_thread);
659 static DWORD WINAPI WatcherThreadFunc(LPVOID param) {
660 const ThreadIdAndHandle* tah =
661 reinterpret_cast<const ThreadIdAndHandle*
>(param);
663 ::WaitForSingleObject(tah->second, INFINITE) == WAIT_OBJECT_0);
664 OnThreadExit(tah->first);
665 ::CloseHandle(tah->second);
671 static ThreadIdToThreadLocals* GetThreadLocalsMapLocked() {
674 MemoryIsNotDeallocated memory_is_not_deallocated;
676 static ThreadIdToThreadLocals*
map =
new ThreadIdToThreadLocals();
683 static Mutex thread_map_mutex_;
687 Mutex ThreadLocalRegistryImpl::thread_map_mutex_(Mutex::kStaticMutex);
689 ThreadLocalValueHolderBase* ThreadLocalRegistry::GetValueOnCurrentThread(
690 const ThreadLocalBase* thread_local_instance) {
691 return ThreadLocalRegistryImpl::GetValueOnCurrentThread(
692 thread_local_instance);
695 void ThreadLocalRegistry::OnThreadLocalDestroyed(
696 const ThreadLocalBase* thread_local_instance) {
697 ThreadLocalRegistryImpl::OnThreadLocalDestroyed(thread_local_instance);
700 #endif // GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS
702 #if GTEST_USES_POSIX_RE
712 regfree(&partial_regex_);
713 regfree(&full_regex_);
715 free(
const_cast<char*
>(pattern_));
719 bool RE::FullMatch(
const char*
str,
const RE& re) {
720 if (!re.is_valid_)
return false;
723 return regexec(&re.full_regex_,
str, 1, &
match, 0) == 0;
728 bool RE::PartialMatch(
const char*
str,
const RE& re) {
729 if (!re.is_valid_)
return false;
732 return regexec(&re.partial_regex_,
str, 1, &
match, 0) == 0;
741 const size_t full_regex_len = strlen(regex) + 10;
742 char*
const full_pattern =
new char[full_regex_len];
744 snprintf(full_pattern, full_regex_len,
"^(%s)$", regex);
745 is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0;
755 const char*
const partial_regex = (*regex ==
'\0') ?
"()" : regex;
756 is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0;
759 <<
"Regular expression \"" << regex
760 <<
"\" is not a valid POSIX Extended regular expression.";
762 delete[] full_pattern;
765 #elif GTEST_USES_SIMPLE_RE
769 bool IsInSet(
char ch,
const char*
str) {
770 return ch !=
'\0' && strchr(
str,
ch) !=
nullptr;
776 bool IsAsciiDigit(
char ch) {
return '0' <=
ch &&
ch <=
'9'; }
777 bool IsAsciiPunct(
char ch) {
778 return IsInSet(
ch,
"^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~");
780 bool IsRepeat(
char ch) {
return IsInSet(
ch,
"?*+"); }
781 bool IsAsciiWhiteSpace(
char ch) {
return IsInSet(
ch,
" \f\n\r\t\v"); }
782 bool IsAsciiWordChar(
char ch) {
783 return (
'a' <=
ch &&
ch <=
'z') || (
'A' <=
ch &&
ch <=
'Z') ||
784 (
'0' <=
ch &&
ch <=
'9') ||
ch ==
'_';
788 bool IsValidEscape(
char c) {
789 return (IsAsciiPunct(c) || IsInSet(c,
"dDfnrsStvwW"));
794 bool AtomMatchesChar(
bool escaped,
char pattern_char,
char ch) {
796 switch (pattern_char) {
797 case 'd':
return IsAsciiDigit(
ch);
798 case 'D':
return !IsAsciiDigit(
ch);
799 case 'f':
return ch ==
'\f';
800 case 'n':
return ch ==
'\n';
801 case 'r':
return ch ==
'\r';
802 case 's':
return IsAsciiWhiteSpace(
ch);
803 case 'S':
return !IsAsciiWhiteSpace(
ch);
804 case 't':
return ch ==
'\t';
805 case 'v':
return ch ==
'\v';
806 case 'w':
return IsAsciiWordChar(
ch);
807 case 'W':
return !IsAsciiWordChar(
ch);
809 return IsAsciiPunct(pattern_char) && pattern_char ==
ch;
812 return (pattern_char ==
'.' &&
ch !=
'\n') || pattern_char ==
ch;
818 <<
" in simple regular expression \"" << regex <<
"\": ").GetString();
823 bool ValidateRegex(
const char* regex) {
824 if (regex ==
nullptr) {
825 ADD_FAILURE() <<
"NULL is not a valid simple regular expression.";
829 bool is_valid =
true;
832 bool prev_repeatable =
false;
833 for (
int i = 0; regex[
i];
i++) {
834 if (regex[i] ==
'\\') {
836 if (regex[i] ==
'\0') {
837 ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
838 <<
"'\\' cannot appear at the end.";
842 if (!IsValidEscape(regex[i])) {
843 ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
844 <<
"invalid escape sequence \"\\" << regex[
i] <<
"\".";
847 prev_repeatable =
true;
849 const char ch = regex[
i];
851 if (
ch ==
'^' && i > 0) {
853 <<
"'^' can only appear at the beginning.";
855 }
else if (
ch ==
'$' && regex[i + 1] !=
'\0') {
857 <<
"'$' can only appear at the end.";
859 }
else if (IsInSet(
ch,
"()[]{}|")) {
861 <<
"'" <<
ch <<
"' is unsupported.";
863 }
else if (IsRepeat(
ch) && !prev_repeatable) {
865 <<
"'" <<
ch <<
"' can only follow a repeatable token.";
869 prev_repeatable = !IsInSet(
ch,
"^$?*+");
883 bool MatchRepetitionAndRegexAtHead(
884 bool escaped,
char c,
char repeat,
const char* regex,
886 const size_t min_count = (repeat ==
'+') ? 1 : 0;
887 const size_t max_count = (repeat ==
'?') ? 1 :
888 static_cast<size_t>(-1) - 1;
892 for (
size_t i = 0;
i <= max_count; ++
i) {
894 if (i >= min_count && MatchRegexAtHead(regex,
str + i)) {
901 if (
str[i] ==
'\0' || !AtomMatchesChar(escaped, c,
str[i]))
910 bool MatchRegexAtHead(
const char* regex,
const char*
str) {
920 const bool escaped = *regex ==
'\\';
923 if (IsRepeat(regex[1])) {
927 return MatchRepetitionAndRegexAtHead(
928 escaped, regex[0], regex[1], regex + 2,
str);
933 return (*
str !=
'\0') && AtomMatchesChar(escaped, *regex, *
str) &&
934 MatchRegexAtHead(regex + 1,
str + 1);
946 bool MatchRegexAnywhere(
const char* regex,
const char*
str) {
947 if (regex ==
nullptr ||
str ==
nullptr)
return false;
950 return MatchRegexAtHead(regex + 1,
str);
954 if (MatchRegexAtHead(regex,
str))
956 }
while (*
str++ !=
'\0');
963 free(
const_cast<char*
>(pattern_));
964 free(
const_cast<char*
>(full_pattern_));
968 bool RE::FullMatch(
const char*
str,
const RE& re) {
969 return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_,
str);
974 bool RE::PartialMatch(
const char*
str,
const RE& re) {
975 return re.is_valid_ && MatchRegexAnywhere(re.pattern_,
str);
980 pattern_ = full_pattern_ =
nullptr;
981 if (regex !=
nullptr) {
985 is_valid_ = ValidateRegex(regex);
991 const size_t len = strlen(regex);
995 char*
buffer =
static_cast<char*
>(malloc(
len + 3));
1006 if (
len == 0 || regex[
len - 1] !=
'$')
1012 #endif // GTEST_USES_POSIX_RE
1022 return file_name +
":";
1048 const char*
const marker =
1052 GetStream() << ::std::endl << marker <<
" "
1069 #if GTEST_HAS_STREAM_REDIRECTION
1076 # if GTEST_OS_WINDOWS
1077 char temp_dir_path[MAX_PATH + 1] = {
'\0' };
1078 char temp_file_path[MAX_PATH + 1] = {
'\0' };
1080 ::GetTempPathA(
sizeof(temp_dir_path), temp_dir_path);
1081 const UINT success = ::GetTempFileNameA(temp_dir_path,
1086 <<
"Unable to create a temporary file in " << temp_dir_path;
1087 const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE);
1088 GTEST_CHECK_(captured_fd != -1) <<
"Unable to open temporary file "
1096 # if GTEST_OS_LINUX_ANDROID
1111 char name_template[] =
"/sdcard/gtest_captured_stream.XXXXXX";
1113 char name_template[] =
"/tmp/captured_stream.XXXXXX";
1114 # endif // GTEST_OS_LINUX_ANDROID
1115 const int captured_fd = mkstemp(name_template);
1116 if (captured_fd == -1) {
1118 <<
"Failed to create tmp file " << name_template
1119 <<
" for test; does the test have access to the /tmp directory?";
1122 # endif // GTEST_OS_WINDOWS
1124 dup2(captured_fd,
fd_);
1142 if (
file ==
nullptr) {
1144 <<
" for capturing stream.";
1167 CapturedStream**
stream) {
1168 if (*
stream !=
nullptr) {
1170 <<
" capturer can exist at a time.";
1172 *
stream =
new CapturedStream(fd);
1179 delete *captured_stream;
1180 *captured_stream =
nullptr;
1205 #endif // GTEST_HAS_STREAM_REDIRECTION
1213 return static_cast<size_t>(ftell(
file));
1218 char*
const buffer =
new char[file_size];
1220 size_t bytes_last_read = 0;
1230 }
while (bytes_last_read > 0 &&
bytes_read < file_size);
1238 #if GTEST_HAS_DEATH_TEST
1239 static const std::vector<std::string>* g_injected_test_argvs =
1242 std::vector<std::string> GetInjectableArgvs() {
1243 if (g_injected_test_argvs !=
nullptr) {
1244 return *g_injected_test_argvs;
1249 void SetInjectableArgvs(
const std::vector<std::string>* new_argvs) {
1250 if (g_injected_test_argvs != new_argvs)
delete g_injected_test_argvs;
1251 g_injected_test_argvs = new_argvs;
1254 void SetInjectableArgvs(
const std::vector<std::string>& new_argvs) {
1256 new std::vector<std::string>(new_argvs.begin(), new_argvs.end()));
1259 void ClearInjectableArgvs() {
1260 delete g_injected_test_argvs;
1261 g_injected_test_argvs =
nullptr;
1263 #endif // GTEST_HAS_DEATH_TEST
1265 #if GTEST_OS_WINDOWS_MOBILE
1269 TerminateProcess(GetCurrentProcess(), 1);
1272 #endif // GTEST_OS_WINDOWS_MOBILE
1282 for (
size_t i = 0;
i != full_flag.length();
i++) {
1294 char*
end =
nullptr;
1295 const long long_value = strtol(
str, &
end, 10);
1301 msg <<
"WARNING: " << src_text
1302 <<
" is expected to be a 32-bit integer, but actually"
1303 <<
" has value \"" <<
str <<
"\".\n";
1311 if (long_value == LONG_MAX || long_value == LONG_MIN ||
1318 msg <<
"WARNING: " << src_text
1319 <<
" is expected to be a 32-bit integer, but actually"
1320 <<
" has value " <<
str <<
", which overflows.\n";
1335 #if defined(GTEST_GET_BOOL_FROM_ENV_)
1336 return GTEST_GET_BOOL_FROM_ENV_(
flag, default_value);
1340 return string_value ==
nullptr ? default_value
1341 : strcmp(string_value,
"0") != 0;
1342 #endif // defined(GTEST_GET_BOOL_FROM_ENV_)
1349 #if defined(GTEST_GET_INT32_FROM_ENV_)
1350 return GTEST_GET_INT32_FROM_ENV_(
flag, default_value);
1354 if (string_value ==
nullptr) {
1356 return default_value;
1361 string_value, &
result)) {
1362 printf(
"The default value %s is used.\n",
1365 return default_value;
1369 #endif // defined(GTEST_GET_INT32_FROM_ENV_)
1382 const char* xml_output_file_env =
posix::GetEnv(
"XML_OUTPUT_FILE");
1383 if (
nullptr != xml_output_file_env) {
1384 default_value_for_output_flag =
std::string(
"xml:") + xml_output_file_env;
1386 return default_value_for_output_flag;
1392 #if defined(GTEST_GET_STRING_FROM_ENV_)
1393 return GTEST_GET_STRING_FROM_ENV_(
flag, default_value);
1397 return value ==
nullptr ? default_value :
value;
1398 #endif // defined(GTEST_GET_STRING_FROM_ENV_)