在方法出现异常时需要把传入参数值和本地变量值异导出来供分析。之前因为测试的对象都是普通的值,写的loadLocalVarArray能正常工作。
这几天要在方法进入时inject一个long startTime供在方法退出时计算方法方法执行时间,发现如果本地变量是long和double本地变量栈中实际
占用两个位置,而nextLocal和firstLocal是本地变量栈的地址位置,根本无法知道实际的本地变量个数和具体的索引。
当然用for(int i=0;i< nextLocal-firstLocal;i++){
try{ loadLocal(i+firstLocal) }catch(Exception ex){........}
}利用异常来判断是否有某个localIndex是可以牧举出来的,但是这样太猥琐了。
查看GeneratorAdapter发现有一个私有yojgList<Type> localTypes,在visit的时候,本地变量的type会被放在这个数组中。但是存放的方式几乎和栈中差不多。假如有三个double的亦是,栈中是:
firstLocal + 0
firstLocal + 2
firstLocal + 4
这样nextLocal-firstLocal是6,但是loadLocal(6)肯定出异常。而这个list也是把一个type set到对应的位置。这样它就需要把前面没有的地方填null.设置后是这样的:
0 J
1 null
2 J
3 null
4 J
这个list的长度是5,可以正确地 loadLocal(index).但是它是一个私有变量,我只好给GeneratorAdapter增加一个
public int getLocalLength(){
return this.localTypes.size();
}
说明:因为instrumention功能是独立天任何app的,它引用的库在premain中调用,那么如果应用中使用了同样的库而版本不同,则无法再载
入相同的类,因为premain在main之前已经载入了,为了防止版本冲突,我们是把其它 app常用库重新package进来的,这个工作是非常必要的,所以修改源码仍然可以接受。
有了这个getLocalLength()就好办了:
void loadVarArray() {
Type OBJECT_TYPE = Type.getObjectType("java/lang/Object");
int varCnt = getLocalLength();
if (varCnt == 0) { //返回一个空数组
push(0);
newArray(OBJECT_TYPE);
return;
}
/*
* 先检查栈的空位(long和double占两个位,其一个标记为null),如果直接用栈长度指定数组
* 则占位的位置为null,返回出去程序不知道是占位的null还是一个localVar的值为null
*/
int arrLen = 0;
for (int i = 0; i < varCnt; i++) {
Type t = getLocalType(super.firstLocal + i);
if (t != null)
arrLen++;
}
push(arrLen); //实际需要的数组长度
newArray(OBJECT_TYPE);
int arrIndex = 0;
for (int i = 0; i < varCnt; i++) {
int index = super.firstLocal + i;
Type t = getLocalType(index);
if (t == null)
continue;
dup();
push(arrIndex++);
loadLocal(index, t);
box(t);
arrayStore(OBJECT_TYPE);
}
}
这样正确地把所有本地变量加载到数组中(数组现在在操作栈的栈顶,你可以访问它了)。
完整的实现:
分享到:
相关推荐
本文将深入探讨C32Asm的功能、使用方法及其在实际应用中的重要性。 首先,我们需要了解什么是PE格式。PE是Windows操作系统下执行文件的标准格式,包含了程序运行所需的全部信息,如代码、数据、资源等。而反汇编则...
4. **断点与调试**:设置断点进行程序调试,观察执行过程中的变量变化和流程控制。 5. **脚本支持**:支持自定义脚本,可以自动化执行一系列操作,提高分析效率。 6. **导出与导入**:可以将反汇编结果导出为文本...
3. **符号解析**:C32ASM可能支持解析并显示函数名、变量名和其他符号信息,帮助用户理解代码逻辑。 4. **内存映射**:在反汇编过程中,工具会展示内存布局,包括段、堆和栈的分配情况,便于理解程序运行时的状态。...
对于 AIX 平台,采用以下方法管理 ASM 磁盘: 1. **创建和管理磁盘组**: - 使用 `asmca` 或 SQL*Plus 命令创建磁盘组。 - 根据需要设置冗余级别 (NORMAL 或 HIGH)。 2. **Standalone 方式使用**: - 在单个...
W32asm无极版在这一方面也有所建树,它支持动态调试,可以在程序运行时监控内存变化、API调用以及变量状态,这对于理解恶意软件在运行时如何执行其恶意行为至关重要。 除了去壳功能,W32asm无极版还包含了其他实用...
本文将深入探讨PE头文件的结构及其在ASM(汇编语言)中的实现,通过源码分析帮助你理解如何分析PE文件,尤其是exe格式的文件。 首先,我们需要了解PE文件的基本结构。一个PE文件主要由DOS头、PE头(NT头)和节区表...
在Oracle10g RAC(Real Application Clusters)与ASM(Automatic Storage Management)环境中,日常管理操作至关重要,确保了数据库的高效运行与集群的稳定性。本文将深入解析几个关键的管理命令,涵盖网络配置、...
标题中的"ASM tool Link.exe Masm.exe"提及的是两个在编程领域,特别是汇编语言编程中常用的工具。ASM是汇编语言(Assembly)的缩写,而Link.exe和Masm.exe则是微软提供的与之相关的实用程序。 Masm.exe,全称...
本文将分析在ARM架构下,如何在C语言中调用汇编语言方法,以及如何在汇编中使用C定义的全局变量。 首先,C语言中内嵌汇编是一种方便的方法,允许开发者利用汇编语言的优势来优化特定的性能瓶颈。在ARM处理器中,...
提供了强大的调试功能,如断点设置、单步执行、变量查看、内存查看等,这使得调试汇编代码变得如同调试高级语言一样简单。这对于理解程序运行机制和定位问题至关重要。 5. **资源管理** VisualASM支持资源的导入...
3. 汇编文件中,使用`AREA`定义代码段,`EXPORT`导出函数,`IMPORT`导入全局变量,如: ```assembly AREA asmfile, CODE, READONLY EXPORT asmDouble IMPORT gVar asmDouble ldr r0, =gVar ldr r1, [r0] mov r2,...
要在C中调用汇编函数,首先在C文件中声明函数原型并使用`extern`关键字,其次在汇编文件中用`EXPORT`导出函数名,确保函数名与C中的声明一致,便于C调用。汇编函数结束时使用`mov pc, lr`返回调用点。 示例:C调用...
2. **导出汇编函数**:在汇编文件中使用`EXPORT`指令导出函数名,并使用该函数名作为代码段的标识。 3. **函数调用**:在C代码中像调用普通C函数一样调用该汇编函数。 #### 实例分析 以下是一个具体的实例,展示...
导出命令应包含索引和行数据,并在出现问题时有备用的导出方法。 整个迁移方案中,数据的备份和恢复是至关重要的,因此在每个步骤之后,都需要进行验证和测试,以确保数据的完整性和系统的稳定运行。这个方案提供了...
1. `asm`:允许在C++程序中插入汇编代码,提供更低级别的控制,但使用时需谨慎,因为这会降低代码的可读性和可维护性。 2. `auto`:这是一个存储类型标识符,用于声明具有局部作用域的变量,比如在for循环内部声明...
1. `asm`: 这个关键字在早期的C++中用于嵌入汇编代码,但已被`__asm`替代。然而,现代C++更倾向于使用inline assembly或更高级的优化技术,如模板元编程,而不是直接使用汇编。 2. `auto`: 自动类型推断关键字,...
根据文件内容,开发过程中还需注意串口操作指令集、数据帧架构、寄存器配置、变量配置等关键知识点。 串口操作指令集包括了常用的通信指令,是人机界面与外部设备交互的重要手段。数据帧架构是串口通信的基础,为...
3.2.3本地注册表 3.3 Clusterware启动流程 3.3.1启动流程 3.3.2后台进程 3.4 Clusterware隔离机制 3.4.1 Clusterware心跳 3.4.2 Clusterware隔离特性IPMI 3.4.3 RAC隔离体系 3.5网格即插即用 3.5.1 GPnP...
1. `asm`:这个关键字允许程序员在C++程序中嵌入汇编代码,提供对底层硬件的直接控制,但使用时需谨慎,因为它可能导致代码难以理解和维护。 2. `auto`:`auto`用于声明变量,表明变量具有局部作用域,通常用于for...