我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Android中jni如何调试打印char阵列

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Android中jni如何调试打印char阵列

这篇文章将为大家详细讲解有关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): testPrintMatrix08-03 18:46:03.101 D/345 (30611): 48 65 6c 6c 6f 2c 20 74 68 69 73 20 69 73 20 7008-03 18:46:03.101 D/345 (30611): 72 69 6e 74 5f 6d 61 74 72 69 78 27 73 20 74 6508-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

关于“Android中jni如何调试打印char阵列”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Android中jni如何调试打印char阵列

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Android中jni如何调试打印char阵列

这篇文章将为大家详细讲解有关Android中jni如何调试打印char阵列,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Android jni调试打印char阵列的实例详解前言:在android开发中,用
2023-05-30

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录