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
-~----------~----~----~----~------~----~------~--~---

Reply via email to