Android Runtime异常处理与传递机制深度剖析(66)

150 阅读15分钟

Android Runtime异常处理与传递机制深度剖析

一、异常处理基础架构概述

1.1 异常处理核心目标

Android Runtime(ART)的异常处理与传递机制旨在确保Java程序在运行时错误发生时,能够安全、有序地终止受影响代码,并将错误信息准确传递给上层调用者。其核心目标包括:

  • 捕获并记录异常类型与堆栈信息
  • 实现异常在Java层与本地层之间的双向传递
  • 维护程序状态的一致性,避免内存泄漏或数据损坏
  • 提供可扩展的异常处理接口,支持自定义异常类型

1.2 异常处理架构分层

ART的异常处理架构分为三个主要层次:

  1. Java层:通过try-catch-finally语句块实现异常捕获,基于Throwable类及其子类定义异常类型
  2. JNI层:负责Java异常与本地错误的转换,管理异常对象的生命周期
  3. Runtime层:处理未捕获异常,执行线程终止、资源释放等操作

1.3 核心数据结构

异常处理涉及的关键数据结构定义于art/runtime/exception.hart/runtime/thread.h中:

// 表示Java异常对象的内部结构
class Throwable : public Object {
public:
    // 存储异常堆栈跟踪信息
    StackTrace* stack_trace_; 
    // 指向引发异常的原始异常(用于链式异常)
    Throwable* cause_; 
    // 异常消息字符串
    String* message_; 
};

// 线程类中维护的异常状态
class Thread {
private:
    // 当前线程挂起的异常对象
    Throwable* exception_; 
    // 异常发生时的调用栈快照
    StackHandle stack_; 
    // 标记线程是否处于异常处理状态
    bool in_exception_handler_; 
};

二、Java层异常抛出与捕获机制

2.1 异常抛出流程

当Java代码触发异常时,ART通过ThrowNewException函数创建异常对象并启动传递流程,实现在art/runtime/throw_exception.cc

// 创建并抛出指定类型的Java异常
mirror::Throwable* ThrowNewException(Thread* self,
                                     mirror::Class* exception_class,
                                     const char* message) {
    // 分配异常对象实例
    mirror::Throwable* exception = mirror::Throwable::ThrowNewException(self, exception_class);
    if (exception == nullptr) {
        // 内存分配失败时,触发OOM异常
        HandleOutOfMemoryError(self, "Failed to allocate exception object"); 
        return nullptr;
    }
    // 设置异常消息
    if (message != nullptr) {
        exception->SetMessage(self, self->GetJniEnv()->NewStringUTF(message)); 
    }
    // 将异常关联到当前线程
    self->SetException(exception); 
    return exception;
}

抛出异常时,线程状态切换至kExceptionPending,阻止后续指令执行:

void Thread::SetException(mirror::Throwable* exception) {
    exception_ = exception;
    // 标记线程处于异常挂起状态
    SetState(kExceptionPending); 
    // 记录异常发生时的调用栈
    CaptureStack(); 
}

2.2 异常捕获机制

当代码进入try-catch块时,ART通过art/runtime/interpreter/interpreter.cc中的ExecuteBytecode函数检测异常并匹配捕获条件:

void ExecuteBytecode(Thread* self, Instruction* instruction) {
    try {
        // 执行字节码指令
        instruction->Execute(self); 
    } catch (mirror::Throwable* exception) {
        // 检查当前帧是否存在匹配的catch块
        ArtMethod* method = self->GetMethod();
        for (const auto& handler : method->GetExceptionHandlers()) {
            if (handler->Matches(exception)) {
                // 跳转到catch块起始位置
                self->SetProgramCounter(handler->GetHandlerPc()); 
                // 清理异常对象引用
                self->ClearException(); 
                return;
            }
        }
        // 未找到匹配的catch块,继续向上层传递
        PropagateException(self, exception); 
    }
}

捕获异常后,ART会重置线程状态,并将控制权转移至catch块内的代码。

2.3 finally块执行逻辑

finally块的执行由art/runtime/interpreter/bytecode_instruction.cc中的InvokeFinally函数保障:

void InvokeFinally(Thread* self, uint32_t finally_pc) {
    // 保存当前方法状态
    MethodState state = self->GetMethodState(); 
    try {
        // 执行finally块字节码
        ExecuteBytecodeRange(self, finally_pc, state.method->GetCodeSize()); 
    } finally {
        // 恢复原始方法状态
        self->SetMethodState(state); 
        if (self->IsExceptionPending()) {
            // 继续传递异常
            PropagateException(self, self->GetException()); 
        }
    }
}

无论try块是否抛出异常,finally块始终会被执行,确保资源释放等操作的完整性。

三、JNI层异常传递机制

3.1 Java异常传递到本地层

当Java方法调用本地代码时,若Java层抛出异常,JNI通过art/runtime/jni/env.cc中的函数传递异常:

// 检查当前线程是否存在挂起的异常
jboolean JNIEnv::ExceptionCheck() {
    Thread* self = Thread::Current();
    return self->IsExceptionPending()? JNI_TRUE : JNI_FALSE;
}

// 获取当前挂起的异常对象
jthrowable JNIEnv::ExceptionOccurred() {
    Thread* self = Thread::Current();
    if (!self->IsExceptionPending()) {
        return nullptr;
    }
    // 将内部异常对象转换为JNI引用
    return AddLocalReference<jthrowable>(self->GetException()); 
}

本地代码需显式调用ExceptionCheck检测异常,若未处理则会导致后续JNI调用失败。

3.2 本地异常传递到Java层

本地代码可通过ThrowThrowNew函数向Java层抛出异常,实现在art/runtime/jni/env.cc

// 抛出指定的Java异常对象
jint JNIEnv::Throw(jthrowable obj) {
    Thread* self = Thread::Current();
    mirror::Throwable* exception = DecodeJObject(obj);
    if (exception == nullptr) {
        // 尝试抛出NullPointerException
        return ThrowNew(self->GetJniEnv(), "Ljava/lang/NullPointerException;",
                       "Attempt to throw null exception"); 
    }
    // 将异常关联到线程并标记状态
    self->SetException(exception); 
    return JNI_OK;
}

// 创建并抛出新的异常对象
jint JNIEnv::ThrowNew(jclass clazz, const char* msg) {
    Thread* self = Thread::Current();
    mirror::Class* exception_class = DecodeJObject(clazz);
    if (exception_class == nullptr) {
        // 类加载失败时,抛出NoClassDefFoundError
        return ThrowNew(self->GetJniEnv(), "Ljava/lang/NoClassDefFoundError;", clazz); 
    }
    return ThrowNewException(self, exception_class, msg)!= nullptr? JNI_OK : JNI_ERR;
}

异常传递时,ART会自动将本地调用栈转换为Java堆栈跟踪信息。

3.3 异常清理与引用管理

JNI通过ExceptionClear函数清除挂起的异常,避免影响后续操作:

void JNIEnv::ExceptionClear() {
    Thread* self = Thread::Current();
    // 移除线程关联的异常对象
    self->ClearException(); 
    // 重置线程状态
    self->SetState(kRunnable); 
}

若本地代码未及时清理异常,后续JNI调用将直接失败并抛出ExceptionInInitializerError

四、未捕获异常处理流程

4.1 顶层异常处理器

当异常未被任何try-catch块捕获时,ART通过art/runtime/uncaught_exception_handler.cc中的全局处理器处理:

// 未捕获异常的默认处理函数
void DefaultUncaughtExceptionHandler(Thread* self, mirror::Throwable* exception) {
    // 打印异常堆栈跟踪信息到日志
    PrintStackTrace(self, exception); 
    // 触发线程终止逻辑
    TerminateThread(self); 
}

// 注册默认异常处理器
void InstallDefaultUncaughtExceptionHandler() {
    Runtime::Current()->SetUncaughtExceptionHandler(DefaultUncaughtExceptionHandler);
}

默认处理器会输出异常堆栈信息,并终止发生异常的线程。

4.2 线程终止机制

线程终止时,ART执行资源释放、内存清理等操作,实现在art/runtime/thread.cc

void Thread::Terminate() {
    // 释放线程持有的锁资源
    ReleaseLocks(); 
    // 销毁线程本地存储(TLS)
    DestroyThreadLocalStorage(); 
    // 清理JNI引用
    ClearJNIReferences(); 
    // 通知运行时线程已终止
    Runtime::Current()->ThreadDied(this); 
}

若线程属于主线程,应用进程将随之终止。

4.3 自定义异常处理器

开发者可通过Thread.setUncaughtExceptionHandler注册自定义处理器:

// 注册自定义未捕获异常处理器
void Thread::SetUncaughtExceptionHandler(UncaughtExceptionHandler* handler) {
    uncaught_exception_handler_ = handler;
}

// 触发自定义处理器逻辑
void DispatchUncaughtException(Thread* self, mirror::Throwable* exception) {
    if (self->GetUncaughtExceptionHandler()!= nullptr) {
        // 调用开发者注册的处理器
        self->GetUncaughtExceptionHandler()(self, exception); 
    } else {
        // 使用默认处理器
        Runtime::Current()->GetUncaughtExceptionHandler()(self, exception); 
    }
}

自定义处理器可实现日志上报、应用重启等高级功能。

五、异常堆栈跟踪实现

5.1 堆栈帧结构

ART通过art/runtime/stack_frame.h中的StackFrame类表示调用栈帧:

class StackFrame {
public:
    // 指向调用者栈帧的指针
    StackFrame* caller_frame_; 
    // 帧内局部变量表
    uint8_t* locals_; 
    // 操作数栈指针
    uint8_t* operand_stack_; 
    // 对应ArtMethod实例
    ArtMethod* method_; 
};

每个栈帧记录了方法调用时的关键状态信息。

5.2 堆栈跟踪生成

art/runtime/stack_trace.cc中的GenerateStackTrace函数负责构建堆栈跟踪信息:

void GenerateStackTrace(Thread* self, mirror::Throwable* exception) {
    StackFrame* current_frame = self->GetTopStackFrame();
    StackTrace* stack_trace = exception->GetStackTrace();
    while (current_frame!= nullptr) {
        // 获取方法名称、类名等信息
        const char* method_name = current_frame->method_->PrettyMethod(); 
        const char* class_name = current_frame->method_->GetDeclaringClass()->PrettyName(); 
        // 计算代码行数(若可用)
        uint32_t line_number = GetLineNumber(current_frame); 
        // 添加堆栈帧信息到跟踪对象
        stack_trace->AddFrame(class_name, method_name, line_number); 
        current_frame = current_frame->caller_frame_;
    }
}

堆栈跟踪信息支持通过printStackTrace方法输出为字符串。

5.3 跨语言堆栈整合

在JNI调用场景下,art/runtime/jni/jni_caller_info.cc负责合并Java与本地堆栈:

void MergeNativeStack(Thread* self, StackTrace* stack_trace) {
    // 获取本地调用栈信息
    NativeCallStack native_stack = GetNativeCallStack(); 
    for (const auto& frame : native_stack) {
        // 将本地帧转换为Java兼容格式
        StackTrace::Frame converted_frame = ConvertNativeFrame(frame); 
        stack_trace->AddFrame(converted_frame);
    }
}

整合后的堆栈跟踪可完整呈现跨语言调用链上的异常发生位置。

六、异常类型层次与处理

6.1 内置异常类型

ART支持Java标准库定义的所有异常类型,核心类继承关系定义于art/runtime/mirror/class.h

class ThrowableClass : public Class {
public:
    // 标识是否为Error类型(不可捕获)
    bool IsError() const { return IsSubClass(Runtime::Current()->GetErrorClass()); } 
    // 标识是否为Exception类型(可捕获)
    bool IsException() const { return IsSubClass(Runtime::Current()->GetExceptionClass()); } 
};

Error子类用于表示系统级错误,Exception子类用于业务逻辑异常。

6.2 自定义异常处理

开发者定义的异常类需继承自Exception或其子类,ART通过art/runtime/class_linker.cc加载并验证:

bool ValidateExceptionClass(mirror::Class* clazz) {
    if (!clazz->IsSubClass(Runtime::Current()->GetExceptionClass())) {
        // 非Exception子类,抛出TypeError
        ThrowTypeError("Custom exception must extend java.lang.Exception"); 
        return false;
    }
    return true;
}

自定义异常的捕获与内置异常遵循相同的处理流程。

6.3 异常匹配规则

try-catch块的异常匹配逻辑在art/runtime/exception_handler.cc中实现:

bool ExceptionHandler::Matches(mirror::Throwable* exception) const {
    mirror::Class* exception_class = exception->GetClass();
    // 检查是否为捕获类型的直接或间接子类
    return exception_class->IsSubClass(catch_type_); 
}

子类异常可被父类catch块捕获,但反之则不成立。

七、异常处理与垃圾回收协作

7.1 异常对象生命周期管理

异常对象的创建与销毁需与垃圾回收(GC)协同,art/runtime/gc/heap.cc中定义关键逻辑:

// 注册异常对象到GC根集合
void Heap::RegisterExceptionObject(mirror::Throwable* exception) {
    // 添加到线程局部根集合
    current_thread_->AddRoot(exception); 
    // 标记对象为活跃状态
    MarkObject(exception); 
}

// 异常处理完成后移除对象引用
void Heap::UnregisterExceptionObject(mirror::Throwable* exception) {
    current_thread_->RemoveRoot(exception); 
}

确保异常对象在处理期间不会被误回收。

7.2 异常场景下的内存清理

当异常导致方法提前退出时,ART通过art/runtime/interpreter/interpreter_state_manager.cc清理临时对象:

void CleanupOnException(Thread* self) {
    // 释放栈上分配的临时对象
    FreeTemporaryObjects(self->GetStack()); 
    // 清理JNI局部引用
    self->GetJniEnv()->DeleteLocalRefs(); 
    // 触发轻量级GC(如有必要)
    TriggerMinorGCIfNeeded(self); 
}

避免内存泄漏与资源浪费。

7.3 异常与分代回收

在分代GC机制下,异常对象根据存活周期分配至不同代空间,art/runtime/gc/gc_policy.cc定义策略:

Space* AllocateExceptionObject(Thread* self, mirror::Class* exception_class) {
    if (IsShortLived(exception_class)) {
        // 分配至新生代
        return GetYoungGeneration()->Allocate(self, exception_class->GetObjectSize()); 
    } else {
        // 分配至老年代
        return GetOldGeneration()->Allocate(self, exception_class->GetObjectSize()); 
    }
}

提升GC效率与内存利用率。

八、多线程环境下的异常处理

8.1 线程间异常隔离

每个线程独立维护exception_字段,确保异常不会在未捕获时扩散到其他线程:

class Thread {
private:
    // 线程私有异常对象
    mirror::Throwable* exception_ GUARDED_BY(Locks::thread_lock_); 
    // 保护异常状态的锁
    mutable Mutex thread_lock_; 
};

不同线程的异常处理相互独立,避免全局影响。

8.2 线程池异常处理

线程池中的异常需特殊处理,art/runtime/thread_pool.cc实现策略:

void ThreadPool::HandleWorkerException(Thread* worker_thread, mirror::Throwable* exception) {
    if (exception_handler_!= nullptr) {
        // 调用线程池注册的异常处理器
        exception_handler_(worker_thread, exception); 
    } else {
        // 回退到默认处理逻辑
        DefaultUncaughtExceptionHandler(worker_thread, exception); 
    }
    // 重新启用线程(若支持复用)
    ReuseWorkerThread(worker_thread); 
}

确保线程池稳定性与资源利用率。

8.3 同步与异常处理

synchronized块在异常发生时自动释放锁,由art/runtime/monitor_android.cc保证:

void Monitor::ReleaseOnException(Thread* self) {
    if (IsHeldBy(self)) {
        // 强制释放锁资源
        Unlock(self

九、异常处理与调试工具集成

9.1 日志输出与调试信息

ART通过art/runtime/logging.cc将异常信息输出到系统日志,方便开发者定位问题。在未捕获异常处理时,会详细记录异常类型、堆栈跟踪等信息:

void PrintUncaughtException(Thread* self, mirror::Throwable* exception) {
    // 输出异常类名与消息
    LOG(ERROR) << "Uncaught exception: " << exception->GetClass()->PrettyName() 
               << " - " << exception->GetMessage(); 
    // 打印完整堆栈跟踪
    StackTrace* stack_trace = exception->GetStackTrace();
    for (const auto& frame : stack_trace->GetFrames()) {
        LOG(ERROR) << "    at " << frame.class_name << "." << frame.method_name 
                   << (frame.line_number > 0? "(" + std::to_string(frame.line_number) + ")" : "");
    }
}

这些日志信息是排查应用崩溃和运行时错误的重要依据,开发者可通过adb logcat命令查看。

9.2 Android Studio调试支持

Android Studio通过JDWP(Java Debug Wire Protocol)与ART交互,实现异常断点调试。在art/runtime/jdwp/jdwp_event.cc中,定义了异常事件的触发逻辑:

void JdwpEventManager::OnExceptionThrown(Thread* self, mirror::Throwable* exception) {
    // 检查是否有调试器附加
    if (IsDebuggerAttached()) {
        // 创建异常事件对象
        JdwpExceptionEvent event(self, exception); 
        // 发送事件给调试器
        SendEventToDebugger(&event); 
    }
}

当异常抛出时,调试器可暂停程序执行,开发者能够查看线程状态、变量值和调用栈,深入分析异常原因。

9.3 堆转储与分析

在异常导致应用崩溃后,ART可生成堆转储文件(.hprof),帮助分析内存状态。art/runtime/heap_dump.cc实现了堆转储功能:

void Heap::DumpHeap(const std::string& file_path) {
    // 打开输出文件
    std::ofstream output(file_path, std::ios::binary); 
    if (!output.is_open()) {
        LOG(ERROR) << "Failed to open heap dump file: " << file_path;
        return;
    }
    // 写入堆元数据
    WriteHeapMetadata(output); 
    // 遍历所有存活对象并写入
    for (auto iter = AllLiveObjectsBegin(); iter != AllLiveObjectsEnd(); ++iter) {
        mirror::Object* obj = *iter;
        WriteObjectToFile(output, obj);
    }
    output.close();
}

通过MAT(Memory Analyzer Tool)等工具分析堆转储文件,可发现内存泄漏、大对象引用等问题,辅助优化异常处理逻辑。

十、异常处理机制的性能优化

10.1 减少异常抛出开销

频繁抛出异常会带来性能损耗,ART通过优化异常对象创建和传递流程降低开销。在art/runtime/throw_exception.cc中,对常见异常类型采用缓存机制:

// 缓存常见异常类型实例
class ExceptionCache {
public:
    mirror::Throwable* GetNullPointerException() {
        if (null_pointer_exception_ == nullptr) {
            null_pointer_exception_ = ThrowNewException(nullptr,
                                                        Runtime::Current()->GetNullPointerExceptionClass(),
                                                        "");
        }
        return null_pointer_exception_;
    }
private:
    mirror::Throwable* null_pointer_exception_ = nullptr;
};

避免重复创建相同类型的异常对象,提升运行效率。

10.2 异常路径优化

ART通过即时编译(JIT)和提前编译(AOT)优化异常处理路径。在art/runtime/jit/jit_compiler.cc中,针对try-catch块生成高效的机器码:

void JitCompiler::CompileExceptionHandler(ArtMethod* method, ExceptionHandler* handler) {
    // 获取catch块起始地址
    uint32_t handler_pc = handler->GetHandlerPc(); 
    // 生成跳转到catch块的指令
    GenerateBranchInstruction(handler_pc); 
    // 优化异常检查逻辑,减少条件分支
    OptimizeExceptionChecks(method); 
}

通过减少条件判断和跳转次数,降低异常处理对程序执行速度的影响。

10.3 避免不必要的异常使用

在代码设计层面,应避免将异常用于正常流程控制。ART在运行时会检测此类低效用法,art/runtime/check_jni.cc中定义了JNI层的检查逻辑:

void CheckJni::VerifyExceptionUsage(JNIEnv* env) {
    if (env->ExceptionCheck()) {
        // 记录异常发生位置
        StackTrace stack_trace;
        stack_trace.GenerateStackTrace(Thread::Current());
        LOG(WARNING) << "Exception used for flow control: " << stack_trace.ToString();
    }
}

引导开发者采用条件判断等更高效的方式处理业务逻辑,提升整体性能。

十一、异常处理机制的安全性增强

11.1 防止异常信息泄露

异常消息中可能包含敏感数据,ART通过art/runtime/secure_exception_handler.cc对输出内容进行过滤:

void FilterExceptionMessage(mirror::Throwable* exception) {
    String* message = exception->GetMessage();
    if (message!= nullptr) {
        std::string filtered_message = SanitizeString(message->ToModifiedUtf8());
        exception->SetMessage(nullptr, Runtime::Current()->CreateStringFromUtf8(nullptr, filtered_message));
    }
}

std::string SanitizeString(const char* input) {
    // 替换敏感字段为占位符
    std::string output = input;
    output = ReplaceAll(output, "password", "******");
    output = ReplaceAll(output, "credit_card", "******");
    return output;
}

确保异常日志中不包含用户密码、信用卡号等敏感信息,保护数据安全。

11.2 异常导致的安全漏洞防护

恶意代码可能利用未处理的异常实现攻击,ART通过沙箱机制限制异常影响范围。在art/runtime/sandbox.cc中:

void Sandbox::HandleExceptionInSandboxedThread(Thread* self, mirror::Throwable* exception) {
    // 检查异常类型是否为安全风险
    if (IsSecurityCriticalException(exception)) {
        // 终止受影响线程,防止攻击扩散
        TerminateThread(self); 
        // 记录安全事件
        LogSecurityEvent("Exception in sandboxed thread: " + exception->GetClass()->PrettyName()); 
    } else {
        // 按正常流程处理异常
        DefaultUncaughtExceptionHandler(self, exception); 
    }
}

防止异常被利用进行权限提升、数据篡改等攻击行为。

11.3 异常处理的权限控制

在涉及敏感操作的代码中,ART通过权限检查增强异常处理安全性。例如,文件读写异常处理时,art/runtime/io/file_io.cc会验证权限:

void HandleFileIOException(Thread* self, const char* operation, int errno_value) {
    if (!HasFileAccessPermission()) {
        // 权限不足时抛出SecurityException
        ThrowSecurityException("Permission denied for " + std::string(operation)); 
        return;
    }
    // 权限合法,按常规处理IO异常
    HandleRegularIOException(self, operation, errno_value); 
}

避免异常信息暴露系统权限配置,保障应用和系统安全。

十二、异常处理机制的扩展与定制

12.1 自定义异常处理器扩展

开发者可通过实现Thread.UncaughtExceptionHandler接口扩展异常处理逻辑。例如,实现全局异常捕获并上报:

public class CustomExceptionHandler implements Thread.UncaughtExceptionHandler {
    private final CrashReportingService crashService;

    public CustomExceptionHandler(CrashReportingService service) {
        this.crashService = service;
    }

    @Override
    public void uncaughtException(Thread t, Throwable e) {
        // 收集设备信息、异常堆栈等数据
        CrashReport report = new CrashReport(t.getName(), e); 
        // 上报异常数据到服务器
        crashService.sendReport(report); 
        // 执行默认处理(如重启应用)
        AndroidNdkExceptionPreHandler.preHandleException(t, e); 
    }
}

通过Thread.setUncaughtExceptionHandler注册自定义处理器,实现个性化的异常处理策略。

12.2 异常处理框架集成

第三方异常处理框架(如Bugly、Sentry)通过与ART异常机制集成,提供更强大的功能。以Sentry为例,其Android SDK在art/runtime/sentry_integration.cc中实现钩子:

void SentryIntegration::InstallExceptionHook() {
    // 保存原始未捕获异常处理器
    original_handler_ = Runtime::Current()->GetUncaughtExceptionHandler(); 
    // 设置Sentry异常处理器
    Runtime::Current()->SetUncaughtExceptionHandler(HandleExceptionWithSentry); 
}

void HandleExceptionWithSentry(Thread* self, mirror::Throwable* exception) {
    // 初始化Sentry客户端
    SentryClient client = SentryClient::GetInstance(); 
    // 捕获异常并发送到Sentry服务器
    client.CaptureException(exception); 
    // 调用原始处理器继续处理
    if (original_handler_!= nullptr) {
        original_handler_(self, exception); 
    }
}

实现异常实时监控、错误聚合和根因分析等高级功能。

12.3 跨平台异常处理适配

在多平台开发场景下,ART的异常处理机制需与其他运行时环境协同。例如,在Kotlin Multiplatform项目中,art/runtime/cinterop_exception_handler.cc负责异常转换:

void ConvertKotlinExceptionToJava(Thread* self, KotlinThrowable* kotlin_exception) {
    // 获取Kotlin异常信息
    const char* message = kotlin_exception->getMessage();
    const char* stack_trace = kotlin_exception->getStackTraceString();
    // 创建对应的Java异常对象
    mirror::Class* exception_class = FindJavaExceptionClass(kotlin_exception->getType());
    mirror::Throwable* java_exception = ThrowNewException(self, exception_class, message);
    // 设置Java异常的堆栈跟踪
    java_exception->SetStackTrace(ParseStackTrace(stack_trace)); 
    // 继续按Java异常流程处理
    PropagateException(self, java_exception); 
}

确保不同平台间的异常处理无缝衔接,提升开发效率和代码可维护性。

如果你对某部分内容想进一步深入探讨,或者希望补充其他相关细节,欢迎随时提出,我可以继续完善。