Android 平台的Crash崩溃捕获-全

article/2025/11/7 23:03:14

上层-java/kotlin:

Android应用层java/kotlin的crash捕获相对容易。直接实现Thread.UncaughtExceptionHandler即可处理收集。Thread.UncaughtExceptionHandler:当某一线程因未捕获的异常而即将终止时,Java 虚拟机将使用 Thread.getUncaughtExceptionHandler() 查询该线程以获得其 UncaughtExceptionHandler 的线程,并调用处理程序的 uncaughtException 方法,将线程和异常作为参数传递。如果某一线程没有明确设置其 UncaughtExceptionHandler,则将它的 ThreadGroup 对象作为其 UncaughtExceptionHandler。如果 ThreadGroup 对象对处理异常没有什么特殊要求,那么它可以将调用转发给 默认的未捕获异常处理程序。

我们需要实现此接口,并注册为程序中默认未捕获异常处理。这样当未捕获异常发生时,就可以做一些个性化的异常处理操作。

<pre name="code" class="java">package com.example.mycrashtest;import java.io.File;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.Thread.UncaughtExceptionHandler;
import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;
import android.os.Environment;
import android.os.Looper;
import android.os.SystemClock;
import android.util.Log;
import android.widget.Toast;/*** <h3>全局捕获异常</h3>* <br>* 当程序发生Uncaught异常的时候,有该类来接管程序,并记录错误日志* */
@SuppressLint("SimpleDateFormat")
public class CrashHandler implements UncaughtExceptionHandler {public static String TAG = "MyCrash";// 系统默认的UncaughtException处理类private Thread.UncaughtExceptionHandler mDefaultHandler;private static CrashHandler instance = new CrashHandler();private Context mContext;// 用来存储设备信息和异常信息private Map<String, String> infos = new HashMap<String, String>();// 用于格式化日期,作为日志文件名的一部分private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");/** 保证只有一个CrashHandler实例 */private CrashHandler() {}/** 获取CrashHandler实例 ,单例模式 */public static CrashHandler getInstance() {return instance;}/*** 初始化* * @param context*/public void init(Context context) {mContext = context;// 获取系统默认的UncaughtException处理器mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();// 设置该CrashHandler为程序的默认处理器Thread.setDefaultUncaughtExceptionHandler(this);autoClear(5);}/*** 当UncaughtException发生时会转入该函数来处理*/@Overridepublic void uncaughtException(Thread thread, Throwable ex) {if (!handleException(ex) && mDefaultHandler != null) {// 如果用户没有处理则让系统默认的异常处理器来处理mDefaultHandler.uncaughtException(thread, ex);} else {SystemClock.sleep(3000);// 退出程序android.os.Process.killProcess(android.os.Process.myPid());System.exit(1);}}/*** 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.* * @param ex* @return true:如果处理了该异常信息; 否则返回false.*/private boolean handleException(Throwable ex) {if (ex == null)return false;try {// 使用Toast来显示异常信息new Thread() {@Overridepublic void run() {Looper.prepare();Toast.makeText(mContext, "很抱歉,程序出现异常,即将重启.",Toast.LENGTH_LONG).show();Looper.loop();}}.start();// 收集设备参数信息collectDeviceInfo(mContext);// 保存日志文件saveCrashInfoFile(ex);SystemClock.sleep(3000);} catch (Exception e) {e.printStackTrace();}return true;}/*** 收集设备参数信息* * @param ctx*/public void collectDeviceInfo(Context ctx) {try {PackageManager pm = ctx.getPackageManager();PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(),PackageManager.GET_ACTIVITIES);if (pi != null) {String versionName = pi.versionName + "";String versionCode = pi.versionCode + "";infos.put("versionName", versionName);infos.put("versionCode", versionCode);}} catch (NameNotFoundException e) {Log.e(TAG, "an error occured when collect package info", e);}Field[] fields = Build.class.getDeclaredFields();for (Field field : fields) {try {field.setAccessible(true);infos.put(field.getName(), field.get(null).toString());} catch (Exception e) {Log.e(TAG, "an error occured when collect crash info", e);}}}/*** 保存错误信息到文件中* @param ex* @return 返回文件名称,便于将文件传送到服务器* @throws Exception*/private String saveCrashInfoFile(Throwable ex) throws Exception {StringBuffer sb = new StringBuffer();try {SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String date = sDateFormat.format(new java.util.Date());sb.append("\r\n" + date + "\n");for (Map.Entry<String, String> entry : infos.entrySet()) {String key = entry.getKey();String value = entry.getValue();sb.append(key + "=" + value + "\n");}Writer writer = new StringWriter();PrintWriter printWriter = new PrintWriter(writer);ex.printStackTrace(printWriter);Throwable cause = ex.getCause();while (cause != null) {cause.printStackTrace(printWriter);cause = cause.getCause();}printWriter.flush();printWriter.close();String result = writer.toString();sb.append(result);String fileName = writeFile(sb.toString());return fileName;} catch (Exception e) {Log.e(TAG, "an error occured while writing file...", e);sb.append("an error occured while writing file...\r\n");writeFile(sb.toString());}return null;}private String writeFile(String sb) throws Exception {String time = formatter.format(new Date());String fileName = "crash-" + time + ".log";if (FileUtil.hasSdcard()) {String path = getGlobalpath();File dir = new File(path);if (!dir.exists())dir.mkdirs();FileOutputStream fos = new FileOutputStream(path + fileName, true);fos.write(sb.getBytes());fos.flush();fos.close();}return fileName;}public static String getGlobalpath() {return Environment.getExternalStorageDirectory().getAbsolutePath()+ File.separator + "crash" + File.separator;}public static void setTag(String tag) {TAG = tag;}/*** 文件删除* @param day 文件保存天数*/public void autoClear(final int autoClearDay) {FileUtil.delete(getGlobalpath(), new FilenameFilter() {@Overridepublic boolean accept(File file, String filename) {String s = FileUtil.getFileNameWithoutExtension(filename);int day = autoClearDay < 0 ? autoClearDay : -1 * autoClearDay;String date = "crash-" + DateUtil.getOtherDay(day);return date.compareTo(s) >= 0;}});}}
package com.example.mycrashtest;import android.app.Application;public class MyAppcation extends Application{@Overridepublic void onCreate() {super.onCreate();CrashHandler.getInstance().init(this);}}

如此一来,java层的crash就能捕获了。

Native-C/C++层:

native crash具有上下文不全、出错信息模糊、难以捕捉等特点,比java crash更难修复。Android中JNI/NDK一般都是将c/c++生成so文件引入在java层调用c/c++的方法。当然也可以不这样。先看看so文件吧:

so 组成

一个完整的 so 由C代码加一些 debug 信息组成,这些debug信息会记录 so 中所有方法的对照表,就是方法名和其偏移地址的对应表,也叫做符号表,这种 so 也叫做未 strip 的,通常体积会比较大。一般release的 so 都是需要经过一个strip操作的,这样strip之后的 so 中的debug信息会被剥离,整个 so 的体积也会缩小。

如下图所示:

如下可以看到strip之前和之后的大小对比。

可以简单将这个debug信息理解为Java代码混淆中的mapping文件,只有拥有这个mapping文件才能进行堆栈分析。

如果堆栈信息丢了,基本上堆栈无法还原,问题也无法解决。

所以,这些debug信息尤为重要,是我们分析NE问题的关键信息,那么我们在编译 so 时候务必保留一份未被strip的so 或者剥离后的符号表信息,以供后面问题分析,并且每次编译的so 都需要保存,一旦产生代码修改重新编译,那么修改前后的符号表信息会无法对应,也无法进行分析。

获取 strip 和未被 strip 的 so

目前Android Studio无论是使用mk或者Cmake编译的方式都会同时输出strip和未strip的so,如下图是Cmake编译so产生的两个对应的so。

strip之前的so路径:build/intermediates/transforms/mergeJniLibs

strip之后的so路径:build/intermediates/transforms/stripDebugSymbol

另外也可以通过Android SDK提供的工具aarch64-linux-android-strip手动进行strip,aarch64-linux-android-strip这个工具位于/Users/njvivo/Library/Android/sdk/ndk/21.3.6528147/toolchains目录下。

现在看看具体的几种捕获:

logcat捕获

顾名思义,就是通过logcat进行捕获,我们通过Android Studio打开logcat,制造一个NE(NativeException),只能看到很多类似#00 pc 00000000000161a0的符号,并没有一个可以直接阅读的日志,我们想通过logcat直接输出一份可以直接阅读的log。

可以使用Android/SDK/NDK下面提供的一个工具ndk-stack,它可以直接将NE输出的log解析为可阅读的日志。

ndk-stack一般是位于ndk的工具下面,Mac下的地址为

/Users/XXXX/Library/Android/sdk/ndk/21.3.6528147/ndk-stack

然后在该目录下执行控制台命令,或者在 Android Studio的terminal中执行也可

adb shell logcat | androidsdk绝对路径/ndk-stack -sym so所在目录

如此控制台在应用发生NE的时候便会输出如下日志,由日志可以看出,崩溃对应的so以及对应的方法名,如果有c的源码,那么就很容易定位问题。

promote:~ njvivo$ adb shell logcat | ndk-stack -sym libbreakpad-core.so
********** Crash dump: **********
Build fingerprint: 'vivo/PD1809/PD1809:8.1.0/OPM1.171019.026/compil04252203:user/release-keys'
#00 0x00000000000161a0 /data/app/com.android.necase-lEp0warh8FqicyY1YqGXXA==/lib/arm64/libbreakpad-core.so (Java_com_online_breakpad_BreakpadInit_nUpdateLaunchInfo+16)
#01 0x00000000000090cc /data/app/com.android.necase-lEp0warh8FqicyY1YqGXXA==/oat/arm64/base.odex (offset 0x9000)
Crash dump is completed

其实ndk-stack这个工具原理就是内部集成利用了addr2line来实时解析堆栈并且显示在控制台中。

看到这里有的小伙伴就觉得那这个不是很简单,但是实际的崩溃场景一是不容易复现,二是用户的场景有时候很难模拟,那么线上的NE崩溃又该如何监测和定位呢,有两种方式。

通过DropBox日志解析--适用于系统应用

这个很简单,DropBox会记录JE,NE,ANR的各种日志,只需要将DropBox下面的日志传上来即可进行分析解决,下面贴上一份日志示例。

 解析方案1:

借助上述的ndk-stack工具,可以直接将DropBox下面的日志解析成堆栈,从中可以看出,崩溃在breakpad.cpp第111行的Crash()方法中。

ndk-stack -sym /Users/njvivo/Desktop/NE -dump data_app_native_crash@1605531663898.txt
********** Crash dump: **********
Build fingerprint: 'vivo/PD1809/PD1809:8.1.0/OPM1.171019.026/compil04252203:user/release-keys'
#00 0x00000000000161a0 /data/app/com.android.necase-lEp0warh8FqicyY1YqGXXA==/lib/arm64/libbreakpad-core.so (Java_com_online_breakpad_BreakpadInit_nUpdateLaunchInfo+16)
Crash()
/Users/njvivo/Documents/project/Breakpad/breakpad-build/src/main/cpp/breakpad.cpp:111:8
Java_com_online_breakpad_BreakpadInit_nUpdateLaunchInfo
/Users/njvivo/Documents/project/Breakpad/breakpad-build/src/main/cpp/breakpad.cpp:122:0
#01 0x00000000000090cc /data/app/com.android.necase-lEp0warh8FqicyY1YqGXXA==/oat/arm64/base.odex (offset 0x9000)
Crash dump is completed

解析方案2:

还是利用Android/SDK/NDK提供的工具linux-android-addr2line,这个工具位于/Users/njvivo/Library/Android/sdk/ndk目录下,有两个版本。

aarch64架构
/Users/njvivo/Library/Android/sdk/ndk/21.3.6528147/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/bin/aarch64-linux-android-addr2line
arm架构
/Users/njvivo/Library/Android/sdk/ndk/21.3.6528147/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-addr2line

命令使用方法如下,结合未被strip的so以及日志里面出现的堆栈符号00000000000161a0,同样可以解析出崩溃地址和方法。

aarch64-linux-android-addr2line -f -C -e libbreakpad-core.so 00000000000161a0Crash()
/Users/njvivo/Documents/project/Breakpad/breakpad-build/src/main/cpp/breakpad.cpp:111

 基于以上,看似也很简单,但是有一个致命的问题就是DropBox只有系统应用能访问,非系统应用根本拿不到日志,那么,非系统应用该怎么办呢?

通过BreakPad捕获解析--适用于所有应用

非系统应用可以通过google提供的开源工具BreakPad进行监测分析,CrashSDK也是采用的此种方式,可以实时监听到NE的发生,并且记录相关的文件, 从而可以将崩溃和相应的应用崩溃时的启动、场景等结合起来上报。

下面简单介绍一下BreakPad的使用方式。

BreakPad的实现功能

BreakPad主要提供两个个功能,NE的监听和回调,生成minidump文件,也就是dmp结尾的文件,另外提供两个工具,符号表工具和堆栈还原工具。

  • 符号表工具:用于从so中提取出debug信息,获取到堆栈对应的符号表。
  • 堆栈还原工具:用于将BreakPad生成的dump文件还原成符号,也就是堆栈偏移值。

这两个工具会在编译BreakPad源码的时候产生。

编译完之后会产生minidump_stackwalk工具,有些同学不想编译的话,Android Studio本身也提供了这个工具。

这个minidump_stackwalk程序在Android Studio的目录下面也存在,可以拿出来直接使用,如果不想编译的话,直接到该目录下面取即可,Mac路径为:

/Applications/Android Studio.app/Contents/bin/lldb/bin/minidump_stackwalk

BreakPad的捕获原理

由上述可以得知,BreakPad在应用发生NE崩溃时,可以将NE对应的minidump文件写入到本地,同时会回调给应用层,应用层可以针对本次崩溃做一些处理,达到捕获统计的作用,后续将minidump文件上传之后结合minidump_stackwalk以及addr2line工具可以还原出实际堆栈,示意图如下:

 在应用发生NE时,BreakPad会在手机本地生成一个dump文件,如图所示:

 得到了以上文件,我们只能知道应用发生了NE,但是这些文件其实是不可读的,需要解析这些文件。

下面着重讲一下如何分析上面产生的NE:

1、获取NE崩溃的dump文件,将刚才得到的minidump_stackwalk和dump文件放在同一个目录,也可以不放,填写路径的时候填写绝对路径即可。

然后在该目录下的终端窗口执行以下命令,该命令表示用minidump_stackwalk解析dump文件,解析后的信息输出到当前目录下的crashLog.txt文件。

./minidump_stackwalk xxxxxxxx.dmp >crashLog.txt

2、执行完之后,minidump_stackwalk会将NE的相关信息写到crashLog.txt里面,详细信息如图所示:

3、根据解析出的NE信息,关注图中红框,可以得知,这个崩溃发生的 libbreakpad-core.so 里面,0x161a0代表崩溃发生在相对根位置偏移161a0的位置。

获取崩溃堆栈

1、利用之前提到的addr2line工具,可以根据发生Crash的so文件以及偏移地址(0x161a0)可以得出产生crash的方法、行数和调用堆栈关系。

2、在其根目录对的终端窗口运行以下命令。

arm-linux-androideabi-addr2line -C -f -e ${SOPATH} ${Address}
-C -f           //打印错误行数所在的函数名称
-e                //打印错误地址的对应路径及行数
${SOPATH}         //so库路径
${Address}        //需要转换的堆栈错误信息地址,可以添加多个,但是中间要用空格隔开,例如:0x161a0

3、如下图是真实运行的示例

aarch64-linux-android-addr2line -f -C -e libbreakpad-core.so 0x161a0
Crash()
/Users/njvivo/Documents/project/Breakpad/breakpad-build/src/main/cpp/breakpad.cpp:111

由上图可以知道,该崩溃发生在breakpad.cpp文件的第111行,函数名是Crash(),与真实的文件一致,崩溃代码如下:

void Crash() {volatile int *a = (int *) (NULL);*a = 1; //此处在代码里是111行
}extern "C"
JNIEXPORT void JNICALL
Java_com_online_breakpad_BreakpadInit_nUpdateLaunchInfo(JNIEnv *env, jobject instance,jstring mLaunchInfoStr_) {DO_TRY{Crash();const char *mLaunchInfoStr = env->GetStringUTFChars(mLaunchInfoStr_, 0);launch_info = (char *) mLaunchInfoStr;
//        env->ReleaseStringUTFChars(mLaunchInfoStr_, mLaunchInfoStr);}DO_CATCH("updateLaunchInfo");}

基于以上,便可以通过应用收集的dump文件解析的NE的详细堆栈信息。


Android NativeCrash 捕获与解析


http://chatgpt.dhexx.cn/article/8Qf89aPD.shtml

相关文章

服务器appcrash的问题怎么修复,电脑appcrash的问题怎么修复?

电脑是很复杂的程序代码设计的&#xff0c;因而有时会遇到一些奇怪的问题&#xff0c;而APPCRASH错误也是其中一种&#xff0c;如运行程序出现APPCRASH错误&#xff0c;我们在日志中查看事件名称为APPCRASH&#xff0c;这时很多朋友不知道怎么解决&#xff0c;下面小编和大家一…

iOS中“事件”的前因后果

iOS的事件是一个由触发行为到响应的过程。本文旨在表达事件如何处理响应&#xff0c;如何传递事件的。 1. 前言 国内智能手机要从2000年开始说起&#xff0c;手机的进化是飞速的&#xff0c;单从操作来看&#xff0c;最开始是数字实体键盘&#xff0c;后来出现了全字母的实体键…

AppCrash explorer问题(解决方法)

AppCrash 顾名思义 程序崩溃了 先上问题&#xff1a; 资源管理器不断地显示停止工作&#xff08;关闭后10s又出来报错&#xff09; 我也在网上找了很多资料&#xff0c;还去Google搜了一下&#xff0c;但我的错误和dll这个无关&#xff0c;修改注册表等方法都无法解决此问题&a…

win7 APPCRASH问题解决!

真是废了老劲了。。什么清理插件&#xff0c;各种运行msconfig/启动都试了 问题&#xff1a;**.exe已停止工作 问题事件名称: APPCRASH 应用程序名: compute_image_mean.exe 应用程序版本: 0.0.0.0 应用程序时间戳: 579c50f5 故障模块名称: MSVCR120.dll 故障模块版本: 12.0.21…

mysql安装appcrash_appcrash事件怎么解决-appcrash问题解决方法 - 系统家园

在电脑上运行程序的时候常常会遇到很多的问题然后提示appcrash错误&#xff0c;为此下面就给你们带来了appcrash问题解决方法&#xff0c;一直遇到这个问题的小伙伴就快来解决一下吧。 appcrash事件怎么解决&#xff1a; 方法一&#xff1a; 1、出现appcrash错误会提示给你故障…

程序崩溃APPcrash的问题

【问题】 小编在对接扫码枪枪的时候遇到了一个问题&#xff1a;拔出扫码枪的时候&#xff0c;有状态返回但是出现了这个错误&#xff1a; 【解决办法】 小编我真是心累的“狠”&#xff0c;但经过me的不辞辛苦还是找到了问题的根本&#xff1a; 一、厂家提供的环境 二、小编…

问题事件名称: APPCRASH(解决方法)

问题事件名称: APPCRASH(解决方法)(转&#xff09; 下面分享一下解决win7或者是Vista的一个刺手的问题 APPCRASH&#xff08;app是程序的意思&#xff0c;crash是坠机的意思。就是程序崩溃了/程序撞车……&#xff09; 我们使用软件的时候有时候会出现这种情况 举个例子 Dung…

appcrash事件怎么解决?三种方法教你

我们在电脑上运行程序的时候常常会遇到很多的问题然后提示appcrash错误&#xff0c;为此下面小编就给你们带来了appcrash问题解决方法&#xff0c;有遇到这个问题的小伙伴就快来解决一下吧。 appcrash事件怎么解决&#xff1f; 方法一 1、出现appcrash错误会提示给你故障模块&a…

LoadRunner9.1下载与破解

LoadRunner9.1下载与破解 上一篇 / 下一篇 2009-03-03 18:42:39 / 个人分类&#xff1a;测试工具 查看( 918 ) / 评论( 2 ) / 评分( 0 / 0 ) 一、Loadrunner下载地址&#xff1a; http://h30302.www3.hp.com/prdownloads/T7177-15005.iso?ordernumber380397475&itemid1&…

Loadrunner11破解详解 .

使用说明&#xff1a;要以管理员的身份运行 1、正常安装完LR11后。然后双击deletelicense.exe 2、然后解压替换其中的2个DLL文件拷贝到"C:\Program Files\HP\LoadRunner\bin\"下替换原有文件 3、进入LR&#xff0c;输入以上的序列号即可 global-100: AEACFSJI-YASEKJ…

LoadRunner11的安装与破解

现在很多人都在用LoadRunner11&#xff0c;下面我就来说说自己下载和安装LR11的过程。 一、安装 1.先来下载LR11.建议大家都在正规网站下载&#xff0c;推荐一个网站http://bbs.51testing.com/thread-423695-1-1.html&#xff0c;直接将此网站复制到迅雷下载http://www.genil…

Loadrunner11在win10下的安装、汉化与破解方法

Loadrunner11安装与破解方法 工具/原料 • HP Loadrunner 11.00 • 汉化包 • 破解文件 1 安装英文版 1.1 运行“setup.exe” 点击安装&#xff0c;其中会有提示缺少“Microsoft Visual C 2005 SP1运行组件”&#xff0c; 在“\lrunner\Chs\prerequisites\vc2005_sp1_redis…

loadrunner11基础使用

其实loadrunner11只要环境装好了&#xff0c;没那么多报错 装好Loadrunner后要用管理员权限打开&#xff0c;不然可能会报错 win10可以装lr12和12.5&#xff0c;但是无法破解&#xff0c;最大并发50人&#xff0c;还只有7天试用期&#xff0c;7天过了要重新装 loadrunner11中主…

loadrunner 11下载及破解

原文地址为&#xff1a; loadrunner 11下载及破解 1.下载参照文章&#xff1a; http://www.51testing.com/?uid-4827-action-viewspace-itemid-225451 2.破解参照文章&#xff1a; http://naotang.com/index.php?optioncom_content&viewarticle&id66:loadrunner11&a…

LoadRunner11的安装、破解以及基本使用

首先安装环境 除此之外没啥了&#xff0c;安装时会提示缺少什么组件&#xff0c;点击确认安装即可&#xff0c;剩下基本都是下一步就OK。 安装完成后自动启动会提示只剩余10天试用期 之后开始破解 选择“新许可证”,输入“ AEAMAUIK-YAFEKEKJJKEEA-BCJGI” 再次打开程序&…

LoadRunner测试工具大全下载,破解,licence

LoadRunner测试工具大全下载&#xff0c;破解&#xff0c;licence。 目前的版本有7.8&#xff0c;8.0&#xff0c;8.1下面是他们的下载地址&#xff0c;大家看自己的情况下载 安装程序资源 &#xff08;eMule资源&#xff09; 《工业标准级负载测试工具 LoadRunner》(LoadRunne…

loadrunner 11 的下载和安装与破解

Loadrunner安装详解 一 、 下载篇 下载地址是&#xff0c;这个是我自己搜集的&#xff0c;也可以安装其他版本&#xff1a; 链接&#xff1a;http://pan.baidu.com/s/1skGkzb3 密码&#xff1a;88uq loadrunner 12 链接: https://pan.baidu.com/s/1qXL4tFu 密码: cgrt …

loadrunner11.0 安装 破解

一 、下载(4G多):ed2k://|file|%5B%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95%E5%B7%A5%E5%85%B7LR11.00%5D.loadrunner-11.iso|4313382912|b95afeb3a879c6b8146435bb79e8cb97|hntupkaxx5ltzwovgdkv7uexj7ukal5hu|/ 二 、安装: 1.首先我安装了一个加载ISO光盘的虚拟光驱的工具: …

loaderrunner11.00安装与破解

在下面的链接里面下载安装包&#xff0c;语言包&#xff0c;以及破解程序 http://pan.baidu.com/s/1bnEQmEr 安装完安装包&#xff0c;语言包后&#xff0c;关键看怎么破解&#xff0c;步骤如下&#xff1a; 1. lm70.dll文件&#xff0c;覆盖\LoadRunner\bin下文件即可。 mlr5l…

Loadrunner安装破解

右键用软碟通加载 选择loadrunner安装镜像>打开 双击打开 setup >以管理员身份运行 完整安装&#xff0c;记得千万不要汉化 否&#xff0c;继续安装 默认&#xff0c;确定 默认&#xff0c;下一步 同意协议&#xff0c;下一步 用户信息&#xff0c;默认…