AOSP测试用例之可见性问题

一、前言

1.1 背景

最近在学习Hook技术,想了解一下在实现JavaHook时,将Java方法转成Native方法时,需要修改ArtMethod对象的成员变量的值。为了弄清楚变量的偏移,笔者在AOSP中写了一个可执行(以下简称"Demo“),用于计算这个偏移量(对于有C、C++语言基础的开发者来说,这个答案可能一眼就能看出来,哈哈)。

在做这个事情的过程中,遇到了一些小问题,故记录一下,形成本文。

1.2 Demo目录结构

在这里插入图片描述

笔者在将demo放置在了 AOSP 目录下的 development中,而要使用的ArtMethod类却在art目录下。

也正是因为这种目录的隔离,导致了编译时的可见性问题,后面会说一下这个问题的如何解决的。

二、简述Demo内容的实现

demo的内容很简单,就两个文件:一个Android.bp , 另一个源文件。

//art_method_test.cpp

#include <iostream>
#include "../../art/runtime/art_method.h"  // 使用源码树中的原始路径
#include <cstddef>
int main() {

    std::cout << "ArtMethod内存布局验证:" << std::endl;
    std::cout << "sizeof(ArtMethod): " << sizeof(art::ArtMethod) << std::endl;
    std::cout << "declaring_class_ offset: " 
              << offsetof(art::ArtMethod, declaring_class_) << std::endl;
    std::cout << "access_flags_ offset: " << offsetof(art::ArtMethod, access_flags_) << std::endl;
    std::cout << "ptr_sized_fields_ offset: " << offsetof(art::ArtMethod, ptr_sized_fields_) << std::endl;
    std::cout << "PtrSizedFields sizeof: " << sizeof(art::ArtMethod::PtrSizedFields) << std::endl;
    return 0;
}

上述内容很简单,offsetof是cstddef头文件中定义的一个宏,用来计算字段偏移的。 接下来,看一下Android.bp中的内容:

cc_test {
    name: "art_method_layout_test",
    srcs: ["art_method_test.cpp"],

    static_libs: [
        "libartbase",
        "libart",
        "libdexfile",
    ],

    header_libs:[
      "libbase_headers",
    ],

    cflags: [
        "-fno-access-control",
		"-Wall",
        "-Werror",
      //  "-Iart/runtime/", 
    ],
    required: ["art"],
    compile_multilib: "both",  // 同时编译32/64位
}

如上面所示,Android.bp文件指明了 源文件、以及其依赖库、需要引入的头文件以及编译时需要的cpp flags。

然后,进行编译:

$ mm development/shark_art_method_test/

输出目录: out/target/product/rk3568_s/data/nativetest64/art_method_layout_test/art_method_layout_test , 然后上传到手机上,进行运行。

三、遇到的问题

  • 跨模块导致的可见性问题
  • ArtMethod成员不可见问题

3.1 跨模块导致的可见性问题

由于Demo 依赖着"libartbase"、“libart”、“libdexfile” , 并且这些库都是art目录内可见,因此需要将这些库的Android.bp的可见性,增加”//development/shark_art_method_test/“,或者改为”全项目可见“ :

// <AOSP>/art/libartbase/Android.bp
art_cc_library {
    name: "libartbase",
    ...
    visibility: [
	    ...
        "//development/shark_art_method_test",
    ],
    ...
}

// <AOSP>/art/runtime/Android.bp
art_cc_library {
    name: "libart",
	...
    visibility: ["//visibility:public"],
    ...
}

// <AOSP>/art/libdexfile/Android.bp
art_cc_library {
    name: "libdexfile",
    visibility: [
	    ...
        "//development/shark_art_method_test",
		...
    ],
    ...
}

3.2 ArtMethod成员不可见问题

class ArtMethod final {

 ...
 
 protected:

  GcRoot<mirror::Class> declaring_class_;

  std::atomic<std::uint32_t> access_flags_;
  
  uint32_t dex_method_index_;
  
  uint16_t method_index_;

  union {
    uint16_t hotness_count_;
    uint16_t imt_index_;
  };
  
  struct PtrSizedFields {
    void* data_;

    void* entry_point_from_quick_compiled_code_;

  } ptr_sized_fields_;
  ...
};

ArtMethod类中,我们期望访问的成员 declaring_class_、access_flags_ 等,都是protected , 因为对于 外部的类,是无法访问到,因此可以在编译时,增加 编译选项 “-fno-access-control”, 来突破这个限制。

cc_test {
    name: "art_method_layout_test",
	...
    cflags: [
        "-fno-access-control",
		...
    ],
    ...
}

四、总结

文中的程序,很简单。就是遇到的这两种可见性,需要额外处理一下:

  • AOSP模块间的可见性, 可以通过Android.bp的visibility进行配置;
  • C++语法的可见性,需要指明 ”-fno-access-control“ 来突破限制;

这里可能还有一种简洁的方式: 修改art目录下的Android.bp ,增加可见性。笔者没有进行尝试,但是笔者查看了一下art子模块的都默认继承了art顶层的Android.bp协议了。

五、写在最后

一个普通的老Androider, 再卷一把,加油2025, 干中学! 欢迎一起探讨大前端技术(Android、Framework、HarmonyOS、Flutter 甚至是前端)!

未完待续,笔者会分享AOSP编译相关的知识,敬请期待!

极化码(Polar Code)是由土耳其科学家Erdal Arıkan在2009年提出的一种新型纠错编码技术。它通过利用信道的极化现象,将虚拟信道分为误码率接近0和接近1/2的两类。在编码设计中,数据被放置在误码率极低的信道上,从而实现高效的数据传输。极化码的主要优势在于其理论编码容量能够达到香农限,并且构造方法较为简单。 MATLAB是一种功能强大的数学计算和编程工具,广泛应用于科学研究和工程领域。在极化码的研究中,MATLAB可用于构建编码和解码算法,模拟数据在不同信道条件下的传输效果,验证理论性能,并优化相关参数。 SC(Successive Cancellation,逐位取消)译码是极化码的基本解码方法。它从最可靠的比特开始,依次解码每个虚拟信道,且每个比特的解码结果会影响后续比特的解码,因为它们之间存在依赖关系。虽然SC译码的实现较为简单,但其计算复杂度较高,随着码长的增加,解码时间会线性增长。 SCL(Successive Cancellation List,逐位取消列表)译码是SC译码的改进版本。它通过引入列表机制,同时处理多个路径,从而增强了错误校正能力,并在一定程度上降低了错误率。与SC译码相比,SCL译码虽然需要消耗更多的计算资源,但能够提供更好的性能。 一个完整的MATLAB仿真资源通常含以下内容: 编码模块:用于实现极化码的生成,括码字构造和极化矩阵操作等。 信道模型:用于模拟各种通信信道,例如AWGN(加性高斯白噪声)信道或衰落信道。 SC/SCL译码模块:含SC译码和SCL译码的算法实现。 误码率(BER)计算:通过比较发送和接收的码字,计算误码率,以评估编码性能。 性能曲线绘制:绘制误码率与信噪比(SNR)之间的关系曲线,展示不同译码策略的性能差异。 使用说明:指导用户如何运行仿真,理解代码结构,以及如何调整参数以进行自定义实验。 代码注
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值