一、前言

C/C++平时用的不多,写段代码就错误百出,最近写了一段文件读取的。运行的时候直接so挂掉了。网上百度了一下 FORTIFY: vsprintf: prevented write past end of buffer 报错一般是由于传入的参数的问题。这里像下面的这样的so崩溃的堆栈打印 怎么去定位分析呢。这里介绍一个实用的工具 addr2line

--------- beginning of crash
05-21 14:36:18.879  4405  4434 F libc    : FORTIFY: vsprintf: prevented write past end of buffer
05-21 14:36:18.879  4405  4434 F libc    : Fatal signal 6 (SIGABRT), code -6 in tid 4434 (Thread-8)
05-21 14:36:18.880  1714  1714 W         : debuggerd: handling request: pid=4405 uid=10038 gid=10038 tid=4434
05-21 14:36:18.959  4466  4466 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
05-21 14:36:18.960  4466  4466 F DEBUG   : Build fingerprint: 'PAX/tulip_pax/tulip-pax:7.1.1/NMF26X/20220520:userdebug/release-keys'
05-21 14:36:18.960  4466  4466 F DEBUG   : Revision: '0'
05-21 14:36:18.960  4466  4466 F DEBUG   : ABI: 'arm64'
05-21 14:36:18.960  4466  4466 F DEBUG   : pid: 4405, tid: 4434, name: Thread-8  >>> com.example.myapplication <<<
05-21 14:36:18.960  4466  4466 F DEBUG   : signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
05-21 14:36:18.967  4466  4466 F DEBUG   : Abort message: 'FORTIFY: vsprintf: prevented write past end of buffer'
05-21 14:36:18.967  4466  4466 F DEBUG   :     x0   0000000000000000  x1   0000000000001152  x2   0000000000000006  x3   0000000000000008
05-21 14:36:18.967  4466  4466 F DEBUG   :     x4   0000000000000000  x5   0000000000000000  x6   0000000000808080  x7   0000000000000030
05-21 14:36:18.967  4466  4466 F DEBUG   :     x8   0000000000000083  x9   ffffffffffffffdf  x10  0000000000000000  x11  0000000000000001
05-21 14:36:18.967  4466  4466 F DEBUG   :     x12  ffffffffffffffff  x13  0000000000000000  x14  0000000000000000  x15  0034680550cd3842
05-21 14:36:18.967  4466  4466 F DEBUG   :     x16  00000072e9897ee0  x17  00000072e98412e4  x18  00000000ffffffff  x19  00000072cf2954f8
05-21 14:36:18.967  4466  4466 F DEBUG   :     x20  0000000000000006  x21  00000072cf295450  x22  0000000000000009  x23  00000072e1eb2139
05-21 14:36:18.967  4466  4466 F DEBUG   :     x24  00000072e788d0e0  x25  00000072e1eb214a  x26  00000072d4dde853  x27  6be61a7d50c6d729
05-21 14:36:18.967  4466  4466 F DEBUG   :     x28  00000072e78130b0  x29  00000072cf2939f0  x30  00000072e983e78c
05-21 14:36:18.967  4466  4466 F DEBUG   :     sp   00000072cf2939d0  pc   00000072e98412ec  pstate 0000000060000000
05-21 14:36:18.975  4466  4466 F DEBUG   : 
05-21 14:36:18.975  4466  4466 F DEBUG   : backtrace:
05-21 14:36:18.975  4466  4466 F DEBUG   :     #00 pc 000000000006b2ec  /system/lib64/libc.so (tgkill+8)
05-21 14:36:18.975  4466  4466 F DEBUG   :     #01 pc 0000000000068788  /system/lib64/libc.so (pthread_kill+64)
05-21 14:36:18.975  4466  4466 F DEBUG   :     #02 pc 0000000000023ce8  /system/lib64/libc.so (raise+24)
05-21 14:36:18.975  4466  4466 F DEBUG   :     #03 pc 000000000001c76c  /system/lib64/libc.so (abort+52)
05-21 14:36:18.975  4466  4466 F DEBUG   :     #04 pc 0000000000020cf4  /system/lib64/libc.so (__libc_fatal+104)
05-21 14:36:18.975  4466  4466 F DEBUG   :     #05 pc 0000000000020c88  /system/lib64/libc.so (__fortify_chk_fail+52)
05-21 14:36:18.975  4466  4466 F DEBUG   :     #06 pc 00000000000743cc  /system/lib64/libc.so (__sprintf_chk+192)
05-21 14:36:18.975  4466  4466 F DEBUG   :     #07 pc 000000000004cc3c  /system/lib64/libpaxapijni.so (readExternalLogtoFile+972)
05-21 14:36:18.975  4466  4466 F DEBUG   :     #08 pc 0000000000036968  /system/lib64/libpaxapijni.so (Java_pax_util_OsPaxApi_getAppLogs+188)
05-21 14:36:18.975  4466  4466 F DEBUG   :     #09 pc 0000000000799b50  /data/app/com.example.myapplication-1/oat/arm64/base.odex (offset 0x733000)

二、初步分析:定位报错的代码位置


这里我们可以看到报错的方法是libpaxapijni.so文件里面的 readExternalLogtoFile方法,这个readExternalLogtoFile 是我写的一个读写文件的方法。libc.so (__sprintf_chk+192) 这里我预感是sprintf 这个方法出的错。下面用add2line方法具体定位一下。

05-21 14:36:18.975  4466  4466 F DEBUG   :     #06 pc 00000000000743cc  /system/lib64/libc.so (__sprintf_chk+192)
05-21 14:36:18.975  4466  4466 F DEBUG   :     #07 pc 000000000004cc3c  /system/lib64/libpaxapijni.so (readExternalLogtoFile+972)

三、add2line定位具体报错的行数


1、首选查找报错的so在 out下面的路径 ,我这是out/target/product/tulip-pax/symbols/system/lib64/libpaxapijni.so 注意要用symbols 下的 lib64位的。

songzhihao@ubuntu:~/im30-project/android$ find out/ -name libpaxapijni.so
out/target/product/tulip-pax/symbols/system/lib/libpaxapijni.so
out/target/product/tulip-pax/symbols/system/lib64/libpaxapijni.so
out/target/product/tulip-pax/obj_arm/lib/libpaxapijni.so

2、查看 报错的行地址数,上面的报错log里面可以看到 #07 pc 000000000004cc3c /system/lib64/libpaxapijni.so (readExternalLogtoFile+972) 报错地方地址是000000000004cc3c

3、在Android代码根目录下执行命令

addr2line -f -e out/target/product/tulip-pax/symbols/system/lib64/libpaxapijni.so 000000000004cc3c

执行结果很明显了,151行然后去看看哪一行哪里的问题吧,我这是
sprintf(networkLogFile,"%s/%s",NETWORK_LOG_DIR,ptr->d_name); networkLogFile 数组的长度是48,但是拷贝进去的字符超过48了,所以报错,改大数组的长度就OK了,掌握了方法还是非常简单的。

readNetworkLogFile
/proc/self/cwd/paxdroid/external/paxdroid-log/external_log.c:151

四、写在最后如果对你有帮助的话点个赞粉一个吧。

更多推荐

使用addr2line 定位 FORTIFY: vsprintf: prevented write past end of buffer‘ 报错解决思路