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
61 # include <sys/procfs.h>
62 #endif // GTEST_OS_QNX
65 # include <procinfo.h>
66 # include <sys/types.h>
67 #endif // GTEST_OS_AIX
70 # include <zircon/process.h>
71 # include <zircon/syscalls.h>
72 #endif // GTEST_OS_FUCHSIA
83 #if defined(_MSC_VER) || defined(__BORLANDC__)
98 std::ifstream file(filename.c_str());
111 (
Message() <<
"/proc/" << getpid() <<
"/stat").GetString();
112 return ReadProcFileField<int>(filename, 19);
118 const task_t task = mach_task_self();
119 mach_msg_type_number_t thread_count;
120 thread_act_array_t thread_list;
121 const kern_return_t status = task_threads(task, &thread_list, &thread_count);
122 if (status == KERN_SUCCESS) {
126 reinterpret_cast<vm_address_t
>(thread_list),
127 sizeof(thread_t) * thread_count);
128 return static_cast<size_t>(thread_count);
139 const int fd = open(
"/proc/self/as", O_RDONLY);
143 procfs_info process_info;
145 devctl(fd, DCMD_PROC_INFO, &process_info,
sizeof(process_info),
nullptr);
148 return static_cast<size_t>(process_info.num_threads);
157 struct procentry64 entry;
158 pid_t pid = getpid();
159 int status = getprocs64(&entry,
sizeof(entry),
nullptr, 0, &pid, 1);
161 return entry.pi_thcount;
167 #elif GTEST_OS_FUCHSIA
172 zx_status_t status = zx_object_get_info(
174 ZX_INFO_PROCESS_THREADS,
179 if (status == ZX_OK) {
194 #endif // GTEST_OS_LINUX
196 #if GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS
198 void SleepMilliseconds(
int n) {
202 AutoHandle::AutoHandle()
203 : handle_(INVALID_HANDLE_VALUE) {}
205 AutoHandle::AutoHandle(Handle handle)
208 AutoHandle::~AutoHandle() {
217 Reset(INVALID_HANDLE_VALUE);
222 if (handle_ != handle) {
224 ::CloseHandle(handle_);
229 <<
"Resetting a valid handle to itself is likely a programmer error "
230 "and thus not allowed.";
234 bool AutoHandle::IsCloseable()
const {
237 return handle_ !=
nullptr && handle_ != INVALID_HANDLE_VALUE;
240 Notification::Notification()
241 : event_(::CreateEvent(nullptr,
248 void Notification::Notify() {
252 void Notification::WaitForNotification() {
254 ::WaitForSingleObject(event_.Get(), INFINITE) == WAIT_OBJECT_0);
258 : owner_thread_id_(0),
260 critical_section_init_phase_(0),
261 critical_section_(new CRITICAL_SECTION) {
262 ::InitializeCriticalSection(critical_section_);
268 if (type_ == kDynamic) {
269 ::DeleteCriticalSection(critical_section_);
270 delete critical_section_;
271 critical_section_ =
nullptr;
276 ThreadSafeLazyInit();
277 ::EnterCriticalSection(critical_section_);
278 owner_thread_id_ = ::GetCurrentThreadId();
281 void Mutex::Unlock() {
282 ThreadSafeLazyInit();
286 owner_thread_id_ = 0;
287 ::LeaveCriticalSection(critical_section_);
292 void Mutex::AssertHeld() {
293 ThreadSafeLazyInit();
294 GTEST_CHECK_(owner_thread_id_ == ::GetCurrentThreadId())
295 <<
"The current thread is not holding the mutex @" <<
this;
308 class MemoryIsNotDeallocated
311 MemoryIsNotDeallocated() : old_crtdbg_flag_(0) {
313 old_crtdbg_flag_ = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
316 _CrtSetDbgFlag(old_crtdbg_flag_ & ~_CRTDBG_ALLOC_MEM_DF);
320 ~MemoryIsNotDeallocated() {
323 _CrtSetDbgFlag(old_crtdbg_flag_);
328 int old_crtdbg_flag_;
336 void Mutex::ThreadSafeLazyInit() {
338 if (type_ == kStatic) {
340 ::InterlockedCompareExchange(&critical_section_init_phase_, 1L, 0L)) {
344 owner_thread_id_ = 0;
347 MemoryIsNotDeallocated memory_is_not_deallocated;
348 critical_section_ =
new CRITICAL_SECTION;
350 ::InitializeCriticalSection(critical_section_);
354 &critical_section_init_phase_, 2L, 1L) ==
360 while (::InterlockedCompareExchange(&critical_section_init_phase_,
374 <<
"Unexpected value of critical_section_init_phase_ "
375 <<
"while initializing a static mutex.";
382 class ThreadWithParamSupport :
public ThreadWithParamBase {
384 static HANDLE CreateThread(Runnable* runnable,
385 Notification* thread_can_start) {
386 ThreadMainParam*
param =
new ThreadMainParam(runnable, thread_can_start);
388 HANDLE thread_handle = ::CreateThread(
391 &ThreadWithParamSupport::ThreadMain,
396 <<
"CreateThread failed with error " << ::GetLastError() <<
".";
397 if (thread_handle ==
nullptr) {
400 return thread_handle;
404 struct ThreadMainParam {
405 ThreadMainParam(Runnable* runnable, Notification* thread_can_start)
406 : runnable_(runnable),
407 thread_can_start_(thread_can_start) {
409 std::unique_ptr<Runnable> runnable_;
411 Notification* thread_can_start_;
414 static DWORD WINAPI ThreadMain(
void* ptr) {
416 std::unique_ptr<ThreadMainParam>
param(
static_cast<ThreadMainParam*
>(ptr));
417 if (
param->thread_can_start_ !=
nullptr)
418 param->thread_can_start_->WaitForNotification();
419 param->runnable_->Run();
424 ThreadWithParamSupport();
431 ThreadWithParamBase::ThreadWithParamBase(Runnable *runnable,
432 Notification* thread_can_start)
433 : thread_(ThreadWithParamSupport::CreateThread(runnable,
437 ThreadWithParamBase::~ThreadWithParamBase() {
442 GTEST_CHECK_(::WaitForSingleObject(thread_.Get(), INFINITE) == WAIT_OBJECT_0)
443 <<
"Failed to join the thread with error " << ::GetLastError() <<
".";
450 class ThreadLocalRegistryImpl {
454 static ThreadLocalValueHolderBase* GetValueOnCurrentThread(
455 const ThreadLocalBase* thread_local_instance) {
456 DWORD current_thread = ::GetCurrentThreadId();
458 ThreadIdToThreadLocals*
const thread_to_thread_locals =
459 GetThreadLocalsMapLocked();
460 ThreadIdToThreadLocals::iterator thread_local_pos =
461 thread_to_thread_locals->find(current_thread);
462 if (thread_local_pos == thread_to_thread_locals->end()) {
463 thread_local_pos = thread_to_thread_locals->insert(
464 std::make_pair(current_thread, ThreadLocalValues())).first;
465 StartWatcherThreadFor(current_thread);
467 ThreadLocalValues& thread_local_values = thread_local_pos->second;
468 ThreadLocalValues::iterator value_pos =
469 thread_local_values.find(thread_local_instance);
470 if (value_pos == thread_local_values.end()) {
473 .insert(std::make_pair(
474 thread_local_instance,
475 std::shared_ptr<ThreadLocalValueHolderBase>(
476 thread_local_instance->NewValueForCurrentThread())))
479 return value_pos->second.get();
482 static void OnThreadLocalDestroyed(
483 const ThreadLocalBase* thread_local_instance) {
484 std::vector<std::shared_ptr<ThreadLocalValueHolderBase> > value_holders;
489 ThreadIdToThreadLocals*
const thread_to_thread_locals =
490 GetThreadLocalsMapLocked();
491 for (ThreadIdToThreadLocals::iterator
it =
492 thread_to_thread_locals->begin();
493 it != thread_to_thread_locals->end();
495 ThreadLocalValues& thread_local_values =
it->second;
496 ThreadLocalValues::iterator value_pos =
497 thread_local_values.find(thread_local_instance);
498 if (value_pos != thread_local_values.end()) {
499 value_holders.push_back(value_pos->second);
500 thread_local_values.erase(value_pos);
510 static void OnThreadExit(DWORD thread_id) {
512 std::vector<std::shared_ptr<ThreadLocalValueHolderBase> > value_holders;
517 ThreadIdToThreadLocals*
const thread_to_thread_locals =
518 GetThreadLocalsMapLocked();
519 ThreadIdToThreadLocals::iterator thread_local_pos =
520 thread_to_thread_locals->find(thread_id);
521 if (thread_local_pos != thread_to_thread_locals->end()) {
522 ThreadLocalValues& thread_local_values = thread_local_pos->second;
523 for (ThreadLocalValues::iterator value_pos =
524 thread_local_values.begin();
525 value_pos != thread_local_values.end();
527 value_holders.push_back(value_pos->second);
529 thread_to_thread_locals->erase(thread_local_pos);
538 typedef std::map<
const ThreadLocalBase*,
539 std::shared_ptr<ThreadLocalValueHolderBase> >
543 typedef std::map<DWORD, ThreadLocalValues> ThreadIdToThreadLocals;
547 typedef std::pair<DWORD, HANDLE> ThreadIdAndHandle;
549 static void StartWatcherThreadFor(DWORD thread_id) {
552 HANDLE thread = ::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION,
558 DWORD watcher_thread_id;
559 HANDLE watcher_thread = ::CreateThread(
562 &ThreadLocalRegistryImpl::WatcherThreadFunc,
563 reinterpret_cast<LPVOID
>(
new ThreadIdAndHandle(thread_id, thread)),
564 CREATE_SUSPENDED, &watcher_thread_id);
568 ::SetThreadPriority(watcher_thread,
569 ::GetThreadPriority(::GetCurrentThread()));
570 ::ResumeThread(watcher_thread);
571 ::CloseHandle(watcher_thread);
576 static DWORD WINAPI WatcherThreadFunc(LPVOID
param) {
577 const ThreadIdAndHandle* tah =
578 reinterpret_cast<const ThreadIdAndHandle*
>(
param);
580 ::WaitForSingleObject(tah->second, INFINITE) == WAIT_OBJECT_0);
581 OnThreadExit(tah->first);
582 ::CloseHandle(tah->second);
588 static ThreadIdToThreadLocals* GetThreadLocalsMapLocked() {
590 MemoryIsNotDeallocated memory_is_not_deallocated;
591 static ThreadIdToThreadLocals*
map =
new ThreadIdToThreadLocals();
598 static Mutex thread_map_mutex_;
602 Mutex ThreadLocalRegistryImpl::thread_map_mutex_(Mutex::kStaticMutex);
604 ThreadLocalValueHolderBase* ThreadLocalRegistry::GetValueOnCurrentThread(
605 const ThreadLocalBase* thread_local_instance) {
606 return ThreadLocalRegistryImpl::GetValueOnCurrentThread(
607 thread_local_instance);
610 void ThreadLocalRegistry::OnThreadLocalDestroyed(
611 const ThreadLocalBase* thread_local_instance) {
612 ThreadLocalRegistryImpl::OnThreadLocalDestroyed(thread_local_instance);
615 #endif // GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS
617 #if GTEST_USES_POSIX_RE
627 regfree(&partial_regex_);
628 regfree(&full_regex_);
630 free(
const_cast<char*
>(pattern_));
634 bool RE::FullMatch(
const char*
str,
const RE& re) {
635 if (!re.is_valid_)
return false;
638 return regexec(&re.full_regex_,
str, 1, &match, 0) == 0;
643 bool RE::PartialMatch(
const char*
str,
const RE& re) {
644 if (!re.is_valid_)
return false;
647 return regexec(&re.partial_regex_,
str, 1, &match, 0) == 0;
656 const size_t full_regex_len = strlen(regex) + 10;
657 char*
const full_pattern =
new char[full_regex_len];
659 snprintf(full_pattern, full_regex_len,
"^(%s)$", regex);
660 is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0;
670 const char*
const partial_regex = (*regex ==
'\0') ?
"()" : regex;
671 is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0;
674 <<
"Regular expression \"" << regex
675 <<
"\" is not a valid POSIX Extended regular expression.";
677 delete[] full_pattern;
680 #elif GTEST_USES_SIMPLE_RE
684 bool IsInSet(
char ch,
const char*
str) {
685 return ch !=
'\0' && strchr(
str,
ch) !=
nullptr;
691 bool IsAsciiDigit(
char ch) {
return '0' <=
ch &&
ch <=
'9'; }
692 bool IsAsciiPunct(
char ch) {
693 return IsInSet(
ch,
"^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~");
695 bool IsRepeat(
char ch) {
return IsInSet(
ch,
"?*+"); }
696 bool IsAsciiWhiteSpace(
char ch) {
return IsInSet(
ch,
" \f\n\r\t\v"); }
697 bool IsAsciiWordChar(
char ch) {
698 return (
'a' <=
ch &&
ch <=
'z') || (
'A' <=
ch &&
ch <=
'Z') ||
699 (
'0' <=
ch &&
ch <=
'9') ||
ch ==
'_';
703 bool IsValidEscape(
char c) {
704 return (IsAsciiPunct(c) || IsInSet(c,
"dDfnrsStvwW"));
709 bool AtomMatchesChar(
bool escaped,
char pattern_char,
char ch) {
711 switch (pattern_char) {
712 case 'd':
return IsAsciiDigit(
ch);
713 case 'D':
return !IsAsciiDigit(
ch);
714 case 'f':
return ch ==
'\f';
715 case 'n':
return ch ==
'\n';
716 case 'r':
return ch ==
'\r';
717 case 's':
return IsAsciiWhiteSpace(
ch);
718 case 'S':
return !IsAsciiWhiteSpace(
ch);
719 case 't':
return ch ==
'\t';
720 case 'v':
return ch ==
'\v';
721 case 'w':
return IsAsciiWordChar(
ch);
722 case 'W':
return !IsAsciiWordChar(
ch);
724 return IsAsciiPunct(pattern_char) && pattern_char ==
ch;
727 return (pattern_char ==
'.' &&
ch !=
'\n') || pattern_char ==
ch;
732 return (Message() <<
"Syntax error at index " <<
index
733 <<
" in simple regular expression \"" << regex <<
"\": ").GetString();
738 bool ValidateRegex(
const char* regex) {
739 if (regex ==
nullptr) {
740 ADD_FAILURE() <<
"NULL is not a valid simple regular expression.";
744 bool is_valid =
true;
747 bool prev_repeatable =
false;
748 for (
int i = 0; regex[
i];
i++) {
749 if (regex[
i] ==
'\\') {
751 if (regex[
i] ==
'\0') {
753 <<
"'\\' cannot appear at the end.";
757 if (!IsValidEscape(regex[
i])) {
759 <<
"invalid escape sequence \"\\" << regex[
i] <<
"\".";
762 prev_repeatable =
true;
764 const char ch = regex[
i];
766 if (
ch ==
'^' &&
i > 0) {
768 <<
"'^' can only appear at the beginning.";
770 }
else if (
ch ==
'$' && regex[
i + 1] !=
'\0') {
772 <<
"'$' can only appear at the end.";
774 }
else if (IsInSet(
ch,
"()[]{}|")) {
776 <<
"'" <<
ch <<
"' is unsupported.";
778 }
else if (IsRepeat(
ch) && !prev_repeatable) {
780 <<
"'" <<
ch <<
"' can only follow a repeatable token.";
784 prev_repeatable = !IsInSet(
ch,
"^$?*+");
798 bool MatchRepetitionAndRegexAtHead(
799 bool escaped,
char c,
char repeat,
const char* regex,
801 const size_t min_count = (repeat ==
'+') ? 1 : 0;
802 const size_t max_count = (repeat ==
'?') ? 1 :
803 static_cast<size_t>(-1) - 1;
807 for (
size_t i = 0;
i <= max_count; ++
i) {
809 if (
i >= min_count && MatchRegexAtHead(regex,
str +
i)) {
816 if (
str[
i] ==
'\0' || !AtomMatchesChar(escaped, c,
str[
i]))
825 bool MatchRegexAtHead(
const char* regex,
const char*
str) {
835 const bool escaped = *regex ==
'\\';
838 if (IsRepeat(regex[1])) {
842 return MatchRepetitionAndRegexAtHead(
843 escaped, regex[0], regex[1], regex + 2,
str);
848 return (*
str !=
'\0') && AtomMatchesChar(escaped, *regex, *
str) &&
849 MatchRegexAtHead(regex + 1,
str + 1);
861 bool MatchRegexAnywhere(
const char* regex,
const char*
str) {
862 if (regex ==
nullptr ||
str ==
nullptr)
return false;
865 return MatchRegexAtHead(regex + 1,
str);
869 if (MatchRegexAtHead(regex,
str))
871 }
while (*
str++ !=
'\0');
878 free(
const_cast<char*
>(pattern_));
879 free(
const_cast<char*
>(full_pattern_));
883 bool RE::FullMatch(
const char*
str,
const RE& re) {
884 return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_,
str);
889 bool RE::PartialMatch(
const char*
str,
const RE& re) {
890 return re.is_valid_ && MatchRegexAnywhere(re.pattern_,
str);
895 pattern_ = full_pattern_ =
nullptr;
896 if (regex !=
nullptr) {
900 is_valid_ = ValidateRegex(regex);
906 const size_t len = strlen(regex);
910 char*
buffer =
static_cast<char*
>(malloc(
len + 3));
921 if (
len == 0 || regex[
len - 1] !=
'$')
927 #endif // GTEST_USES_POSIX_RE
937 return file_name +
":";
952 const char* file,
int line) {
963 const char*
const marker =
967 GetStream() << ::std::endl << marker <<
" "
984 #if GTEST_HAS_STREAM_REDIRECTION
990 explicit CapturedStream(
int fd) : fd_(fd), uncaptured_fd_(dup(fd)) {
991 # if GTEST_OS_WINDOWS
992 char temp_dir_path[MAX_PATH + 1] = {
'\0' };
993 char temp_file_path[MAX_PATH + 1] = {
'\0' };
995 ::GetTempPathA(
sizeof(temp_dir_path), temp_dir_path);
996 const UINT success = ::GetTempFileNameA(temp_dir_path,
1001 <<
"Unable to create a temporary file in " << temp_dir_path;
1002 const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE);
1003 GTEST_CHECK_(captured_fd != -1) <<
"Unable to open temporary file "
1005 filename_ = temp_file_path;
1011 # if GTEST_OS_LINUX_ANDROID
1026 char name_template[] =
"/sdcard/gtest_captured_stream.XXXXXX";
1028 char name_template[] =
"/tmp/captured_stream.XXXXXX";
1029 # endif // GTEST_OS_LINUX_ANDROID
1030 const int captured_fd = mkstemp(name_template);
1031 filename_ = name_template;
1032 # endif // GTEST_OS_WINDOWS
1034 dup2(captured_fd, fd_);
1039 remove(filename_.c_str());
1043 if (uncaptured_fd_ != -1) {
1046 dup2(uncaptured_fd_, fd_);
1047 close(uncaptured_fd_);
1048 uncaptured_fd_ = -1;
1051 FILE*
const file =
posix::FOpen(filename_.c_str(),
"r");
1072 static
void CaptureStream(
int fd,
const char* stream_name,
1074 if (*
stream !=
nullptr) {
1076 <<
" capturer can exist at a time.";
1083 const std::string content = (*captured_stream)->GetCapturedString();
1085 delete *captured_stream;
1086 *captured_stream =
nullptr;
1103 return GetCapturedStream(&g_captured_stdout);
1108 return GetCapturedStream(&g_captured_stderr);
1111 #endif // GTEST_HAS_STREAM_REDIRECTION
1118 fseek(file, 0, SEEK_END);
1119 return static_cast<size_t>(ftell(file));
1124 char*
const buffer =
new char[file_size];
1126 size_t bytes_last_read = 0;
1127 size_t bytes_read = 0;
1129 fseek(file, 0, SEEK_SET);
1134 bytes_last_read = fread(
buffer+bytes_read, 1, file_size-bytes_read, file);
1135 bytes_read += bytes_last_read;
1136 }
while (bytes_last_read > 0 && bytes_read < file_size);
1144 #if GTEST_HAS_DEATH_TEST
1145 static const std::vector<std::string>* g_injected_test_argvs =
1148 std::vector<std::string> GetInjectableArgvs() {
1149 if (g_injected_test_argvs !=
nullptr) {
1150 return *g_injected_test_argvs;
1155 void SetInjectableArgvs(
const std::vector<std::string>* new_argvs) {
1156 if (g_injected_test_argvs != new_argvs)
delete g_injected_test_argvs;
1157 g_injected_test_argvs = new_argvs;
1160 void SetInjectableArgvs(
const std::vector<std::string>& new_argvs) {
1162 new std::vector<std::string>(new_argvs.begin(), new_argvs.end()));
1165 #if GTEST_HAS_GLOBAL_STRING
1166 void SetInjectableArgvs(
const std::vector< ::string>& new_argvs) {
1168 new std::vector<std::string>(new_argvs.begin(), new_argvs.end()));
1170 #endif // GTEST_HAS_GLOBAL_STRING
1172 void ClearInjectableArgvs() {
1173 delete g_injected_test_argvs;
1174 g_injected_test_argvs =
nullptr;
1176 #endif // GTEST_HAS_DEATH_TEST
1178 #if GTEST_OS_WINDOWS_MOBILE
1182 TerminateProcess(GetCurrentProcess(), 1);
1185 #endif // GTEST_OS_WINDOWS_MOBILE
1195 for (
size_t i = 0;
i != full_flag.length();
i++) {
1196 env_var <<
ToUpper(full_flag.c_str()[
i]);
1207 char*
end =
nullptr;
1208 const long long_value = strtol(
str, &
end, 10);
1214 msg <<
"WARNING: " << src_text
1215 <<
" is expected to be a 32-bit integer, but actually"
1216 <<
" has value \"" <<
str <<
"\".\n";
1223 const Int32 result =
static_cast<Int32>(long_value);
1224 if (long_value == LONG_MAX || long_value == LONG_MIN ||
1227 result != long_value
1231 msg <<
"WARNING: " << src_text
1232 <<
" is expected to be a 32-bit integer, but actually"
1233 <<
" has value " <<
str <<
", which overflows.\n";
1248 #if defined(GTEST_GET_BOOL_FROM_ENV_)
1252 const char*
const string_value =
posix::GetEnv(env_var.c_str());
1254 : strcmp(string_value,
"0") != 0;
1255 #endif // defined(GTEST_GET_BOOL_FROM_ENV_)
1262 #if defined(GTEST_GET_INT32_FROM_ENV_)
1266 const char*
const string_value =
posix::GetEnv(env_var.c_str());
1267 if (string_value ==
nullptr) {
1274 string_value, &result)) {
1275 printf(
"The default value %s is used.\n",
1282 #endif // defined(GTEST_GET_INT32_FROM_ENV_)
1295 const char* xml_output_file_env =
posix::GetEnv(
"XML_OUTPUT_FILE");
1296 if (
nullptr != xml_output_file_env) {
1297 default_value_for_output_flag =
std::string(
"xml:") + xml_output_file_env;
1299 return default_value_for_output_flag;
1305 #if defined(GTEST_GET_STRING_FROM_ENV_)
1311 #endif // defined(GTEST_GET_STRING_FROM_ENV_)