Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Open more actions menu

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Repro for invalid pthread_t 0x... passed to pthread_getcpuclockid

This is a repro of the abort seen in the following issue: getsentry/sentry-java#2604. It is based on a basic Android Studio app template. The only things that changed were the following:

  • text content and size of the centered TextView, which is clickable to trigger the repro.
  • the MainActivity starts the Android method tracer onCreate in background sampling mode (using the same parameters as the Android SDK).
  • an OnClickListener calling the native code that triggers the abort.

What happens in the native code?

  • The JNI function starts a native thread (appending it to the pthread thread list)

  • the native thread attaches to the ART (appending it to the ART thread list)

  • but exits before detaching (-> the thread remains in the ART thread list)

  • the JNI function joins that thread ( removing it from the pthread thread list)

    JavaVM *parent_vm = nullptr;
    env->GetJavaVM(&parent_vm);
    // create a single thread that attaches, but never detaches.
    auto t = std::thread([=] {
    JNIEnv *child_env = nullptr;
    parent_vm->GetEnv(reinterpret_cast<void **>(&child_env), JNI_VERSION_1_6);
    JavaVMAttachArgs args;
    args.version = JNI_VERSION_1_6;
    args.name = "non_detaching_thread";
    args.group = nullptr;
    // this adds the thread to the runtime thread-list, that
    // the tracer uses to sample all running runtime threads
    parent_vm->AttachCurrentThread(&child_env, &args);
    #if IGNORED
    parent_vm->DetachCurrentThread();
    #endif
    });
    // Join so that bionic removes this thread from the pthread thread-list. After join completion
    // the thread will still be in the runtime thread-list, leading tracer to sample a thread that
    // has no pthread equivalent. A `pthread_exit()` before Detach will achieve the same thing.
    t.join();

Why does that lead to an abort?

  • Calling pthread_exit() or pthread_join() before an attached thread could be detached is illegal.
  • But that doesn't necessarily mean that it will fail at that point.
  • Since the two thread lists are now out of sync, the ART method tracer will retrieve a thread from the ART thread list that is no longer maintained in pthread state
  • The first function requiring a look-up in the tracer sampling path seems to be pthread_getcpuclockid() [1], which aborts with a fatal log if the provided pthread_t cannot be found [2].

[1] https://cs.android.com/android/platform/superproject/main/+/main:bionic/libc/bionic/pthread_getcpuclockid.cpp;l=36

[2] https://cs.android.com/android/platform/superproject/main/+/main:bionic/libc/bionic/pthread_internal.cpp;l=119-130

About

A repro where the Android method tracer aborts, because a native dependency called pthread_[join|exit] before detaching.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages

Morty Proxy This is a proxified and sanitized view of the page, visit original site.