这是一次快速跟进发布,用于修复 17.22.1 中的一项回归,以及期间合入的另外几个问题。

我们在 17.22.1 中为 glibc 添加的栈丢弃逻辑,假定每个正在退出的线程都是由我们设置的。GLib 仅仅接管的线程——例如外部 pthread 调用 GLib 时——退出时仍会执行 finalize,但从未经过 realize,因此栈丢弃逻辑会解引用 NULL,并让进程随之崩溃。一个 frida-node 使用方在完成附加、加载脚本并退出后会死于 SIGSEGV;长时间运行的测试中,只要其中一个此类线程在运行途中退出,也会发生同样的问题。@hsorbo 修复了这个问题:没有可供处理的基础数据时跳过栈丢弃,并添加了一个测试,用于接管外部线程并让其退出。

Håvard 还修复了 QuickJS 分支中一个长期存在的问题。当循环收集器释放对象时,会释放所有以该对象为键的 WeakMap 条目值。这些值是扫描后仍存活的对象;如果这种释放使其中某个对象的引用计数降为零,它会因为运行时正忙于移除循环而被忽略,此后也不会再得到处理。它会以零引用计数一直留到运行时销毁,此时其终结器可能访问已经不存在的状态。现在,这类对象会收集到延迟列表中,并在循环移除结束后释放,与其他引用计数降为零的对象相同。

最后,@mbv06 注意到新版 ART 会把启动镜像的 methods 节复制到自己的 memfd 映射,因此 Android 启动支持现在还会在 boot-image-methods.art 中查找 setArgV0() JNI 槽位。

尽情使用吧!

变更日志

  • glibc:对接管的线程跳过栈丢弃,修复 17.22.1 引入的线程退出崩溃。感谢 @hsorbo!
  • quickjs:释放移除循环期间被释放的存活对象,使循环收集过程中通过 WeakMap 条目释放的值能够运行终结器,而不会一直残留到运行时销毁。感谢 @hsorbo!
  • android:在 boot-image-methods.art 中扫描 setArgV0() JNI 槽位,因为新版 ART 会单独映射启动镜像的 methods 节。感谢 @mbv06!