GithubHelp home page GithubHelp logo

memory-leak-detector's Introduction

MemoryLeakDetector

简体中文版说明 >>>

GitHub license Platform API

MemoryLeakDetector is a native memory leak monitoring tool developed by Xigua video android team. It has simple access, wide monitoring range, excellent performance and good stability. It is widely used in native-memory-leak-governance of ByteDance's major apps, and the benefits are significant!

Apps using MemoryLeakDetector

Get started

Step 1: Add the JitPack repository to your build file

allprojects {
    repositories {
        maven { url 'https://jitpack.io' }
    }
}

Step 2: Add the dependency

dependencies {
    implementation 'com.github.bytedance:memory-leak-detector:0.2.1'
}

Step 3: Add code for simple usage (This step is not necessary for using broadcast control)

// Using MemoryLeakDetector to monitor specified so
Raphael.start(
    Raphael.MAP64_MODE|Raphael.ALLOC_MODE|0x0F0000|1024,
    "/storage/emulated/0/raphael", // need sdcard permission
    ".*libxxx\\.so$"
);
// Using MemoryLeakDetector to monitor current process
Raphael.start(
    Raphael.MAP64_MODE|Raphael.ALLOC_MODE|0x0F0000|1024,
    "/storage/emulated/0/raphael", // need sdcard permission
    null
);
## broadcast command for specified so
adb shell am broadcast -a com.bytedance.raphael.ACTION_START -f 0x01000000 --es configs 0xCF0400 --es regex ".*libXXX\\.so$"
## broadcast command (RaphaelReceiver component process)
adb shell am broadcast -a com.bytedance.raphael.ACTION_START -f 0x01000000 --es configs 0xCF0400

Step 4: Print result

// code control
Raphael.print();
## broadcast command
adb shell am broadcast -a com.bytedance.raphael.ACTION_PRINT -f 0x01000000

Step 5: Analysis

## analysis report
##   -r: report path
##   -o: output file name
##   -s: symbol file dir
python3 library/src/main/python/raphael.py -r report -o leak-doubts.txt -s ./symbol/
## analysis maps
##   -m: maps file path
python3 library/src/main/python/mmap.py -m maps

Step 6: Stop monitoring

// code control
Raphael.stop();
## broadcast command
adb shell am broadcast -a com.bytedance.raphael.ACTION_STOP -f 0x01000000

Extra

  1. Android Camera内存问题剖析
  2. 西瓜视频稳定性治理体系建设一:Tailor 原理及实践
  3. 西瓜视频稳定性治理体系建设二:Raphael 原理及实践

Support

  1. Communicate on GitHub issues
  2. Mail: [email protected]
  3. WeChat: 429013449
  4. QQ Group

QQ Group

License

Copyright (c) 2021 ByteDance Inc

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

memory-leak-detector's People

Contributors

caoshen avatar cr321 avatar marryton007 avatar shentianzhou avatar sygobject avatar zhouweihui 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

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

memory-leak-detector's Issues

Python 脚本对 addr2line 输出的处理,遗漏了函数信息

目前是这样,第二行只有文件名

def addr_to_line(address, symbol_path):
    # for aarch64
    status, output = subprocess.getstatusoutput('aarch64-linux-android-addr2line -C -e %s -f %s' % (symbol_path, address))
    if status != 0:
        print(output)
        raise Exception('execute [aarch64-linux-android-addr2line -C -e %s -f %s] failed' % (symbol_path, address))
    return output.split('\n')[1]
def addr_to_line(address, symbol_path):
    # for aarch64
    status, output = subprocess.getstatusoutput('aarch64-linux-android-addr2line -C -e %s -f %s' % (symbol_path, address))
    if status != 0:
        print(output)
        raise Exception('execute [aarch64-linux-android-addr2line -C -e %s -f %s] failed' % (symbol_path, address))
    lines = output.split('\n')
    return "\t".join(lines)

建议改成这样,把函数名也带上,避免部分情况,只有函数名,没有文件名的时候,显示信息不全。

Vivo手机运行崩溃

Softversion: PD2011C_A_5.9.10
2023-03-07 20:16:45.998 4252-4252 DEBUG pid-4252 A Time: 2023-03-07 20:16:45
2023-03-07 20:16:45.998 4252-4252 DEBUG pid-4252 A *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
2023-03-07 20:16:45.998 4252-4252 DEBUG pid-4252 A Build fingerprint: 'vivo/PD2011/PD2011:10/QP1A.190711.020/compiler12281609:user/release-keys'
2023-03-07 20:16:45.998 4252-4252 DEBUG pid-4252 A Revision: '0'
2023-03-07 20:16:45.998 4252-4252 DEBUG pid-4252 A ABI: 'arm64'
2023-03-07 20:16:45.998 4252-4252 DEBUG pid-4252 A Timestamp: 2023-03-07 20:16:45+0800
2023-03-07 20:16:45.998 4252-4252 DEBUG pid-4252 A pid: 4143, tid: 4143, name: ce.raphael.demo >>> com.bytedance.raphael.demo <<<
2023-03-07 20:16:45.998 4252-4252 DEBUG pid-4252 A uid: 10756
2023-03-07 20:16:45.998 4252-4252 DEBUG pid-4252 A signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x7674d3f344
2023-03-07 20:16:45.998 4252-4252 DEBUG pid-4252 A Cause: execute-only (no-read) memory access error; likely due to data in .text.
2023-03-07 20:16:45.998 4252-4252 DEBUG pid-4252 A x0 0000007fddb64218 x1 0000007fddb64210 x2 0000007fddb64220 x3 0000007fddb64500
2023-03-07 20:16:45.998 4252-4252 DEBUG pid-4252 A x4 0000007fddb64578 x5 0000000000000004 x6 fefeff7489894bbe x7 7f7f7f7fffff7fff
2023-03-07 20:16:45.998 4252-4252 DEBUG pid-4252 A x8 0000007674d3f344 x9 0000000000000005 x10 0000000000000000 x11 0000000000000000
2023-03-07 20:16:45.998 4252-4252 DEBUG pid-4252 A x12 0000000000000000 x13 0000000000000000 x14 0000000000000004 x15 ffffffffffffffff
2023-03-07 20:16:45.998 4252-4252 DEBUG pid-4252 A x16 00000075893d6d30 x17 0000007674d70550 x18 00000076799a6000 x19 00000075f2c10800
2023-03-07 20:16:45.998 4252-4252 DEBUG pid-4252 A x20 0000000000000000 x21 00000075f2c10800 x22 0000007fddb64a80 x23 000000758a8a4cbf
2023-03-07 20:16:45.998 4252-4252 DEBUG pid-4252 A x24 000000000000000c x25 0000007678863020 x26 00000075f2c108b0 x27 0000000000000003
2023-03-07 20:16:45.998 4252-4252 DEBUG pid-4252 A x28 0000007fddb64800 x29 0000007fddb64190
2023-03-07 20:16:45.998 4252-4252 DEBUG pid-4252 A sp 0000007fddb640c0 lr 000000758939a41c pc 000000758939a79c

backtrace:
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #00 pc 000000000001479c /data/app/com.bytedance.raphael.demo-QPcNJVTwurgEOvXVmZALJA==/lib/arm64/libraphael.so (BuildId: d1f295ecb37e7ee375b5407d5e7d681a8a6ccd32)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #1 pc 0000000000014418 /data/app/com.bytedance.raphael.demo-QPcNJVTwurgEOvXVmZALJA==/lib/arm64/libraphael.so (BuildId: d1f295ecb37e7ee375b5407d5e7d681a8a6ccd32)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #2 pc 0000000000014070 /data/app/com.bytedance.raphael.demo-QPcNJVTwurgEOvXVmZALJA==/lib/arm64/libraphael.so (A64HookFunctionV+224) (BuildId: d1f295ecb37e7ee375b5407d5e7d681a8a6ccd32)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #3 pc 000000000001465c /data/app/com.bytedance.raphael.demo-QPcNJVTwurgEOvXVmZALJA==/lib/arm64/libraphael.so (A64HookFunction+108) (BuildId: d1f295ecb37e7ee375b5407d5e7d681a8a6ccd32)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #4 pc 0000000000025760 /data/app/com.bytedance.raphael.demo-QPcNJVTwurgEOvXVmZALJA==/lib/arm64/libraphael.so (registerInlineProxy(_JNIEnv*)+128) (BuildId: d1f295ecb37e7ee375b5407d5e7d681a8a6ccd32)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #5 pc 0000000000026848 /data/app/com.bytedance.raphael.demo-QPcNJVTwurgEOvXVmZALJA==/lib/arm64/libraphael.so (Raphael::start(_JNIEnv*, _jobject*, int, _jstring*, _jstring*)+612) (BuildId: d1f295ecb37e7ee375b5407d5e7d681a8a6ccd32)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #6 pc 0000000000027e00 /data/app/com.bytedance.raphael.demo-QPcNJVTwurgEOvXVmZALJA==/lib/arm64/libraphael.so (start(_JNIEnv*, _jobject*, int, _jstring*, _jstring*)+64) (BuildId: d1f295ecb37e7ee375b5407d5e7d681a8a6ccd32)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #7 pc 0000000000140350 /apex/com.android.runtime/lib64/libart.so (art_quick_generic_jni_trampoline+144) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #8 pc 00000000001375b8 /apex/com.android.runtime/lib64/libart.so (art_quick_invoke_static_stub+568) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #9 pc 0000000000169ecc /apex/com.android.runtime/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+276) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #10 pc 00000000003089d8 /apex/com.android.runtime/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+384) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #11 pc 0000000000303c38 /apex/com.android.runtime/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+892) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #12 pc 00000000005a63d8 /apex/com.android.runtime/lib64/libart.so (MterpInvokeStatic+372) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #13 pc 0000000000131994 /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_static+20) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #14 pc 0000000000103c1c [anon:dalvik-classes.dex extracted in memory from /data/app/com.bytedance.raphael.demo-QPcNJVTwurgEOvXVmZALJA==/base.apk] (com.bytedance.raphael.Raphael.start+20)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #15 pc 00000000005a6674 /apex/com.android.runtime/lib64/libart.so (MterpInvokeStatic+1040) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #16 pc 0000000000131994 /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_static+20) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #17 pc 0000000000103982 [anon:dalvik-classes.dex extracted in memory from /data/app/com.bytedance.raphael.demo-QPcNJVTwurgEOvXVmZALJA==/base.apk] (com.bytedance.demo.DemoApp.onCreate+58)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #18 pc 00000000005a3bc4 /apex/com.android.runtime/lib64/libart.so (MterpInvokeVirtual+1352) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #19 pc 0000000000131814 /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_virtual+20) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #20 pc 000000000020c7e8 /system/framework/framework.jar (android.app.Instrumentation.callApplicationOnCreate)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #21 pc 00000000005a3bc4 /apex/com.android.runtime/lib64/libart.so (MterpInvokeVirtual+1352) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #22 pc 0000000000131814 /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_virtual+20) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #23 pc 0000000000196406 /system/framework/framework.jar (android.app.ActivityThread.handleBindApplication+2418)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #24 pc 00000000005a5ed0 /apex/com.android.runtime/lib64/libart.so (MterpInvokeDirect+1100) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #25 pc 0000000000131914 /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_direct+20) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #26 pc 00000000001930c8 /system/framework/framework.jar (android.app.ActivityThread.access$1600)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #27 pc 00000000005a6674 /apex/com.android.runtime/lib64/libart.so (MterpInvokeStatic+1040) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #28 pc 0000000000131994 /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_static+20) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #29 pc 000000000018f21a /system/framework/framework.jar (android.app.ActivityThread$H.handleMessage+1622)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #30 pc 00000000005a3bc4 /apex/com.android.runtime/lib64/libart.so (MterpInvokeVirtual+1352) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #31 pc 0000000000131814 /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_virtual+20) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #32 pc 0000000000320722 /system/framework/framework.jar (android.os.Handler.dispatchMessage+38)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #33 pc 00000000005a3bc4 /apex/com.android.runtime/lib64/libart.so (MterpInvokeVirtual+1352) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #34 pc 0000000000131814 /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_virtual+20) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #35 pc 0000000000347fae /system/framework/framework.jar (android.os.Looper.loop+550)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #36 pc 00000000005a6674 /apex/com.android.runtime/lib64/libart.so (MterpInvokeStatic+1040) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #37 pc 0000000000131994 /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_static+20) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #38 pc 000000000019a300 /system/framework/framework.jar (android.app.ActivityThread.main+196)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #39 pc 00000000002d9cec /apex/com.android.runtime/lib64/libart.so (_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_6JValueEbb.llvm.3084269041190911232+240) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #40 pc 0000000000594fd0 /apex/com.android.runtime/lib64/libart.so (artQuickToInterpreterBridge+1032) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #41 pc 0000000000140468 /apex/com.android.runtime/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #42 pc 00000000001375b8 /apex/com.android.runtime/lib64/libart.so (art_quick_invoke_static_stub+568) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #43 pc 0000000000169ecc /apex/com.android.runtime/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+276) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #44 pc 00000000004b3998 /apex/com.android.runtime/lib64/libart.so (art::(anonymous namespace)::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, art::(anonymous namespace)::ArgArray*, art::JValue*, char const*)+104) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #45 pc 00000000004b553c /apex/com.android.runtime/lib64/libart.so (art::InvokeMethod(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jobject*, _jobject*, unsigned long)+1480) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #46 pc 000000000044080c /apex/com.android.runtime/lib64/libart.so (art::Method_invoke(_JNIEnv*, _jobject*, _jobject*, _jobjectArray*)+52) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #47 pc 00000000000c2b54 /system/framework/arm64/boot.oat (art_jni_trampoline+180) (BuildId: 51b531eaeedd3854c07937602def32199f719aab)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #48 pc 0000000000137334 /apex/com.android.runtime/lib64/libart.so (art_quick_invoke_stub+548) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #49 pc 0000000000169eac /apex/com.android.runtime/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+244) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #50 pc 00000000003089d8 /apex/com.android.runtime/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+384) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #51 pc 0000000000303c38 /apex/com.android.runtime/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+892) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #52 pc 00000000005a3904 /apex/com.android.runtime/lib64/libart.so (MterpInvokeVirtual+648) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #53 pc 0000000000131814 /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_virtual+20) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #54 pc 00000000003b22be /system/framework/framework.jar (com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run+22)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #55 pc 00000000002d9cec /apex/com.android.runtime/lib64/libart.so (_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_6JValueEbb.llvm.3084269041190911232+240) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #56 pc 0000000000594fd0 /apex/com.android.runtime/lib64/libart.so (artQuickToInterpreterBridge+1032) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #57 pc 0000000000140468 /apex/com.android.runtime/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #58 pc 00000000009f8bec /system/framework/arm64/boot-framework.oat (com.android.internal.os.ZygoteInit.main+2460) (BuildId: 3a0c7efedabdc59e784bdec335be079298d9c32e)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #59 pc 00000000001375b8 /apex/com.android.runtime/lib64/libart.so (art_quick_invoke_static_stub+568) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #60 pc 0000000000169ecc /apex/com.android.runtime/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+276) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #61 pc 00000000004b3998 /apex/com.android.runtime/lib64/libart.so (art::(anonymous namespace)::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, art::(anonymous namespace)::ArgArray*, art::JValue*, char const*)+104) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #62 pc 00000000004b3588 /apex/com.android.runtime/lib64/libart.so (art::InvokeWithVarArgs(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, std::__va_list)+408) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #63 pc 00000000003bd8c0 /apex/com.android.runtime/lib64/libart.so (art::JNI::CallStaticVoidMethodV(_JNIEnv*, _jclass*, _jmethodID*, std::__va_list)+624) (BuildId: 80258bb34139165e1c13d1a8291b6f61)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #64 pc 00000000000c0564 /system/lib64/libandroid_runtime.so (_JNIEnv::CallStaticVoidMethod(_jclass*, _jmethodID*, ...)+116) (BuildId: fb614280b8d14b27138a857ecc556532)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #65 pc 00000000000c342c /system/lib64/libandroid_runtime.so (android::AndroidRuntime::start(char const*, android::Vectorandroid::String8 const&, bool)+776) (BuildId: fb614280b8d14b27138a857ecc556532)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #66 pc 00000000000034f8 /system/bin/app_process64 (main+1192) (BuildId: dcb784be77e5b6eb5d380391d1a38fe9)
2023-03-07 20:16:46.337 4252-4252 DEBUG pid-4252 A #67 pc 000000000006ebc4 /apex/com.android.runtime/lib64/bionic/libc.so (__libc_init+108) (BuildId: e9cd5624601680ababdd7ad7eeeb4032)

最后输出结果的单位

大佬,想问下,这个分析工具最后输出的统计数据的单位是字节数吗?
python library/src/main/python/raphael.py -r report -o leak-doubts.txt -s ./symbol/
image

raphael脚本增加-s参数报错

user$ python python/raphael.py -r raphael/report -o leak-doubts.txt -s symbol/
Raphael script version: 1.0.0
{'libmapv2.so': '/Users/user/Documents/driver/libmapv2.so', 'libhawiinav.so': '/Users/user/Documents/driver/libhawiinav.so'}
Traceback (most recent call last):
File "python/raphael.py", line 219, in
print_report(writer, report)
File "python/raphael.py", line 151, in print_report
retry_symbol(record)
File "python/raphael.py", line 110, in retry_symbol
symbol = addr_to_line(frame.pc, symbol_table.get(match.group(1)))
File "python/raphael.py", line 88, in addr_to_line
raise Exception('execute [/Users/user/Library/Android/sdk/ndk/21.1.6352462/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-addr2line -e %s -f %s] failed' % (symbol_path, address))
Exception: execute [/Users/user/Library/Android/sdk/ndk/21.1.6352462/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-addr2line -e /Users/user/Documents/driver/libmapv2.so -f 0x0017c91b] failed

raphael.py执行报错

使用python2.7,执行raphael.py分析report文件,报错如下,是否有python版本要求?

File "D:\open\memory-leak-detector\library\src\main\python\raphael.py", line 149, in print_report
    report.sort(lambda x, y: x.size - y.size, reverse=True)
TypeError: comparison function must return int, not long

请教一下案例中的代码是如何调用的?

我按照案例中的代码实现了一遍,放到我的代码里是这样子的:

protected final CameraCaptureSession.CaptureCallback  captureCallback = new CameraCaptureSession.CaptureCallback() {
    @Override
    public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
        CameraActivity.recycle(result);
    }
};

static Field sTargetField;
static Method sTargetMethod;

@SuppressLint("SoonBlockedPrivateApi")
static void recycle(TotalCaptureResult tcr) {
    try {
        if (sTargetMethod == null || sTargetField == null) {
            Method forName = Class.class.getDeclaredMethod("forName", String.class);
            Method getDeclaredMethod = Class.class.getDeclaredMethod("getDeclaredMethod", String.class, Class[].class);
            Class<?> vmRuntimeClass = (Class<?>) forName.invoke(null, "dalvik.system.VMRuntime");
            Method getRuntime = (Method) getDeclaredMethod.invoke(vmRuntimeClass, "getRuntime", null);
            Method setHiddenApiExemptions = (Method) getDeclaredMethod.invoke(vmRuntimeClass, "setHiddenApiExemptions", new Class[]{String[].class});
            Object sVmRuntime = getRuntime.invoke(null);
            setHiddenApiExemptions.invoke(sVmRuntime, new Object[]{new String[]{"L"}});
        }

        if (sTargetField == null) {
            sTargetField = tcr.getClass().getSuperclass().getDeclaredField("mResults");
            sTargetField.setAccessible(true);
        }

        if (sTargetMethod == null) {
            sTargetMethod = Class.forName("android.hardware.camera2.impl.CameraMetadataNative").getDeclaredMethod("close");
            sTargetMethod.setAccessible(true);
        }

        sTargetMethod.invoke(sTargetField.get(tcr));
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (NoSuchFieldException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }
}

请问是这样调用的吗?

Androidx适配

我看项目依赖了support包下的annotion : com.android.support:support-annotations:28.0.0 可以切换成androidx的annotion库吗?

commands.getstatusoutput在windows平台不支持

raphael.py中commands模块不支持windows平台,且在只Python 3中已被移除,建议改为subprocess
比如改为

output = subprocess.check_output('arm-linux-androideabi-addr2line -C -e %s -f %s' % (symbol_path, address))

另外addr2line 的-C参数支持demangle name,是否可以替换c++filt

【必现】线程卡住问题

MemoryCache.cpp 中
pthread_mutex_lock(&alloc_mutex);
for (auto p : alloc_table) {
for (; p != nullptr; p = p->next) {
write_trace(report, p, nullptr, &dl_cache);
}
}
pthread_mutex_lock(&alloc_mutex);

pthread_mutex_lock(&alloc_mutex);
在调试中发现这句代码卡住线程

存在内存泄露

void Raphael::start(JNIEnv *env, jobject obj, jint configs, jstring space, jstring regex) {
mSpace = (char *) env->GetStringUTFChars(space, 0);
其他省略
}

mSpace 并没有释放,导致内存泄露

Runtime weak performace

  1. MemCache too small, which is 1<<15 by default.
  2. remove_alloc seek recyle stack cost many time.

Galaxy A51 crash when startup demo

环境

手机:Galaxy A51
操作系统:Android 10

现象

直接运行demo最新版,启动会直接crash,下面是日志
`
2022-09-22 17:10:13.487 1215-1215/? E/Zygote: isWhitelistProcess - Process is Whitelisted
2022-09-22 17:10:13.495 1215-1215/? E/Zygote: accessInfo : 1
2022-09-22 17:10:13.503 1215-1215/? I/ce.raphael.dem: Late-enabling -Xcheck:jni
2022-09-22 17:10:13.533 1215-1215/? E/ce.raphael.dem: Unknown bits set in runtime_flags: 0x8000
2022-09-22 17:10:13.554 1215-1215/? D/ActivityThread: setConscryptValidator
2022-09-22 17:10:13.554 1215-1215/? D/ActivityThread: setConscryptValidator - put
2022-09-22 17:10:13.734 1215-1215/com.bytedance.raphael.demo I/A64_HOOK: insns pool initialized.
2022-09-22 17:10:13.735 1215-1215/com.bytedance.raphael.demo E/RAPHAEL: invoke failed at xdl_sym
2022-09-22 17:10:13.735 1215-1215/com.bytedance.raphael.demo W/ce.raphael.dem: 0xebadde09 skipped times: 0
2022-09-22 17:10:13.736 1215-1215/com.bytedance.raphael.demo A/libc: Fatal signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x753ff6532c in tid 1215 (ce.raphael.demo), pid 1215 (ce.raphael.demo)

`

raphael.py 是否考虑,把所有匹配到的 so 都放出来?

目前维护了一个 system_group,有比较多内存算到了 extras,不太直观。想改成这样,把所有的 so 都放出来,然后去掉 system_group。

def group_record(record):
    for frame in record.stack:
        match = re.match(r'.+\/(.+\.(so|apk|oat))', frame.path, re.M | re.I)
        if match.group(1):
            return match.group(1)
    return 'unknown-nostack'

使用std::make_unique创建的对象,无法检测到泄漏

extern "C" JNIEXPORT void JNICALL
Java_com_xxxx_filament_ObjAssimpLoader_nLoad(JNIEnv *env, jclass, jstring path, jlong nativeEngine) {
    g_meshSet = std::make_unique<ObjMeshAssimp>(*((Engine*)nativeEngine));
    utils::Path filename = env->GetStringUTFChars(path, 0);
    g_meshSet->addFromFile(filename, g_materialInstances, true);
    //人为制造一个内存泄漏对象
    std::unique_ptr<ObjMeshAssimp> temp = std::make_unique<ObjMeshAssimp>(*((Engine*)nativeEngine));
}

大佬,问下,我集成这个工具后,生成report,并没有找到我泄漏的so代码行号,唯一相关的so信息如下:

0x00000076e2647000, 4096, 1
0x0000000000214cc0 /data/app/com.xxxx.filament.textured-OlqQ08eyhNALYGjMKOUN6w==/lib/arm64/libfilament_jni.so (std::__ndk1::deque<unsigned int, std::__ndk1::allocator<unsigned int> >::__add_back_capacity())

0x00000076e2ba9000, 4096, 1
0x00000000003127c8 /system/lib64/libart.so (art::jit::JitCodeCache::AddProfilingInfoInternal(art::Thread*, art::ArtMethod*, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> > const&) + 276)
0x0000000000312680 /system/lib64/libart.so (art::jit::JitCodeCache::AddProfilingInfo(art::Thread*, art::ArtMethod*, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> > const&, bool) + 132)
0x0000000000322c14 /system/lib64/libart.so (art::ProfilingInfo::Create(art::Thread*, art::ArtMethod*, bool) + 372)
0x0000000000309040 /system/lib64/libart.so (art::jit::Jit::AddSamples(art::Thread*, art::ArtMethod*, unsigned short, bool) + 504)
0x0000000000280394 /system/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*) + 180)
0x000000000027a444 /system/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*) + 972)
0x0000000000526f0c /system/lib64/libart.so (MterpInvokeVirtual + 592)
0x000000000054a598 /system/lib64/libart.so (ExecuteMterpImpl + 14232)
0x0000000000254148 /system/lib64/libart.so (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool) (.llvm.3404100416) + 492)
0x0000000000259c3c /system/lib64/libart.so (art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*, art::JValue*) + 220)
0x000000000027a428 /system/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*) + 944)
0x0000000000526f0c /system/lib64/libart.so (MterpInvokeVirtual + 592)
0x000000000054a598 /system/lib64/libart.so (ExecuteMterpImpl + 14232)
0x0000000000254148 /system/lib64/libart.so (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool) (.llvm.3404100416) + 492)

但是这看起来像是系统编译的内存信息

release包无法打印栈信息

我写了一个测试程序,打debug包可以打印成完整的栈信息:
0x00000070073ba000,4100, 1
0x006000o07a4 /data/app/b~~CGuroiroinsy5nrm4podLNlkA=/com.bytedance.raphael.demo-1t7DsphtuNVaESHB3XYhr=/lib/arm64/libewjh.so ( Java_com_bytedance_demo_MemoryHookTestNative_mma)
0x0000000000222248 /apex/com.android.art/lib64/libart.so (art_quick_generic_jni_trampoline + 152)

但是引入签名打release包,只能打印出如下栈信息:
0x0000007c16f32000, 4100, 1
0x0000000000222248 /apex/com.android.art/lib64/libart.so (art_quick_generic_jni_trampoline + 152)

通过调试发现好像是栈回溯出现了问题。unwind_backtrace()方法在release包因为pre < fp + kFrameSize提前跳出循环。

以下是debug情况下的方法代码:
0000000000000738 <Java_com_bytedance_demo_MemoryHookTestNative_mma@@base>:
738: d10143ff sub sp, sp, #0x50
73c: a9047bfd stp x29, x30, [sp,#64]
740: 910103fd add x29, sp, #0x40
744: d2800008 mov x8, #0x0 // #0
748: aa0803e2 mov x2, x8
74c: d2820089 mov x9, #0x1004 // #4100
750: 5280006a mov w10, #0x3 // #3
754: 52800443 mov w3, #0x22 // #34
758: 12800004 mov w4, #0xffffffff // #-1
75c: 5280008b mov w11, #0x4 // #4
760: 9000000c adrp x12, 0 __cxa_finalize@plt-0x640
764: 911f218c add x12, x12, #0x7c8
768: 9000000d adrp x13, 0 __cxa_finalize@plt-0x640
76c: 911f39ad add x13, x13, #0x7ce
770: 9000000e adrp x14, 0 __cxa_finalize@plt-0x640
774: 911f45ce add x14, x14, #0x7d1
778: f81f83a0 stur x0, [x29,#-8]
77c: f81f03a1 stur x1, [x29,#-16]
780: aa0203e0 mov x0, x2
784: aa0903e1 mov x1, x9
788: 2a0a03e2 mov w2, w10
78c: aa0803e5 mov x5, x8
790: b81e43ab stur w11, [x29,#-28]
794: f9000fec str x12, [sp,#24]
798: f9000bed str x13, [sp,#16]
79c: f90007ee str x14, [sp,#8]
7a0: 97ffffb0 bl 660 mmap@plt
7a4: f81e83a0 stur x0, [x29,#-24]
7a8: b85e43a0 ldur w0, [x29,#-28]
7ac: f9400fe1 ldr x1, [sp,#24]
7b0: f9400be2 ldr x2, [sp,#16]
7b4: f94007e3 ldr x3, [sp,#8]
7b8: 97ffffa6 bl 650 __android_log_print@plt
7bc: a9447bfd ldp x29, x30, [sp,#64]
7c0: 910143ff add sp, sp, #0x50
7c4: d65f03c0 ret

以下是release情况下的方法代码:
00000000000006d4 <Java_com_bytedance_demo_MemoryHookTestNative_mma>:
6d4: a9bf7bfd stp x29, x30, [sp,#-16]!
6d8: 910003fd mov x29, sp
6dc: 52820081 mov w1, #0x1004 // #4100
6e0: 52800062 mov w2, #0x3 // #3
6e4: 52800443 mov w3, #0x22 // #34
6e8: 12800004 mov w4, #0xffffffff // #-1
6ec: aa1f03e0 mov x0, xzr
6f0: aa1f03e5 mov x5, xzr
6f4: 97ffffcf bl 630 mmap@plt
6f8: 90000001 adrp x1, 0 __cxa_finalize@plt-0x610
6fc: 90000002 adrp x2, 0 __cxa_finalize@plt-0x610
700: 90000003 adrp x3, 0 __cxa_finalize@plt-0x610
704: 911c7021 add x1, x1, #0x71c
708: 911c8842 add x2, x2, #0x722
70c: 911c9463 add x3, x3, #0x725
710: 52800080 mov w0, #0x4 // #4
714: a8c17bfd ldp x29, x30, [sp],#16
718: 17ffffc2 b 620 __android_log_print@plt

请问我该如何编译release包才能够获得正常的栈信息?

配置项的各个参数含义具体是什么

Raphael.MAP64_MODE | Raphael.ALLOC_MODE | 0x0F0000 | 1024
前两个mode我大概可以猜到是什么,一个是监听 MMAP,一个是监听 ALLOC,查看源码我看到还有一个 DIFF_CACHE,这是什么含义?
后面的 0x0F0000 和 1024 又是配置的什么?

部分场景raphael.py聚合的不准

部分场景raphael.py聚合的不准
比如

0x0000007010381000, 16785408, 1
0x00000000005932e0 /data/app/xxx/lib/arm64/libmya.so (unknown)
0x000000000045b8e4 /system/lib64/libsystem.so (unknown)
0x00000000000291c0 /data/app/xxx/lib/arm64/libmyb.so (unknown)

根据 group_record聚合函数,从栈底到栈顶遍历,只要是先找到了/data/下的so就返回,这种场景返回的是libmyb.so,实际应该返回libmya.so

def group_record(record):
    default = None
    for i in range(len(record.stack) - 1, -1, -1):
        match = re.match(r'.+\/(.+\.(so|apk|oat))', record.stack[i].path, re.M | re.I)
        if not match or match.group(1) == 'libraphael.so':
            continue
        elif record.stack[i].path.startswith('/data/'):
            return match.group(1)
        elif match.group(1) in system_group and not default:
            default = match.group(1)
    return default if default else 'extras'

运行分析脚本raphael.py 报错

Raphael script version: 1.0.0
Traceback (most recent call last):
File "library/src/main/python/raphael.py", line 215, in
report = parse_report(string)
File "library/src/main/python/raphael.py", line 183, in parse_report
report.append(Trace(match[0][0], match[0][1], match[0][2], stack))
IndexError: list index out of range

libudf耗时问题

image
我简单测试了下libudf的耗时,请问下:
第一次耗时为什么和第二次耗时相差这么大?
第一次耗时这个数量级太大了。

addr2line 获取函数名错误

这个问题不是 memory-leak-detector 的问题,放这里供其他人参考。

因为 memory-leak-detector 依赖 addr2line 来解析一些 unknown 的地址,有些时候,它会给出错误的函数名,导致 memory-leak-detector 的聚合报告里面,出现一些不可能的堆栈。

例如下面一个例子

0x000000724b800000, 188743680, mmap64, 5
0x0000000000f53fb0    my_malloc()
0x0000000002014358  byte_buf::~byte_buf()
0x0000000002013bbc   byte_buf::init(unsigned int)

其中 byte_buf::init() 通过一个 static inline 函数去调用 my_malloc,被 addr2line 误识别为 byte_buf::~byte_buf()。byte_buf::~byte_buf() 是一个虚函数。

是否仍推荐使用

看到目前(2023/11)西瓜视频和抖音未发布Rapheal库,相关功能似乎被npth组件代替,有几个问题期待得到答复:

  1. Rapheal是否仍在维护中?
  2. 是否推荐在解决Android端OOM问题时使用该库?
  3. npth组件未来是否有开源计划?

谢谢!

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.