Android jni调试打印char阵列的实例详解
作者:二流小宝 发布时间:2022-06-18 14:55:40
标签:Android,jni,char阵列
Android jni调试打印char阵列的实例详解
前言:
在android开发中,用jni有时候需要打印某一个字符串的二进制格式输出,比较友好的输出格式是一个四列,八列,十六列的矩阵格式。类似在错误删除野指针时出现如下错误:
pid: 2721, tid: 3005, name: pool-5-thread-5 >>> onxmaps.hunt <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadbaad
Abort message: 'invalid address or address of corrupt block 0x7e31e028 passed to dlfree'
r0 00000000 r1 4011917a r2 deadbaad r3 4011cd0d
r4 7e31e028 r5 40127190 r6 41b54000 r7 7e31e030
r8 00000003 r9 7ed97bb5 sl 00000001 fp 7ed97bb9
ip 00000001 sp 82a7d9c0 lr 400ea873 pc 400ea874 cpsr 600f0030
d0 2064696c61766e69 d1 2073736572646461
d2 657264646120726f d3 6f6320666f207373
d4 3fd34413509f79fb d5 41568f570e698a86
d6 412e848000000000 d7 00000400fb561fc7
d8 7ff0000000000000 d9 41568c0b304b0668
d10 408f400000000000 d11 0000000000000000
d12 0000000000000000 d13 0000000000000000
d14 0000000000000000 d15 0000000000000000
d16 c07422af5ad9a77f d17 010001ff0d000013
d18 6743a514430fcb23 d19 657fcd52992ddb94
d20 4820450ad34fbe9e d21 a2fe0391c1ee451b
d22 bf5544b8ce928c56 d23 d4404b0a8749e7f1
d24 3fd5555555555555 d25 391377ce858a5d48
d26 bca0000000000000 d27 3940000000000000
d28 3ff0000000000000 d29 bef375cbdb605373
d30 412e848000000000 d31 3fd5555555555563
scr 60000013
backtrace:
#00 pc 00011874 /system/lib/libc.so (dlfree+1191)
#01 pc 0000dd13 /system/lib/libc.so (free+10)
#02 pc 00082485 /system/lib/libcrypto.so (CRYPTO_free+24)
#03 pc 0002aa85 /system/lib/libssl.so (ssl_parse_serverhello_tlsext+244)
#04 pc 00016bbd /system/lib/libssl.so (ssl3_get_server_hello+904)
#05 pc 000196bf /system/lib/libssl.so (ssl3_connect+642)
#06 pc 00024f55 /system/lib/libssl.so (SSL_do_handshake+72)
#07 pc 0000c67f /system/lib/libjavacrypto.so
#08 pc 00020bcc /system/lib/libdvm.so (dvmPlatformInvoke+112)
#09 pc 00051927 /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+398)
#10 pc 0002a060 /system/lib/libdvm.so
#11 pc 00031510 /system/lib/libdvm.so (dvmMterpStd(Thread*)+76)
#12 pc 0002eba8 /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184)
#13 pc 00063e75 /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)+336)
#14 pc 00063e99 /system/lib/libdvm.so (dvmCallMethod(Thread*, Method const*, Object*, JValue*, ...)+20)
#15 pc 00058b6b /system/lib/libdvm.so
#16 pc 0000d278 /system/lib/libc.so (__thread_entry+72)
#17 pc 0000d410 /system/lib/libc.so (pthread_create+240)
code around pc:
400ea854 6a014478 62021e4a f7fdb95a e008fd39
400ea864 4621482a 44784a2a f001447a 4a13f9b3
400ea874 49286014 f8d14479 079a31bc f501d51c
400ea884 e8bd70e0 f02c40f8 4823b895 f7fd4478
400ea894 4822fd0d e7fa4478 42b7688f ae10f43f
400ea8a4 481fe611 e7f24478 4478481e 6888e7ef
400ea8b4 f43f4298 e606aed4 bf00bdf8 deadbaad
400ea8c4 0003cdae 0003cda0 0003cd08 0003283b
400ea8d4 0003cc7c 0003cc6a 0003cbf2 0003cbd0
400ea8e4 0003cb74 0003cb5e 0003caf8 0003cae0
400ea8f4 0003cace 0003ca76 0003ca50 0003c9c6
400ea904 0003c970 0003c956 0003c938 0002e90c
400ea914 0003249d 0003c914 00032479 00032471
400ea924 00032461 0003245b 460db538 b1704601
400ea934 0200ea45 f405fb00 04030c10 4620b143
400ea944 ef24f028 bf1842a8 34fff04f 4604e000
code around lr:
400ea850 482e61a3 6a014478 62021e4a f7fdb95a
400ea860 e008fd39 4621482a 44784a2a f001447a
400ea870 4a13f9b3 49286014 f8d14479 079a31bc
400ea880 f501d51c e8bd70e0 f02c40f8 4823b895
400ea890 f7fd4478 4822fd0d e7fa4478 42b7688f
400ea8a0 ae10f43f 481fe611 e7f24478 4478481e
400ea8b0 6888e7ef f43f4298 e606aed4 bf00bdf8
400ea8c0 deadbaad 0003cdae 0003cda0 0003cd08
400ea8d0 0003283b 0003cc7c 0003cc6a 0003cbf2
400ea8e0 0003cbd0 0003cb74 0003cb5e 0003caf8
400ea8f0 0003cae0 0003cace 0003ca76 0003ca50
400ea900 0003c9c6 0003c970 0003c956 0003c938
400ea910 0002e90c 0003249d 0003c914 00032479
400ea920 00032471 00032461 0003245b 460db538
400ea930 b1704601 0200ea45 f405fb00 04030c10
400ea940 4620b143 ef24f028 bf1842a8 34fff04f
谷歌的工程师非常老道,在code around pc以下就是一个五列矩阵,这种打印格式的可读性比较强。最近项目中需要使用加密算法,因此调试时打印矩阵是一种不错的选择。由于android jni提供的接口时
__android_log_write
每次打印都会一行,不会像printf方便。因此需要对__android_log_write进行二次封装。思路就是先申请一段空间,然后把打印的内容存储在该内存中,最后log输出。
具体代码如下:
#include <android/log.h>
#include <cstring>
#include <cstdlib>
// 一般定义在公共文件
#define ldebug(tag, format, ...) {__android_log_write(tag, format, ##__VA_ARGS__);}
#define TAG "345"
void print_matrix(char *text, size_t size) { // 打印16列的矩阵
char temp[16] = {0};
size_t lines = (size + 15) / 16; // 保证打印的整行的矩阵
lines = lines > 0 ? lines : 1; // 最小为一
const size_t LEN = lines * 16 * 3 + 1; // 给打印buf申请足够的buffer。 乘3是因为打印时传入的每个字符char字符占三个位置。见注释AB
char *buf = (char*)malloc(LEN * sizeof(char));
if (NULL == buf) {
return;
}
memset(buf, 0, LEN);
int n = 0;
for (size_t i = 0; i < lines * 16; i++) {
if (16 == n) {
strcat(buf, "\n");//注释A:占一个字符
n = 0;
}
if (n > 0 && i > 0) {
strcat(buf, " ");//注释A:占一个字符
}
memset(temp, 0, 16);
if (i < size) { // 在text字符串内则打印字符串内容,超过text长度则打印00
snprintf(temp, 16, "%02x", *(text + i));//注释B:占两个字符
} else {
snprintf(temp, 16, "%02x", 0);//注释B:占两个字符
}
strcat(buf, temp);
++n;
}
*(buf + LEN - 1) = '\0'; // 注意字符串结束
ldebug(TAG, "%s", buf);
free(buf);
buf = NULL;
}
测试调用代码
void testPrintMatrix() {
char temp[] = "Hello, this is print_matrix's test case.";
print_matrix(temp, sizeof(temp));
}
输出结果
08-03 18:46:03.101 D/345 (30611): testPrintMatrix
08-03 18:46:03.101 D/345 (30611): 48 65 6c 6c 6f 2c 20 74 68 69 73 20 69 73 20 70
08-03 18:46:03.101 D/345 (30611): 72 69 6e 74 5f 6d 61 74 72 69 78 27 73 20 74 65
08-03 18:46:03.101 D/345 (30611): 73 74 20 63 61 73 65 2e 00 00 00 00 00 00 00 00
说明,因为使用<android/log.h>记得在Android.mk添加
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog
如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
来源:http://blog.csdn.net/sweettool/article/details/76651910


猜你喜欢
- 本文实例讲述了C#敏感词过滤实现方法。分享给大家供大家参考。具体如下:这两天突然想到了敏感词过滤 就结合网上找到的资料自己写了一个,脏字数量
- 需要用到 java 写一个 ftp 的工具,因为只有一点点 java 基础,但是由于好几年不用,几乎算是不会了,只好一点点来搞,还好能捡起来
- 使用对象初始值设定项初始化对象可以使用对象初始值设定项以声明方式初始化类型对象,而无需显式调用类型的构造函数。下面的示例演示如何将对象初始值
- 前言这里用swing ,awt写的。我们大概要做成一个电脑的记事本那样的一个编辑器。可以调整字体,字号,颜色。能够打开、保存文件,新建窗口,
- 目录1、二分查找算法思想2、二分查找图示说明3、二分查找优缺点3、java代码实现3.1 使用递归实现3.1 不使用递归实现(while循环
- 前言最近做了一个调查问卷导出的功能,需求是将维护的题目,答案,导出成word,参考了几种方案之后,选择功能强大的freemarker+固定格
- Java Set集合的遍历及实现类的比较Java中Set集合是一个不包含重复元素的Collection,首先我们先看看遍历方法package
- 为了解决在多个窗口之间的传值问题,我们可以通过设置静态类和静态变量的办法来实现窗口间值的传递窗体一代码//窗体1的代码using Syste
- scheduleAtFixedRate(task,time,period)task-所要安排的任务 time-首次执行任务的时间 perio
- 本文简单介绍如何引入validation的步骤,如何通过自定义validation减少代码量,提高生产力。特别提及:非基本类型属性的vali
- 随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了。近年来,随着HTML5的诞生,WebSocket协议被提出,它实
- TabHost控件默认使用LinearLayout包裹TabWidget和FrameLayout,布局文件如下:<TabHost xm
- 我最近上班又遇到一个小难题了,就是如题所述:ViewPager预加载的问题。相信用过ViewPager的人大抵都有遇到过这种情况,网上的解决
- 有时候,我们需要制作一个Word模板文档,然后发给用户填写,但我们希望用户只能在指定位置填写内容,其他内容不允许编辑和修改。这时候我们就可以
- List 是在开发中比较常用的集合,今天总结一下 Java 中初始化 List 的几种方式。1、常规方式List<String>
- Android 5.0 后用 Battery Historian 工具分析电量。耗电因素移动网络请求手机通过内置的射频模块和基站联系,从而链
- 目录实现基础_routeNamed_flushHistoryUpdatesaddpushpopremove总结整个 flutter 应用的运
- 本文实例为大家分享了android实现简单时钟的具体代码,供大家参考,具体内容如下attrs定义如下<?xml version=&qu
- java后端介绍今天我正式开始了一个新话题,那就是 Web。目前我主要会介绍后端。作为后端的老大哥 java,也有很多后端框架,比如大家耳熟
- 以前使用HttpServletResponse可以通过输出流的方式来向前台输出图片。现在大部分都是使用springboot,在使用sprin