TEST(libbacktrace, thread_multiple_dump) {
  // Dump NUM_THREADS simultaneously.
  std::vector<thread_t> runners(NUM_THREADS);
  std::vector<dump_thread_t> dumpers(NUM_THREADS);

  pthread_attr_t attr;
  pthread_attr_init(&attr);
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  for (size_t i = 0; i < NUM_THREADS; i++) {
    // Launch the runners, they will spin in hard loops doing nothing.
    runners[i].tid = 0;
    runners[i].state = 0;
    ASSERT_TRUE(pthread_create(&runners[i].threadId, &attr, ThreadMaxRun, &runners[i]) == 0);
  }

  // Wait for tids to be set.
  for (std::vector<thread_t>::iterator it = runners.begin(); it != runners.end(); ++it) {
    ASSERT_TRUE(WaitForNonZero(&it->state, 10));
  }

  // Start all of the dumpers at once, they will spin until they are signalled
  // to begin their dump run.
  int32_t dump_now = 0;
  for (size_t i = 0; i < NUM_THREADS; i++) {
    dumpers[i].thread.tid = runners[i].tid;
    dumpers[i].thread.state = 0;
    dumpers[i].done = 0;
    dumpers[i].now = &dump_now;

    ASSERT_TRUE(pthread_create(&dumpers[i].thread.threadId, &attr, ThreadDump, &dumpers[i]) == 0);
  }

  // Start all of the dumpers going at once.
  android_atomic_acquire_store(1, &dump_now);

  for (size_t i = 0; i < NUM_THREADS; i++) {
    ASSERT_TRUE(WaitForNonZero(&dumpers[i].done, 10));

    // Tell the runner thread to exit its infinite loop.
    android_atomic_acquire_store(0, &runners[i].state);

    ASSERT_TRUE(dumpers[i].backtrace != NULL);
    VerifyMaxDump(dumpers[i].backtrace);

    delete dumpers[i].backtrace;
    dumpers[i].backtrace = NULL;
  }
}
TEST(libbacktrace, thread_ignore_frames) {
  pthread_attr_t attr;
  pthread_attr_init(&attr);
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

  thread_t thread_data = { 0, 0, 0 };
  pthread_t thread;
  ASSERT_TRUE(pthread_create(&thread, &attr, ThreadLevelRun, &thread_data) == 0);

  // Wait up to 2 seconds for the tid to be set.
  ASSERT_TRUE(WaitForNonZero(&thread_data.state, 2));

  UniquePtr<Backtrace> all(Backtrace::Create(getpid(), thread_data.tid));
  ASSERT_TRUE(all.get() != NULL);
  ASSERT_TRUE(all->Unwind(0));

  UniquePtr<Backtrace> ign1(Backtrace::Create(getpid(), thread_data.tid));
  ASSERT_TRUE(ign1.get() != NULL);
  ASSERT_TRUE(ign1->Unwind(1));

  UniquePtr<Backtrace> ign2(Backtrace::Create(getpid(), thread_data.tid));
  ASSERT_TRUE(ign2.get() != NULL);
  ASSERT_TRUE(ign2->Unwind(2));

  VerifyIgnoreFrames(all.get(), ign1.get(), ign2.get(), NULL);

  // Tell the thread to exit its infinite loop.
  android_atomic_acquire_store(0, &thread_data.state);
}
Пример #3
0
TEST(libbacktrace, thread_ignore_frames) {
  pthread_attr_t attr;
  pthread_attr_init(&attr);
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

  thread_t thread_data = { 0, 0, 0 };
  pthread_t thread;
  ASSERT_TRUE(pthread_create(&thread, &attr, ThreadLevelRun, &thread_data) == 0);

  // Wait up to 2 seconds for the tid to be set.
  ASSERT_TRUE(WaitForNonZero(&thread_data.state, 2));

  backtrace_context_t all;
  ASSERT_TRUE(backtrace_create_context(&all, getpid(), thread_data.tid, 0));

  backtrace_context_t ign1;
  ASSERT_TRUE(backtrace_create_context(&ign1, getpid(), thread_data.tid, 1));

  backtrace_context_t ign2;
  ASSERT_TRUE(backtrace_create_context(&ign2, getpid(), thread_data.tid, 2));

  VerifyIgnoreFrames(all.backtrace, ign1.backtrace, ign2.backtrace, NULL);

  backtrace_destroy_context(&all);
  backtrace_destroy_context(&ign1);
  backtrace_destroy_context(&ign2);

  // Tell the thread to exit its infinite loop.
  android_atomic_acquire_store(0, &thread_data.state);
}
TEST(libbacktrace, thread_level_trace) {
  pthread_attr_t attr;
  pthread_attr_init(&attr);
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

  thread_t thread_data = { 0, 0, 0 };
  pthread_t thread;
  ASSERT_TRUE(pthread_create(&thread, &attr, ThreadLevelRun, &thread_data) == 0);

  // Wait up to 2 seconds for the tid to be set.
  ASSERT_TRUE(WaitForNonZero(&thread_data.state, 2));

  // Save the current signal action and make sure it is restored afterwards.
  struct sigaction cur_action;
  ASSERT_TRUE(sigaction(SIGURG, NULL, &cur_action) == 0);

  UniquePtr<Backtrace> backtrace(Backtrace::Create(getpid(), thread_data.tid));
  ASSERT_TRUE(backtrace.get() != NULL);
  ASSERT_TRUE(backtrace->Unwind(0));

  VerifyLevelDump(backtrace.get());

  // Tell the thread to exit its infinite loop.
  android_atomic_acquire_store(0, &thread_data.state);

  // Verify that the old action was restored.
  struct sigaction new_action;
  ASSERT_TRUE(sigaction(SIGURG, NULL, &new_action) == 0);
  EXPECT_EQ(cur_action.sa_sigaction, new_action.sa_sigaction);
  EXPECT_EQ(cur_action.sa_flags, new_action.sa_flags);
}
void ThreadSetState(void* data) {
  thread_t* thread = reinterpret_cast<thread_t*>(data);
  android_atomic_acquire_store(1, &thread->state);
  volatile int i = 0;
  while (thread->state) {
    i++;
  }
}
Пример #6
0
status_t V4L2VideoNode::open()
{
    status_t status(NO_ERROR);
    status = V4L2DeviceBase::open();
    if (status == NO_ERROR)
        mState = DEVICE_OPEN;

    android_atomic_acquire_store(0,&mBuffersInDevice);
    return status;
}
void* ThreadDump(void* data) {
  dump_thread_t* dump = reinterpret_cast<dump_thread_t*>(data);
  while (true) {
    if (android_atomic_acquire_load(dump->now)) {
      break;
    }
  }

  // The status of the actual unwind will be checked elsewhere.
  dump->backtrace = Backtrace::Create(getpid(), dump->thread.tid);
  dump->backtrace->Unwind(0);

  android_atomic_acquire_store(1, &dump->done);

  return NULL;
}
Пример #8
0
 /*
  * this is called by our "fake" BpGraphicBufferProducer. We package the
  * data and reply Parcel and forward them to the calling thread.
  */
 virtual status_t transact(uint32_t code,
         const Parcel& data, Parcel* reply, uint32_t flags) {
     this->code = code;
     this->data = &data;
     this->reply = reply;
     android_atomic_acquire_store(0, &memoryBarrier);
     if (exitPending) {
         // if we've exited, we run the message synchronously right here
         handleMessage(Message(MSG_API_CALL));
     } else {
         barrier.close();
         looper->sendMessage(this, Message(MSG_API_CALL));
         barrier.wait();
     }
     return NO_ERROR;
 }
Пример #9
0
status_t V4L2VideoNode::close()
{
    status_t status(NO_ERROR);

    if (mState == DEVICE_STARTED) {
        stop();
    }
    if (!mBufferPool.isEmpty()) {
        destroyBufferPool();
    }

    status = V4L2DeviceBase::close();
    if (status == NO_ERROR)
        mState = DEVICE_CLOSED;

    android_atomic_acquire_store(0,&mBuffersInDevice);
    return status;
}
Пример #10
0
void* ThreadDump(void* data) {
  dump_thread_t* dump = reinterpret_cast<dump_thread_t*>(data);
  while (true) {
    if (android_atomic_acquire_load(dump->now)) {
      break;
    }
  }

  dump->context.data = NULL;
  dump->context.backtrace = NULL;

  // The status of the actual unwind will be checked elsewhere.
  backtrace_create_context(&dump->context, getpid(), dump->thread.tid, 0);

  android_atomic_acquire_store(1, &dump->done);

  return NULL;
}
TEST(libbacktrace, thread_max_trace) {
  pthread_attr_t attr;
  pthread_attr_init(&attr);
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

  thread_t thread_data = { 0, 0, 0 };
  pthread_t thread;
  ASSERT_TRUE(pthread_create(&thread, &attr, ThreadMaxRun, &thread_data) == 0);

  // Wait for the tid to be set.
  ASSERT_TRUE(WaitForNonZero(&thread_data.state, 2));

  UniquePtr<Backtrace> backtrace(Backtrace::Create(getpid(), thread_data.tid));
  ASSERT_TRUE(backtrace.get() != NULL);
  ASSERT_TRUE(backtrace->Unwind(0));

  VerifyMaxDump(backtrace.get());

  // Tell the thread to exit its infinite loop.
  android_atomic_acquire_store(0, &thread_data.state);
}
Пример #12
0
void MonoPipe::updateFrontAndNRPTS(int32_t newFront, int64_t newNextRdPTS)
{
    // Set the MSB of the update sequence number to indicate that there is a
    // multi-variable update in progress.  Use an atomic store with an "acquire"
    // barrier to make sure that the next operations cannot be re-ordered and
    // take place before the change to mUpdateSeq is commited..
    int32_t tmp = mUpdateSeq | 0x80000000;
    android_atomic_acquire_store(tmp, &mUpdateSeq);

    // Update mFront and mNextRdPTS
    mFront = newFront;
    mNextRdPTS = newNextRdPTS;

    // We are finished with the update.  Compute the next sequnce number (which
    // should be the old sequence number, plus one, and with the MSB cleared)
    // and then store it in mUpdateSeq using an atomic store with a "release"
    // barrier so our update operations cannot be re-ordered past the update of
    // the sequence number.
    tmp = (tmp + 1) & 0x7FFFFFFF;
    android_atomic_release_store(tmp, &mUpdateSeq);
}
Пример #13
0
TEST(libbacktrace, thread_max_trace) {
  pthread_attr_t attr;
  pthread_attr_init(&attr);
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

  thread_t thread_data = { 0, 0, 0 };
  pthread_t thread;
  ASSERT_TRUE(pthread_create(&thread, &attr, ThreadMaxRun, &thread_data) == 0);

  // Wait for the tid to be set.
  ASSERT_TRUE(WaitForNonZero(&thread_data.state, 2));

  backtrace_context_t context;

  ASSERT_TRUE(backtrace_create_context(&context, getpid(), thread_data.tid, 0));

  VerifyMaxDump(context.backtrace);

  backtrace_destroy_context(&context);

  // Tell the thread to exit its infinite loop.
  android_atomic_acquire_store(0, &thread_data.state);
}