Code Monkey home page Code Monkey logo

sliver's Introduction

APM 相关技术交流,欢迎加我微信 knight-ZXW

背景

通过StackVisitor实现堆栈抓取的实现DEMO, 方案细节见: https://blog.csdn.net/ByteDanceTech/article/details/119621240

API说明

兼容性测试

目前只在Google模拟器Android 9~13 64位设备 上测试通过,未进行其他版本、机型测试

变更历史

  • 修复在相同线程调用suspend导致卡死的问题 (2023-01-03)

TODO

  • 完善兼容性
  • API 完善,数据写入文件

sliver's People

Contributors

knight-zxw avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

sliver's Issues

你好,在Android13,小米手机上,运行demod的release版本,函数的指针地址有重复导致获取到重复的方法信息(问题必现),debug的apk正常

首次安装启动是正常的,第二次启动就会出现重复的方法
首次启动的 stack_methods 数组和
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 E 在当前线程获取调用栈
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 E stack_methods[0] = 513826097944
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 E stack_methods[1] = 513826090584
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 E stack_methods[2] = 513826090584
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 E stack_methods[3] = 513825995272
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 E stack_methods[4] = 1907603128
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 E stack_methods[5] = 1904142192
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 E stack_methods[6] = 1904142192
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 E stack_methods[7] = 1907484096
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 E stack_methods[8] = 1907486528
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 E stack_methods[9] = 1904979144
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 E stack_methods[10] = 1904181072
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 E stack_methods[11] = 1904181040
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 E stack_methods[12] = 1904352864
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 E stack_methods[13] = 1905622032
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 E stack_methods[14] = 1905626352
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 E stack_methods[15] = 1905626320
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 E stack_methods[16] = 1907483904
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 E stack_methods[17] = 1891454744
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 E stack_methods[18] = 1906723528
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 E stack_methods[19] = 1908015624
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 I
long[] com.zongheng.sliver.Sliver.nativeGetMethodStackTrace(java.lang.Thread, long)
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 I
void v1.d.b()
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 I
void v1.d.b()
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 I
void com.knightboost.sliver.demo.MainActivity.onCreate(android.os.Bundle)
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 I
void android.app.Activity.performCreate(android.os.Bundle, android.os.PersistableBundle)
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 I
void android.app.Instrumentation.callActivityOnCreate(android.app.Activity, android.os.Bundle)
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 I
void android.app.Instrumentation.callActivityOnCreate(android.app.Activity, android.os.Bundle)
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 I
android.app.Activity android.app.ActivityThread.performLaunchActivity(android.app.ActivityThread$ActivityClientRecord, android.content.Intent)
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 I
android.app.Activity android.app.ActivityThread.handleLaunchActivity(android.app.ActivityThread$ActivityClientRecord, android.app.servertransaction.PendingTransactionActions, android.content.Intent)
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 I
void android.app.servertransaction.LaunchActivityItem.execute(android.app.ClientTransactionHandler, android.os.IBinder, android.app.servertransaction.PendingTransactionActions)
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 I
void android.app.servertransaction.TransactionExecutor.executeCallbacks(android.app.servertransaction.ClientTransaction)
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 I
void android.app.servertransaction.TransactionExecutor.execute(android.app.servertransaction.ClientTransaction)
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 I
void android.app.ActivityThread$H.handleMessage(android.os.Message)
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 I
void android.os.Handler.dispatchMessage(android.os.Message)
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 I
boolean android.os.Looper.loopOnce(android.os.Looper, long, int)
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 I
void android.os.Looper.loop()
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 I
void android.app.ActivityThread.main(java.lang.String[])
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 I
java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 I
void com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run()
2023-06-14 14:43:14.627 26901-26901 sliver pid-26901 I
void com.android.internal.os.ZygoteInit.main(java.lang.String[])

第二次启动数据输出
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 E 在当前线程获取调用栈
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 E stack_methods[0] = 2663898288
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 E stack_methods[1] = 2663871912
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 E stack_methods[2] = 2663871912
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 E stack_methods[3] = 2663895072
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 E stack_methods[4] = 1907603128
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 E stack_methods[5] = 1904142192
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 E stack_methods[6] = 1904142192
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 E stack_methods[7] = 1907484096
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 E stack_methods[8] = 1907486528
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 E stack_methods[9] = 1904979144
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 E stack_methods[10] = 1904181072
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 E stack_methods[11] = 1904181040
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 E stack_methods[12] = 1904352864
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 E stack_methods[13] = 1905622032
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 E stack_methods[14] = 1905626352
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 E stack_methods[15] = 1905626320
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 E stack_methods[16] = 1907483904
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 E stack_methods[17] = 1891454744
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 E stack_methods[18] = 1906723528
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 E stack_methods[19] = 1908015624
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 I
long[] com.zongheng.sliver.Sliver.nativeGetMethodStackTrace(java.lang.Thread, long)
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 I
void v1.d.b()
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 I
void v1.d.b()
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 I
void com.knightboost.sliver.demo.MainActivity.onCreate(android.os.Bundle)
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 I
void android.app.Activity.performCreate(android.os.Bundle, android.os.PersistableBundle)
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 I
void android.app.Instrumentation.callActivityOnCreate(android.app.Activity, android.os.Bundle)
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 I
void android.app.Instrumentation.callActivityOnCreate(android.app.Activity, android.os.Bundle)
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 I
android.app.Activity android.app.ActivityThread.performLaunchActivity(android.app.ActivityThread$ActivityClientRecord, android.content.Intent)
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 I
android.app.Activity android.app.ActivityThread.handleLaunchActivity(android.app.ActivityThread$ActivityClientRecord, android.app.servertransaction.PendingTransactionActions, android.content.Intent)
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 I
void android.app.servertransaction.LaunchActivityItem.execute(android.app.ClientTransactionHandler, android.os.IBinder, android.app.servertransaction.PendingTransactionActions)
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 I
void android.app.servertransaction.TransactionExecutor.executeCallbacks(android.app.servertransaction.ClientTransaction)
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 I
void android.app.servertransaction.TransactionExecutor.execute(android.app.servertransaction.ClientTransaction)
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 I
void android.app.ActivityThread$H.handleMessage(android.os.Message)
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 I
void android.os.Handler.dispatchMessage(android.os.Message)
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 I
boolean android.os.Looper.loopOnce(android.os.Looper, long, int)
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 I
void android.os.Looper.loop()
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 I
void android.app.ActivityThread.main(java.lang.String[])
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 I
java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 I
void com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run()
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 I
void com.android.internal.os.ZygoteInit.main(java.lang.String[])
2023-06-14 14:46:31.365 27568-27597 ost.sliver.demo pid-27568 D
MiuiProcessManagerServiceStub setSchedFifo
2023-06-14 14:46:39.227 27568-27595 ost.sliver.demo com.knightboost.sliver.demo

1 可以看出
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 E stack_methods[1] = 2663871912
2023-06-14 14:46:31.292 27568-27568 sliver pid-27568 E stack_methods[2] = 2663871912
这获取到的函数的指针地址有重复的,但是我并没有同一个方法调用两次

2 通过第一次函数的指针地址数组上看,自己写的类返回函数的指针的长度是12位,比如513826097944;但是非首次启动就获取不到长度为12位的函数指针;

在部分Android12 机型上会崩溃

#00 pc 0x00000000003aa704 /apex/com.android.art/lib64/libart.so (art::ThreadList::SuspendThreadByThreadId(unsigned int, art::SuspendReason, bool*)+476)
3KVagKS7J-eSYpicWVYcjA==/lib/arm64/libsliver.so (Java_com_knightboost_sliver_Sliver_nativeGetMethodStackTrace+204)

获取的堆栈中多了一些runtimeMethod方法

获取的堆栈中多了一些runtimeMethod方法:

<runtime method>.<runtime internal callee-save reference and argument registers method>

bool FetchStackVisitor::VisitFrame() {
  void *method = ArtHelper::GetCurMethodOfVisitor(this);
  auto *artMethod = static_cast<ArtMethod *>(method);
// 按照我的理解, 应该是在这里会过滤runtime Method, 不过目前没有生效
  if (artMethod == nullptr || artMethod->IsRuntimeMethod()) {
    return true;
  }
        at android.graphics.HardwareRenderer.nSyncAndDrawFrame
        at android.graphics.HardwareRenderer.syncAndDrawFrame
        at android.view.ThreadedRenderer.draw
        at android.view.ViewRootImpl.draw
        at android.view.ViewRootImpl.performDraw
        at android.view.ViewRootImpl.performTraversals
        at android.view.ViewRootImpl.doTraversal
        at android.view.ViewRootImpl$TraversalRunnable.run
        at android.view.Choreographer$CallbackRecord.run
        at android.view.Choreographer.doCallbacks
        at android.view.Choreographer.doFrame
        at android.view.Choreographer$FrameDisplayEventReceiver.run
        at android.os.Handler.handleCallback
        at android.os.Handler.dispatchMessage
        at android.os.Looper.loop
        at android.app.ActivityThread.main
        at <runtime method>.<runtime internal callee-save reference and argument registers method>
        at java.lang.reflect.Method.invoke
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run
        at <runtime method>.<runtime internal callee-save reference and argument registers method>
        at com.android.internal.os.ZygoteInit.main

你好,我这边试了一下,发现Android 12 系统有几个机型调用SuspendThreadByThreadId会报错

你好,我这边试了一下,发现Android 12 系统有几个机型调用SuspendThreadByThreadId会报错,分别是:

机型:HONOR/FNE-NX9 Android 12,level 31 aarch64
SIGSEGV(SEGV_MAPERR)
#00 pc 00000000001ab550 /apex/com.android.art/lib64/libart.so (art::ThreadList::SuspendThreadByThreadId(unsigned int, art::SuspendReason, bool*)+464) [arm64-v8a::289d75599f6112d5757113220599e90b]

机型:SM-A315G Android 12,level 31 aarch64
SIGSEGV(SEGV_MAPERR)
#00 pc 000000000022f540 /apex/com.android.art/lib64/libart.so (art::ThreadList::SuspendThreadByThreadId(unsigned int, art::SuspendReason, bool*)+452) [arm64-v8a::a49c773ef6221a996ecea990e9753caa]

机型:XT2175-2 Android 12,level 31 aarch64
SIGSEGV(SEGV_MAPERR)
#00 pc 0000000000231ca8 /apex/com.android.art/lib64/libart.so (art::ThreadList::SuspendThreadByThreadId(unsigned int, art::SuspendReason, bool*)+452) [arm64-v8a::56e704c544e6c624201be2ab4933e853]

请问这个有啥排查思路吗?

获取的堆栈中没有代码行号

获取的堆栈实际是这样(缺乏文件名和行号)

29944-29962 TAG           com....looper.monitor.app  D  void java.lang.Thread.sleep(long, int) 
29944-29962 TAG           com....looper.monitor.app  D  void java.lang.Thread.sleep(long) 
29944-29962 TAG           com....looper.monitor.app  D  boolean com.netease.cloudmusic.APP.addIdleHandler$lambda-1(com.netease.cloudmusic.APP) 
29944-29962 TAG           com....looper.monitor.app  D  boolean com.netease.cloudmusic.APP.$r8$lambda$21O6vOVsLj7WDXPcCmA3Hd_TyE0(com.netease.cloudmusic.APP) 
29944-29962 TAG           com....looper.monitor.app  D  boolean com.netease.cloudmusic.APP$$ExternalSyntheticLambda1.queueIdle() 
29944-29962 TAG           com....looper.monitor.app  D  boolean com.netease.cloudmusic.looper.monitor.IdleHandlerDecorator$add$decorator$1.queueIdle() 
29944-29962 TAG           com....looper.monitor.app  D  android.os.Message android.os.MessageQueue.next() 

而正常的getStackTrace格式是这样的

29209-29228 TAG           com....looper.monitor.app  D  android.os.Looper.loopOnce(Looper.java:161)
29209-29228 TAG           com....looper.monitor.app  D  android.os.Looper.loop(Looper.java:288)
29209-29228 TAG           com....looper.monitor.app  D  android.app.ActivityThread.main(ActivityThread.java:7898)
29209-29228 TAG           com....looper.monitor.app  D  java.lang.reflect.Method.invoke(Native Method)
29209-29228 TAG           com....looper.monitor.app  D  com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
29209-29228 TAG           com....looper.monitor.app  D  com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
29209-29228 TAG           com....looper.monitor.app  D  java.lang.Thread.sleep(Native Method)
29209-29228 TAG           com....looper.monitor.app  D  java.lang.Thread.sleep(Thread.java:450)
29209-29228 TAG           com....looper.monitor.app  D  java.lang.Thread.sleep(Thread.java:355)
29209-29228 TAG           com....looper.monitor.app  D  com.netease.cloudmusic.APP.addIdleHandler$lambda-1(APP.kt:70)
29209-29228 TAG           com....looper.monitor.app  D  com.netease.cloudmusic.APP.$r8$lambda$21O6vOVsLj7WDXPcCmA3Hd_TyE0(Unknown Source:0)
29209-29228 TAG           com....looper.monitor.app  D  com.netease.cloudmusic.APP$$ExternalSyntheticLambda1.queueIdle(Unknown Source:2)
29209-29228 TAG           com....looper.monitor.app  D  com.netease.cloudmusic.looper.monitor.IdleHandlerDecorator$add$decorator$1.queueIdle(IdleHandlerDecorator.kt:20)```

如何修改可以保持和系统API一致呢

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.