Reviewers: Søren Gjesse, Description: Linux profiler: check whether signal handler is called in the VM thread.
I have several Chromium's core files having SIGPROF signal handler called in the context of an arbitrary thread, causing a crash. This change introduces checking of current thread in the signal handler. Please review this at http://codereview.chromium.org/171115 Affected files: M src/platform-linux.cc M test/cctest/test-log.cc Index: src/platform-linux.cc diff --git a/src/platform-linux.cc b/src/platform-linux.cc index 6ec5070f911c787973b838bc28d549ca5c29a730..1268a5403b6a57238bca89cd8eae1b40bbec321f 100644 --- a/src/platform-linux.cc +++ b/src/platform-linux.cc @@ -580,6 +580,7 @@ Semaphore* OS::CreateSemaphore(int count) { #ifdef ENABLE_LOGGING_AND_PROFILING static Sampler* active_sampler_ = NULL; +static pthread_t vm_thread_ = 0; #if !defined(__GLIBC__) && (defined(__arm__) || defined(__thumb__)) @@ -616,7 +617,8 @@ static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) { TickSample sample; // If profiling, we extract the current pc and sp. - if (active_sampler_->IsProfiling()) { + if (active_sampler_->IsProfiling() + && pthread_equal(pthread_self(), vm_thread_)) { // Extracting the sample from the context is extremely machine dependent. ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); mcontext_t& mcontext = ucontext->uc_mcontext; @@ -678,6 +680,8 @@ void Sampler::Start() { // platforms. if (active_sampler_ != NULL) return; + vm_thread_ = pthread_self(); + // Request profiling signals. struct sigaction sa; sa.sa_sigaction = ProfilerSignalHandler; Index: test/cctest/test-log.cc diff --git a/test/cctest/test-log.cc b/test/cctest/test-log.cc index 5884a419a9baede2ef1ce1a16881898b96ec3bf8..3e941d4f1c09303560f3025a1fa6602bb65403de 100644 --- a/test/cctest/test-log.cc +++ b/test/cctest/test-log.cc @@ -5,6 +5,7 @@ #ifdef ENABLE_LOGGING_AND_PROFILING #ifdef __linux__ +#include <pthread.h> #include <signal.h> #include <unistd.h> #endif @@ -155,9 +156,10 @@ static bool was_sigprof_received = true; #ifdef __linux__ struct sigaction old_sigprof_handler; +pthread_t our_thread; static void SigProfSignalHandler(int signal, siginfo_t* info, void* context) { - if (signal != SIGPROF) return; + if (signal != SIGPROF || !pthread_equal(pthread_self(), our_thread)) return; was_sigprof_received = true; old_sigprof_handler.sa_sigaction(signal, info, context); } @@ -185,6 +187,7 @@ static int CheckThatProfilerWorks(int log_pos) { // 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'. + our_thread = pthread_self(); was_sigprof_received = false; struct sigaction sa; sa.sa_sigaction = SigProfSignalHandler; --~--~---------~--~----~------------~-------~--~----~ v8-dev mailing list [email protected] http://groups.google.com/group/v8-dev -~----------~----~----~----~------~----~------~--~---
