当前位置: 首页 > 编程笔记 >

Android jni调试打印char阵列的实例详解

齐朝明
2023-03-14
本文向大家介绍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): 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

如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

 类似资料:
  • 问题内容: 这可能是一个简单的修复程序,但我只是没有看到它。我想弄清楚,如何从主体正确打印我的方法?我需要获取,设置和返回方法吗?另外,在课堂上我的while循环是否甚至必要? 该程序会编译并一直运行到无穷大,因此我猜while循环是错误的。但是它也仅在每行上连续打印。 扩展main的类是不相关的,并且是项目的一部分。抱歉,如果张贴错误,谢谢您的帮助。 整个程序的输出类似于: 树皮,树皮。 喵喵。

  • 希望有人能帮我做这件事,我对Java很在行。我的问题是,当我打印数组时,会得到一些字符,我想打印数组中的点数。(请忽略不相关的代码,我甚至还没有完成)

  • 本文向大家介绍java打印出菱形图案实例详解,包括了java打印出菱形图案实例详解的使用技巧和注意事项,需要的朋友参考一下 第一步:首先对图像进行解析 想要打印该图形必须要进行多层循环嵌套,分两个部分进行打印。 第一部分为上半部分前四行,他们是递增的关系,后半部分后三行为递减关系,由此可以得出我们需要写两个打的循环。并且由于“*”位置的关系,我们必须带入空格同时打印。所以每个部分需要两个循环控制,

  • 本文向大家介绍Java编程实现打印螺旋矩阵实例代码,包括了Java编程实现打印螺旋矩阵实例代码的使用技巧和注意事项,需要的朋友参考一下 直接上代码吧。 昨晚腾讯在线测试遇到的题。 螺旋矩阵是指一个呈螺旋状的矩阵,它的数字由第一行开始到右边不断变大,向下变大,向左变大,向上变大,如此循环。 总结 以上就是本文关于Java编程实现打印螺旋矩阵实例代码的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续

  • 本文向大家介绍Java如何调用TSC打印机进行打印详解,包括了Java如何调用TSC打印机进行打印详解的使用技巧和注意事项,需要的朋友参考一下 前言 最近项目中用到了打印机,最开始的完全不懂,现在弄好了,所以做了总结,该篇包括后台的调用打印(两种方式)跟前端的js的打印,但是只有IE现在支持打印,而且如果想远程连接打印机,二维码的生成和直接由打印机的命令进行操作,就要把修改浏览器的安全配置,下面再

  • 问题内容: 我得到以下代码: 这应该在从文件中逐字读取单词时进行大量计数。但是,当我最终尝试将数组打印到终端时,只需检查它是否还可以,然后再开始使程序能够将其写入文本文件,它只会给出一个错误,内容为:[Ljava。 lang.String; @ 163de20但是我不知道在这种情况下如何以及在哪里检查错误?有什么帮助吗? 问题答案: 这不是错误…这是Object类的默认toString()实现返回