diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-12 14:27:29 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-13 09:35:20 +0000 |
commit | c30a6232df03e1efbd9f3b226777b07e087a1122 (patch) | |
tree | e992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/base/process | |
parent | 7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff) | |
download | qtwebengine-chromium-85-based.tar.gz |
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/base/process')
19 files changed, 187 insertions, 27 deletions
diff --git a/chromium/base/process/internal_linux.cc b/chromium/base/process/internal_linux.cc index 35b491738af..41cae833a24 100644 --- a/chromium/base/process/internal_linux.cc +++ b/chromium/base/process/internal_linux.cc @@ -13,6 +13,7 @@ #include "base/files/file_util.h" #include "base/logging.h" +#include "base/notreached.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" @@ -56,6 +57,7 @@ pid_t ProcDirSlotToPid(const char* d_name) { } bool ReadProcFile(const FilePath& file, std::string* buffer) { + DCHECK(FilePath(kProcDir).IsParent(file)); buffer->clear(); // Synchronously reading files in /proc is safe. ThreadRestrictions::ScopedAllowIO allow_io; diff --git a/chromium/base/process/internal_linux.h b/chromium/base/process/internal_linux.h index d8904fd1102..dd6657ac795 100644 --- a/chromium/base/process/internal_linux.h +++ b/chromium/base/process/internal_linux.h @@ -30,6 +30,11 @@ extern const char kStatFile[]; // Returns a FilePath to "/proc/pid". base::FilePath GetProcPidDir(pid_t pid); +// Reads a file from /proc into a string. This is allowed on any thread as +// reading from /proc does not hit the disk. Returns true if the file can be +// read and is non-empty. +bool ReadProcFile(const FilePath& file, std::string* buffer); + // Take a /proc directory entry named |d_name|, and if it is the directory for // a process, convert it to a pid_t. // Returns 0 on failure. diff --git a/chromium/base/process/kill_fuchsia.cc b/chromium/base/process/kill_fuchsia.cc index 2684a14756d..1b7bbd6a283 100644 --- a/chromium/base/process/kill_fuchsia.cc +++ b/chromium/base/process/kill_fuchsia.cc @@ -6,6 +6,7 @@ #include <zircon/syscalls.h> +#include "base/logging.h" #include "base/process/process_iterator.h" #include "base/task/post_task.h" #include "base/threading/platform_thread.h" diff --git a/chromium/base/process/kill_win.cc b/chromium/base/process/kill_win.cc index 3b85dea1cd4..61e8ed5c86c 100644 --- a/chromium/base/process/kill_win.cc +++ b/chromium/base/process/kill_win.cc @@ -12,6 +12,7 @@ #include "base/logging.h" #include "base/macros.h" +#include "base/notreached.h" #include "base/process/memory.h" #include "base/process/process_iterator.h" diff --git a/chromium/base/process/launch_mac.cc b/chromium/base/process/launch_mac.cc index 6fc6ba115fb..9e523d39181 100644 --- a/chromium/base/process/launch_mac.cc +++ b/chromium/base/process/launch_mac.cc @@ -19,7 +19,7 @@ #include "base/process/environment_internal.h" #include "base/threading/scoped_blocking_call.h" #include "base/threading/thread_restrictions.h" -#include "base/trace_event/trace_event.h" +#include "base/trace_event/base_tracing.h" extern "C" { // Changes the current thread's directory to a path or directory file diff --git a/chromium/base/process/launch_posix.cc b/chromium/base/process/launch_posix.cc index 9b7573fdc65..8ad7aa154fa 100644 --- a/chromium/base/process/launch_posix.cc +++ b/chromium/base/process/launch_posix.cc @@ -45,7 +45,7 @@ #include "base/threading/scoped_blocking_call.h" #include "base/threading/thread_restrictions.h" #include "base/time/time.h" -#include "base/trace_event/trace_event.h" +#include "base/trace_event/base_tracing.h" #include "build/build_config.h" #if defined(OS_LINUX) || defined(OS_AIX) diff --git a/chromium/base/process/memory_linux.cc b/chromium/base/process/memory_linux.cc index 6a6091a6047..ac8ffe1c243 100644 --- a/chromium/base/process/memory_linux.cc +++ b/chromium/base/process/memory_linux.cc @@ -132,11 +132,11 @@ bool UncheckedMalloc(size_t size, void** result) { #if BUILDFLAG(USE_ALLOCATOR_SHIM) *result = allocator::UncheckedAlloc(size); #elif defined(MEMORY_TOOL_REPLACES_ALLOCATOR) || \ - (!defined(LIBC_GLIBC) && !defined(USE_TCMALLOC)) + (!defined(LIBC_GLIBC) && !BUILDFLAG(USE_TCMALLOC)) *result = malloc(size); -#elif defined(LIBC_GLIBC) && !defined(USE_TCMALLOC) +#elif defined(LIBC_GLIBC) && !BUILDFLAG(USE_TCMALLOC) *result = __libc_malloc(size); -#elif defined(USE_TCMALLOC) +#elif BUILDFLAG(USE_TCMALLOC) *result = tc_malloc_skip_new_handler(size); #endif return *result != nullptr; diff --git a/chromium/base/process/process_handle.cc b/chromium/base/process/process_handle.cc index 7b130b40b14..fcaa129126c 100644 --- a/chromium/base/process/process_handle.cc +++ b/chromium/base/process/process_handle.cc @@ -6,6 +6,8 @@ #include <stdint.h> +#include <ostream> + #include "base/check.h" #include "build/build_config.h" diff --git a/chromium/base/process/process_info_win.cc b/chromium/base/process/process_info_win.cc index 05d0f21a930..594fd1d112d 100644 --- a/chromium/base/process/process_info_win.cc +++ b/chromium/base/process/process_info_win.cc @@ -9,6 +9,7 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" +#include "base/notreached.h" #include "base/time/time.h" #include "base/win/scoped_handle.h" diff --git a/chromium/base/process/process_iterator_linux.cc b/chromium/base/process/process_iterator_linux.cc index 39313b2bb55..fd1821a2670 100644 --- a/chromium/base/process/process_iterator_linux.cc +++ b/chromium/base/process/process_iterator_linux.cc @@ -8,6 +8,7 @@ #include "base/files/file_util.h" #include "base/logging.h" +#include "base/notreached.h" #include "base/process/internal_linux.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" diff --git a/chromium/base/process/process_metrics.h b/chromium/base/process/process_metrics.h index 2b7cfe14f73..be23db0f928 100644 --- a/chromium/base/process/process_metrics.h +++ b/chromium/base/process/process_metrics.h @@ -13,11 +13,14 @@ #include <memory> #include <string> +#include <utility> +#include <vector> #include "base/base_export.h" #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/process/process_handle.h" +#include "base/threading/platform_thread.h" #include "base/time/time.h" #include "base/values.h" #include "build/build_config.h" @@ -118,6 +121,17 @@ class BASE_EXPORT ProcessMetrics { // will result in a time delta of 2 seconds/per 1 wall-clock second. TimeDelta GetCumulativeCPUUsage(); + // Emits the cumulative CPU usage for all currently active threads since they + // were started into the output parameter (replacing its current contents). + // Threads that have already terminated will not be reported. Thus, the sum of + // these times may not equal the value returned by GetCumulativeCPUUsage(). + // Returns false on failure. We return the usage via an output parameter to + // allow reuse of CPUUsagePerThread's std::vector by the caller, e.g. to avoid + // allocations between repeated calls to method. + // NOTE: Currently only supported on Linux/Android. + using CPUUsagePerThread = std::vector<std::pair<PlatformThreadId, TimeDelta>>; + bool GetCumulativeCPUUsagePerThread(CPUUsagePerThread&); + // Returns the number of average idle cpu wakeups per second since the last // call. int GetIdleWakeupsPerSecond(); diff --git a/chromium/base/process/process_metrics_freebsd.cc b/chromium/base/process/process_metrics_freebsd.cc index a552c033dd8..3fc3160cc1e 100644 --- a/chromium/base/process/process_metrics_freebsd.cc +++ b/chromium/base/process/process_metrics_freebsd.cc @@ -42,6 +42,11 @@ TimeDelta ProcessMetrics::GetCumulativeCPUUsage() { return TimeDelta(); } +bool ProcessMetrics::GetCumulativeCPUUsagePerThread(CPUUsagePerThread&) { + NOTREACHED(); + return false; +} + bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const { return false; } diff --git a/chromium/base/process/process_metrics_fuchsia.cc b/chromium/base/process/process_metrics_fuchsia.cc index 3c7d14cd84e..fc9b0c46eee 100644 --- a/chromium/base/process/process_metrics_fuchsia.cc +++ b/chromium/base/process/process_metrics_fuchsia.cc @@ -6,6 +6,8 @@ #include <lib/fdio/limits.h> +#include "base/notreached.h" + namespace base { size_t GetMaxFds() { @@ -35,6 +37,12 @@ TimeDelta ProcessMetrics::GetCumulativeCPUUsage() { return TimeDelta(); } +bool ProcessMetrics::GetCumulativeCPUUsagePerThread(CPUUsagePerThread&) { + // TODO(https://crbug.com/926581). + NOTIMPLEMENTED(); + return false; +} + bool GetSystemMemoryInfo(SystemMemoryInfoKB* meminfo) { // TODO(https://crbug.com/926581). return false; diff --git a/chromium/base/process/process_metrics_ios.cc b/chromium/base/process/process_metrics_ios.cc index ae36b7d4fc6..6e466801f3b 100644 --- a/chromium/base/process/process_metrics_ios.cc +++ b/chromium/base/process/process_metrics_ios.cc @@ -32,6 +32,11 @@ TimeDelta ProcessMetrics::GetCumulativeCPUUsage() { return TimeDelta(); } +bool ProcessMetrics::GetCumulativeCPUUsagePerThread(CPUUsagePerThread&) { + NOTIMPLEMENTED(); + return false; +} + size_t GetMaxFds() { static const rlim_t kSystemDefaultMaxFds = 256; rlim_t max_fds; diff --git a/chromium/base/process/process_metrics_linux.cc b/chromium/base/process/process_metrics_linux.cc index 7ffccec2b3e..99bc54bc32b 100644 --- a/chromium/base/process/process_metrics_linux.cc +++ b/chromium/base/process/process_metrics_linux.cc @@ -18,6 +18,7 @@ #include "base/files/file_util.h" #include "base/logging.h" #include "base/memory/ptr_util.h" +#include "base/notreached.h" #include "base/optional.h" #include "base/process/internal_linux.h" #include "base/process/process_metrics_iocounters.h" @@ -60,13 +61,9 @@ bool ReadProcFileToTrimmedStringPairs(pid_t pid, StringPiece filename, StringPairs* key_value_pairs) { std::string status_data; - { - // Synchronously reading files in /proc does not hit the disk. - ThreadRestrictions::ScopedAllowIO allow_io; - FilePath status_file = internal::GetProcPidDir(pid).Append(filename); - if (!ReadFileToString(status_file, &status_data)) - return false; - } + FilePath status_file = internal::GetProcPidDir(pid).Append(filename); + if (!internal::ReadProcFile(status_file, &status_data)) + return false; SplitStringIntoKeyValuePairs(status_data, ':', '\n', key_value_pairs); TrimKeyValuePairs(key_value_pairs); return true; @@ -130,6 +127,13 @@ bool ReadProcStatusAndGetFieldAsUint64(pid_t pid, } #endif // defined(OS_LINUX) || defined(OS_AIX) +// Get the total CPU from a proc stat buffer. Return value is number of jiffies +// on success or 0 if parsing failed. +int64_t ParseTotalCPUTimeFromStats(const std::vector<std::string>& proc_stats) { + return internal::GetProcStatsFieldAsInt64(proc_stats, internal::VM_UTIME) + + internal::GetProcStatsFieldAsInt64(proc_stats, internal::VM_STIME); +} + // Get the total CPU of a single process. Return value is number of jiffies // on success or -1 on error. int64_t GetProcessCPU(pid_t pid) { @@ -140,11 +144,7 @@ int64_t GetProcessCPU(pid_t pid) { return -1; } - int64_t total_cpu = - internal::GetProcStatsFieldAsInt64(proc_stats, internal::VM_UTIME) + - internal::GetProcStatsFieldAsInt64(proc_stats, internal::VM_STIME); - - return total_cpu; + return ParseTotalCPUTimeFromStats(proc_stats); } #if defined(OS_CHROMEOS) @@ -175,7 +175,7 @@ void ReadChromeOSGraphicsMemory(SystemMemoryInfoKB* meminfo) { // Incorporate Mali graphics memory if present. FilePath mali_memory_file("/sys/class/misc/mali0/device/memory"); std::string mali_memory_data; - if (ReadFileToString(mali_memory_file, &mali_memory_data)) { + if (ReadFileToStringNonBlocking(mali_memory_file, &mali_memory_data)) { long long mali_size = -1; int num_res = sscanf(mali_memory_data.c_str(), "%lld bytes", &mali_size); if (num_res == 1) @@ -202,6 +202,43 @@ TimeDelta ProcessMetrics::GetCumulativeCPUUsage() { return internal::ClockTicksToTimeDelta(GetProcessCPU(process_)); } +bool ProcessMetrics::GetCumulativeCPUUsagePerThread( + CPUUsagePerThread& cpu_per_thread) { + cpu_per_thread.clear(); + + // Iterate through the different threads tracked in /proc/<pid>/task. + FilePath fd_path = internal::GetProcPidDir(process_).Append("task"); + + DirReaderPosix dir_reader(fd_path.value().c_str()); + if (!dir_reader.IsValid()) + return false; + + for (; dir_reader.Next();) { + const char* tid_str = dir_reader.name(); + if (strcmp(tid_str, ".") == 0 || strcmp(tid_str, "..") == 0) + continue; + + PlatformThreadId tid; + if (!StringToInt(tid_str, &tid)) + continue; + + FilePath thread_stat_path = fd_path.Append(tid_str).Append("stat"); + + std::string buffer; + std::vector<std::string> proc_stats; + if (!internal::ReadProcFile(thread_stat_path, &buffer) || + !internal::ParseProcStats(buffer, &proc_stats)) { + continue; + } + + TimeDelta thread_time = + internal::ClockTicksToTimeDelta(ParseTotalCPUTimeFromStats(proc_stats)); + cpu_per_thread.emplace_back(tid, thread_time); + } + + return !cpu_per_thread.empty(); +} + // For the /proc/self/io file to exist, the Linux kernel must have // CONFIG_TASK_IO_ACCOUNTING enabled. bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const { @@ -280,7 +317,7 @@ int ProcessMetrics::GetOpenFdSoftLimit() const { FilePath fd_path = internal::GetProcPidDir(process_).Append("limits"); std::string limits_contents; - if (!ReadFileToString(fd_path, &limits_contents)) + if (!ReadFileToStringNonBlocking(fd_path, &limits_contents)) return -1; for (const auto& line : SplitStringPiece( @@ -556,7 +593,7 @@ bool GetSystemMemoryInfo(SystemMemoryInfoKB* meminfo) { // Used memory is: total - free - buffers - caches FilePath meminfo_file("/proc/meminfo"); std::string meminfo_data; - if (!ReadFileToString(meminfo_file, &meminfo_data)) { + if (!ReadFileToStringNonBlocking(meminfo_file, &meminfo_data)) { DLOG(WARNING) << "Failed to open " << meminfo_file.value(); return false; } @@ -587,7 +624,7 @@ bool GetVmStatInfo(VmStatInfo* vmstat) { FilePath vmstat_file("/proc/vmstat"); std::string vmstat_data; - if (!ReadFileToString(vmstat_file, &vmstat_data)) { + if (!ReadFileToStringNonBlocking(vmstat_file, &vmstat_data)) { DLOG(WARNING) << "Failed to open " << vmstat_file.value(); return false; } @@ -666,7 +703,7 @@ bool GetSystemDiskInfo(SystemDiskInfo* diskinfo) { FilePath diskinfo_file("/proc/diskstats"); std::string diskinfo_data; - if (!ReadFileToString(diskinfo_file, &diskinfo_data)) { + if (!ReadFileToStringNonBlocking(diskinfo_file, &diskinfo_data)) { DLOG(WARNING) << "Failed to open " << diskinfo_file.value(); return false; } @@ -866,7 +903,7 @@ bool GetSwapInfoImpl(SwapInfo* swap_info) { } std::string mm_stat_data; - if (!ReadFileToString(zram_mm_stat_file, &mm_stat_data)) { + if (!ReadFileToStringNonBlocking(zram_mm_stat_file, &mm_stat_data)) { DLOG(WARNING) << "Failed to open " << zram_mm_stat_file.value(); return false; } @@ -879,7 +916,7 @@ bool GetSwapInfoImpl(SwapInfo* swap_info) { FilePath zram_stat_file("/sys/block/zram0/stat"); std::string stat_data; - if (!ReadFileToString(zram_stat_file, &stat_data)) { + if (!ReadFileToStringNonBlocking(zram_stat_file, &stat_data)) { DLOG(WARNING) << "Failed to open " << zram_stat_file.value(); return false; } diff --git a/chromium/base/process/process_metrics_mac.cc b/chromium/base/process/process_metrics_mac.cc index d0f35471cb7..33b10d8563f 100644 --- a/chromium/base/process/process_metrics_mac.cc +++ b/chromium/base/process/process_metrics_mac.cc @@ -154,6 +154,11 @@ TimeDelta ProcessMetrics::GetCumulativeCPUUsage() { return TimeDelta::FromMicroseconds(TimeValToMicroseconds(task_timeval)); } +bool ProcessMetrics::GetCumulativeCPUUsagePerThread(CPUUsagePerThread&) { + NOTIMPLEMENTED(); + return false; +} + int ProcessMetrics::GetPackageIdleWakeupsPerSecond() { mach_port_t task = TaskForPid(process_); task_power_info power_info_data; diff --git a/chromium/base/process/process_metrics_openbsd.cc b/chromium/base/process/process_metrics_openbsd.cc index 0fb41b6ff3a..0399f8d4441 100644 --- a/chromium/base/process/process_metrics_openbsd.cc +++ b/chromium/base/process/process_metrics_openbsd.cc @@ -64,6 +64,11 @@ TimeDelta ProcessMetrics::GetCumulativeCPUUsage() { return TimeDelta(); } +bool ProcessMetrics::GetCumulativeCPUUsagePerThread(CPUUsagePerThread&) { + NOTREACHED(); + return false; +} + ProcessMetrics::ProcessMetrics(ProcessHandle process) : process_(process), last_cpu_(0) {} diff --git a/chromium/base/process/process_metrics_unittest.cc b/chromium/base/process/process_metrics_unittest.cc index 808a7be09d0..c269a4713f7 100644 --- a/chromium/base/process/process_metrics_unittest.cc +++ b/chromium/base/process/process_metrics_unittest.cc @@ -35,7 +35,8 @@ namespace base { namespace debug { -#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_WIN) +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_WIN) || \ + defined(OS_ANDROID) namespace { void BusyWork(std::vector<std::string>* vec) { @@ -47,7 +48,8 @@ void BusyWork(std::vector<std::string>* vec) { } } // namespace -#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_WIN) || + // defined(OS_ANDROID) // Tests for SystemMetrics. // Exists as a class so it can be a friend of SystemMetrics. @@ -376,7 +378,7 @@ TEST_F(SystemMetricsTest, TestNoNegativeCpuUsage) { EXPECT_GE(metrics->GetPlatformIndependentCPUUsage(), 0.0); } -#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) +#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_WIN) #if defined(OS_CHROMEOS) TEST_F(SystemMetricsTest, ParseZramMmStat) { @@ -646,6 +648,7 @@ TEST(ProcessMetricsTest, GetOpenFdCount) { #endif // defined(OS_LINUX) || (defined(OS_MACOSX) && !defined(OS_IOS)) #if defined(OS_ANDROID) || defined(OS_LINUX) + TEST(ProcessMetricsTestLinux, GetPageFaultCounts) { std::unique_ptr<base::ProcessMetrics> process_metrics( base::ProcessMetrics::CreateProcessMetrics( @@ -676,6 +679,66 @@ TEST(ProcessMetricsTestLinux, GetPageFaultCounts) { ASSERT_GT(counts_after.minor, counts.minor); ASSERT_GE(counts_after.major, counts.major); } + +TEST(ProcessMetricsTestLinux, GetCumulativeCPUUsagePerThread) { + ProcessHandle handle = GetCurrentProcessHandle(); + std::unique_ptr<ProcessMetrics> metrics( + ProcessMetrics::CreateProcessMetrics(handle)); + + Thread thread1("thread1"); + thread1.StartAndWaitForTesting(); + ASSERT_TRUE(thread1.IsRunning()); + + std::vector<std::string> vec1; + thread1.task_runner()->PostTask(FROM_HERE, BindOnce(&BusyWork, &vec1)); + + ProcessMetrics::CPUUsagePerThread prev_thread_times; + EXPECT_TRUE(metrics->GetCumulativeCPUUsagePerThread(prev_thread_times)); + + // Should have at least the test runner thread and the thread spawned above. + EXPECT_GE(prev_thread_times.size(), 2u); + EXPECT_TRUE(std::any_of( + prev_thread_times.begin(), prev_thread_times.end(), + [&thread1](const std::pair<PlatformThreadId, base::TimeDelta>& entry) { + return entry.first == thread1.GetThreadId(); + })); + EXPECT_TRUE(std::any_of( + prev_thread_times.begin(), prev_thread_times.end(), + [](const std::pair<PlatformThreadId, base::TimeDelta>& entry) { + return entry.first == base::PlatformThread::CurrentId(); + })); + + for (const auto& entry : prev_thread_times) { + EXPECT_GE(entry.second, base::TimeDelta()); + } + + thread1.Stop(); + + ProcessMetrics::CPUUsagePerThread current_thread_times; + EXPECT_TRUE(metrics->GetCumulativeCPUUsagePerThread(current_thread_times)); + + // The stopped thread may still be reported until the kernel cleans it up. + EXPECT_GE(prev_thread_times.size(), 1u); + EXPECT_TRUE(std::any_of( + current_thread_times.begin(), current_thread_times.end(), + [](const std::pair<PlatformThreadId, base::TimeDelta>& entry) { + return entry.first == base::PlatformThread::CurrentId(); + })); + + // Reported times should not decrease. + for (const auto& entry : current_thread_times) { + auto prev_it = std::find_if( + prev_thread_times.begin(), prev_thread_times.end(), + [&entry]( + const std::pair<PlatformThreadId, base::TimeDelta>& prev_entry) { + return entry.first == prev_entry.first; + }); + + if (prev_it != prev_thread_times.end()) + EXPECT_GE(entry.second, prev_it->second); + } +} + #endif // defined(OS_ANDROID) || defined(OS_LINUX) #if defined(OS_WIN) diff --git a/chromium/base/process/process_metrics_win.cc b/chromium/base/process/process_metrics_win.cc index 5cf0943c654..3cd51852a33 100644 --- a/chromium/base/process/process_metrics_win.cc +++ b/chromium/base/process/process_metrics_win.cc @@ -162,6 +162,11 @@ TimeDelta ProcessMetrics::GetCumulativeCPUUsage() { TimeDelta::FromFileTime(user_time); } +bool ProcessMetrics::GetCumulativeCPUUsagePerThread(CPUUsagePerThread&) { + NOTIMPLEMENTED(); + return false; +} + bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const { if (!process_.IsValid()) return false; |