Fix issue 410: test-log/ProfLazyMode flakinness under Linux.

I found two causes of flakinness:
 - SIGPROF signal isn't delivered to a process;
 - Profiler thread (the one that retrieves tick events from
   the queue and writes to log) doesn't get a CPU;
Both are fixed.

The script from bug description with run count increased to 200 runs without any test failures.

OS X and Windows are unaffected because they don't use signals mechanism.

BUG=http://code.google.com/p/v8/issues/detail?id=410
TEST=see bug description

Review URL: http://codereview.chromium.org/159406


git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2547 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 25eb4425
......@@ -144,6 +144,26 @@ class LoggerTestHelper : public AllStatic {
using v8::internal::LoggerTestHelper;
// Under Linux, we need to check if signals were delivered to avoid false
// positives. Under other platforms profiling is done via a high-priority
// thread, so this case never happen.
static bool was_sigprof_received = true;
#ifdef __linux__
#include <signal.h>
#include <unistd.h>
struct sigaction old_sigprof_handler;
static void SigProfSignalHandler(int signal, siginfo_t* info, void* context) {
if (signal != SIGPROF) return;
was_sigprof_received = true;
old_sigprof_handler.sa_sigaction(signal, info, context);
}
#endif // __linux__
static int CheckThatProfilerWorks(int log_pos) {
Logger::ResumeProfiler();
CHECK(LoggerTestHelper::IsSamplerActive());
......@@ -160,6 +180,18 @@ static int CheckThatProfilerWorks(int log_pos) {
const char* code_creation = "\ncode-creation,"; // eq. to /^code-creation,/
CHECK_NE(NULL, strstr(buffer.start(), code_creation));
#ifdef __linux__
// Intercept SIGPROF handler to make sure that the test process
// had received it. Under load, system can defer it causing test failure.
// It is important to execute this after 'ResumeProfiler'.
was_sigprof_received = false;
struct sigaction sa;
sa.sa_sigaction = SigProfSignalHandler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_SIGINFO;
CHECK_EQ(0, sigaction(SIGPROF, &sa, &old_sigprof_handler));
#endif // __linux__
// Force compiler to generate new code by parametrizing source.
EmbeddedVector<char, 100> script_src;
i::OS::SNPrintF(script_src,
......@@ -170,6 +202,8 @@ static int CheckThatProfilerWorks(int log_pos) {
const double end_time = i::OS::TimeCurrentMillis() + 200;
while (i::OS::TimeCurrentMillis() < end_time) {
CompileAndRunScript(script_src.start());
// Yield CPU to give Profiler thread a chance to process ticks.
i::OS::Sleep(1);
}
Logger::PauseProfiler();
......@@ -189,7 +223,8 @@ static int CheckThatProfilerWorks(int log_pos) {
buffer[log_size] = '\0';
const char* tick = "\ntick,";
CHECK_NE(NULL, strstr(buffer.start(), code_creation));
CHECK_NE(NULL, strstr(buffer.start(), tick));
const bool ticks_found = strstr(buffer.start(), tick) != NULL;
CHECK_EQ(was_sigprof_received, ticks_found);
return log_pos;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment