Skip to content

Fix jit crash caused by hooking intrinsic methods in bootclasspath on Android 15 and above #148

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

eirv
Copy link
Contributor

@eirv eirv commented Mar 31, 2025

This only happens on Android 15 and above, you can see intrinsics_list.h and instruction_builder.cc

signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0000000000000030
Cause: null pointer dereference
    x0  0000000000000000  x1  0000000000000002  x2  000000704ebe41e8  x3  0000006d8f97ed9d
    x4  000000704ebe4420  x5  0000000000000004  x6  0000006d8099d470  x7  7f7f7f7f7f7f7f7f
    x8  0000000000000010  x9  0000000000000020  x10 0000000000000019  x11 0000006d93a0ea80
    x12 0000006d9308d020  x13 000000000000001c  x14 0000000000000000  x15 0000000000000008
    x16 0000006d93a24d48  x17 000000703949a8c0  x18 0000006d7c2f4000  x19 000000704ebe41e8
    x20 000000704ebe23a0  x21 0000000000000002  x22 000000704ebe42b8  x23 0000000000000001
    x24 0000000000000000  x25 0000000000000000  x26 0000000000000000  x27 000000704ebe4498
    x28 0000000000000000  x29 0000006d8099d370
    lr  0000006d933361d0  sp  0000006d8099d370  pc  0000006d93336164  pst 0000000080001000

14 total frames
backtrace:
      #00 pc 0000000000336164  /apex/com.android.art/lib64/libart.so (art::Add(art::HInstructionList*, art::HBasicBlock*, art::HInstruction*) (.__uniq.147252545582089978308689827824377933333.llvm.7446156075945506185)+116) (BuildId: f09f55f58888db3fa9c586c60e5e1385)
      #01 pc 00000000002efcc8  /apex/com.android.art/lib64/libart.so (art::HInstructionBuilder::BuildInvoke(art::Instruction const&, unsigned int, unsigned int, art::InstructionOperands const&)+5772) (BuildId: f09f55f58888db3fa9c586c60e5e1385)
      #02 pc 00000000002e8f44  /apex/com.android.art/lib64/libart.so (art::HInstructionBuilder::ProcessDexInstruction(art::Instruction const&, unsigned int)+288) (BuildId: f09f55f58888db3fa9c586c60e5e1385)
      #03 pc 00000000002e83d8  /apex/com.android.art/lib64/libart.so (art::HInstructionBuilder::Build()+2804) (BuildId: f09f55f58888db3fa9c586c60e5e1385)
      #04 pc 00000000002b0f1c  /apex/com.android.art/lib64/libart.so (art::HGraphBuilder::BuildGraph()+424) (BuildId: f09f55f58888db3fa9c586c60e5e1385)
      #05 pc 000000000034b4c8  /apex/com.android.art/lib64/libart.so (art::OptimizingCompiler::TryCompile(art::ArenaAllocator*, art::ArenaStack*, art::DexCompilationUnit const&, art::ArtMethod*, art::CompilationKind, art::VariableSizedHandleScope*) const+3176) (BuildId: f09f55f58888db3fa9c586c60e5e1385)
      #06 pc 000000000034f220  /apex/com.android.art/lib64/libart.so (art::OptimizingCompiler::JitCompile(art::Thread*, art::jit::JitCodeCache*, art::jit::JitMemoryRegion*, art::ArtMethod*, art::CompilationKind, art::jit::JitLogger*)+1276) (BuildId: f09f55f58888db3fa9c586c60e5e1385)
      #07 pc 000000000029c54c  /apex/com.android.art/lib64/libart.so (art::jit::JitCompiler::CompileMethod(art::Thread*, art::jit::JitMemoryRegion*, art::ArtMethod*, art::CompilationKind)+636) (BuildId: f09f55f58888db3fa9c586c60e5e1385)
      #08 pc 000000000060d0c8  /apex/com.android.art/lib64/libart.so (art::jit::Jit::CompileMethodInternal(art::ArtMethod*, art::Thread*, art::CompilationKind, bool)+1024) (BuildId: f09f55f58888db3fa9c586c60e5e1385)
      #09 pc 0000000000618d54  /apex/com.android.art/lib64/libart.so (art::jit::JitCompileTask::Run(art::Thread*)+540) (BuildId: f09f55f58888db3fa9c586c60e5e1385)
      #10 pc 00000000008aa424  /apex/com.android.art/lib64/libart.so (art::ThreadPoolWorker::Run()+300) (BuildId: f09f55f58888db3fa9c586c60e5e1385)
      #11 pc 00000000008a9e34  /apex/com.android.art/lib64/libart.so (art::ThreadPoolWorker::Callback(void*)+180) (BuildId: f09f55f58888db3fa9c586c60e5e1385)
      #12 pc 0000000000072114  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+196) (BuildId: c39f57777755022581a2d51ce7f3bb68)
      #13 pc 0000000000064230  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+68) (BuildId: c39f57777755022581a2d51ce7f3bb68)

@@ -28,6 +28,9 @@ class ArtMethod {
inline static auto GetMethodShorty_ =
"_ZN3art15GetMethodShortyEP7_JNIEnvP10_jmethodID"_sym.as<const char *(JNIEnv *env, jmethodID mid)>;

inline static auto SetNotIntrinsic_ =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need another symbol here? SetNonCompilable just use SetAccessFlags for example.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the value of kAccIntrinsic may be modified in subsequent updates of ART, I call this function first.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use SetNotIntrinsic symbol since switching between intrinsic and non-intrinsic may affect many flags (kAccIntrinsicBits).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use SetNotIntrinsic symbol since switching between intrinsic and non-intrinsic may affect many flags (kAccIntrinsicBits).

Already resolved 25 minutes ago

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean just unsetting the kAccIntrinsic flag is not enough, because intrinsic methods use some other flag bits to store their type.

@aviraxp aviraxp requested a review from Copilot April 1, 2025 15:46
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review any files in this pull request.

Files not reviewed (2)
  • lsplant/src/main/jni/art/runtime/art_method.cxx: Language not supported
  • lsplant/src/main/jni/lsplant.cc: Language not supported

@yujincheng08 yujincheng08 requested review from aviraxp and Copilot and removed request for aviraxp May 8, 2025 12:11
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes a JIT crash on Android 15 and above that occurs when hooking intrinsic methods in the bootclasspath.

  • In lsplant.cc, a call to target->SetNonIntrinsic() is added to remove the intrinsic flag from the target method.
  • In art_method.cxx, a new SetNonIntrinsic() method is introduced and the intrinsic flag handling is adjusted based on Android API levels.

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
lsplant/src/main/jni/lsplant.cc Added target->SetNonIntrinsic() in DoHook to disable intrinsic optimizations.
lsplant/src/main/jni/art/runtime/art_method.cxx New SetNonIntrinsic() method and intrinsic flag handling for different SDK versions.

@@ -539,6 +539,8 @@ bool DoHook(ArtMethod *target, ArtMethod *hook, ArtMethod *backup) {
} else {
LOGV("Generated trampoline %p", entrypoint);

Copy link
Preview

Copilot AI May 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Consider adding a comment here to explain that removing the intrinsic flag is necessary to prevent a JIT crash on Android 15 and above.

Suggested change
// Removing the intrinsic flag is necessary to prevent a JIT crash on Android 15 and above.

Copilot uses AI. Check for mistakes.

dummy->SetAccessFlags(kAccIntrinsic);
SetNotIntrinsic_(dummy.get());
if (dummy->GetAccessFlags() == kAccIntrinsic) [[unlikely]] {
for (auto shift = 16U; 32U > shift; ++shift) {
Copy link
Preview

Copilot AI May 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Consider documenting the rationale behind the magic numbers (16U through 32U) used in the bit-shifting logic or replacing them with named constants to clarify their purpose.

Suggested change
for (auto shift = 16U; 32U > shift; ++shift) {
for (auto shift = kBitShiftStart; kBitShiftEnd > shift; ++shift) {

Copilot uses AI. Check for mistakes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants