前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >全志V853芯片 Tina Linux下网络ADB内存泄露如何修复?

全志V853芯片 Tina Linux下网络ADB内存泄露如何修复?

作者头像
阿志小管家
发布2024-02-02 17:27:12
1540
发布2024-02-02 17:27:12
举报
文章被收录于专栏:全志嵌入式那些事

1.主题

Tina Linux 网络ADB内存泄露修复

2.问题背景

硬件:V853 软件:Tina4.0 Linux-4.9 背景:使用网络adb时,反复connect disconnect,会发生内存泄露的问题。

3.问题描述

3.1复现步骤

1、首先使能网络ADB功能。

代码语言:javascript
复制
killall adbd
export ADB_TRANSPORT_PORT=5555
/bin/adbd -D > /dev/null &

2、连接无线网络,保持小机与测试电脑处于同一个局域网中。 由于每款产品连接无线网络的命令不大一致,因此此处就不对网络连接进行赘述了。

3、编写bat脚本,进行压测。

代码语言:javascript
复制
:loop
adb disconnect
adb connect 192.168.0.101
adb disconnect
timeout /t 3
goto :loop
pause

4、使用内存泄露工具查看内存是否泄露。

3.2具体表现

使用内部一款内存泄露工具观察adbd工具内存占用情况:

代码语言:javascript
复制
行 2499: 632        504        74         /bin/adbd
行 2539: 632        504        74         /bin/adbd
行 2581: 632        504        74         /bin/adbd
行 2629: 632        504        74         /bin/adbd
行 2672: 632        504        74         /bin/adbd
行 2711: 632        504        74         /bin/adbd
行 2753: 632        504        74         /bin/adbd
行 2796: 632        504        74         /bin/adbd
行 2841: 632        504        74         /bin/adbd
行 2881: 632        504        74         /bin/adbd
行 2921: 632        504        74         /bin/adbd
行 2961: 632        504        74         /bin/adbd
行 3008: 632        504        74         /bin/adbd
行 3047: 632        504        74         /bin/adbd
行 3091: 632        504        74         /bin/adbd
行 3131: 632        504        74         /bin/adbd
行 3181: 632        504        74         /bin/adbd
行 3221: 632        504        74         /bin/adbd
行 3265: 632        504        74         /bin/adbd
行 3309: 632        504        74         /bin/adbd
行 3349: 632        504        74         /bin/adbd
行 3399: 632        504        74         /bin/adbd
行 3439: 632        504        74         /bin/adbd
行 3483: 632        504        74         /bin/adbd
行 3523: 632        504        74         /bin/adbd
行 3574: 632        504        74         /bin/adbd
行 3614: 632        504        74         /bin/adbd
行 3654: 632        504        74         /bin/adbd
行 3694: 632        636        206        /bin/adbd
行 3740: 632        636        206        /bin/adbd
行 3780: 632        636        206        /bin/adbd
行 3820: 632        636        206        /bin/adbd
行 3860: 632        636        206        /bin/adbd
行 3900: 632        636        206        /bin/adbd
行 3946: 632        636        206        /bin/adbd
行 3986: 632        636        206        /bin/adbd
行 4026: 632        636        206        /bin/adbd
行 4066: 632        636        206        /bin/adbd
行 4117: 632        636        202        /bin/adbd
行 4159: 632        636        206        /bin/adbd
行 4203: 632        636        202        /bin/adbd
行 4245: 632        636        204        /bin/adbd
行 4292: 632        636        206        /bin/adbd
行 4333: 632        668        234        /bin/adbd

发现确实存在内存泄露的情况。

4.问题分析

使能网络adb时,将命令改成:

代码语言:javascript
复制
killall adbd
export ADB_TRANSPORT_PORT=5555
/bin/adbd -D &

将adbd的log信息输出到控制台上,观察adbd的运行情况。

根据log信息以及对比源码能够发现,在调用transport.c的transport_registration_func()函数时,当读到的action等于0,即退出adb时,就会free掉一些之前malloc的指针。

5.根本原因

通过在函数transport_registration_func()的free动作前后添加打印能够发现,在adb disconnect时,并没有调用到free的动作。

再在register_socket_transport()中calloc结构体atransport前后添加打印发现,每次adb connect时,都会重新调用register_socket_transport()去注册传输所需要的资源,并且会重新申请一篇内存。

那么就根据前后,就能知道在disconnect时有一篇内存没有释放,而后重新connect时又新申请内存,导致了内存的泄露。

对比有线adb,在连接时会申请结构体atransport的内存,在拔出usb线时也会free掉对应的内存。

再看回来函数transport_registration_func(),

在初始化时,这里注册了一个异步事情回调函数,当接收到事件的时候,就会调用transport_registration_func()去处理事件。对于拔出USB线来说,就会对gadget进行disconnect,然后composite gadget就会通过uevent通知应用层已经断开连接了,于是adbd就能够获取到事件从而去断开连接,释放资源。

而对于网络adb来说,暂无这种机制。所以就需要依靠在output_thread中,在通信失败后主动触发断连的操作。

在部分SDK中,存在这么一个补丁:

代码语言:javascript
复制
diff --git a/utils/adb/src/transport.c b/utils/adb/src/transport.c
index 9fd6cc2..97a438b 100755
--- a/utils/adb/src/transport.c
+++ b/utils/adb/src/transport.c
@@ -285,7 +285,6 @@ static void *output_thread(void *_t)
         } else {
             D("%s: remote read failed for transport\n", t->serial);
             put_apacket(p);
-            break;
         }
     }

补丁的作用时,当通信失败时,就会断连、释放资源。这个补丁引入是为了修复USB ADB在通信不佳的情况下,触发了通信失败然后导致了USB重新枚举。 但是引入该补丁后,在使用网络ADB时,通信失败也不会被断连了,因此也造成了内存泄露的问题。

6.解决办法

基于上述情况,在output_thread中加入限制的条件。在USB ADB时,取消break,让其一直在循环当中。对于网络ADB来说,则是执行break,当发生断连时,能够及时将资源释放掉。

修复的补丁如附件所示。

0001-adbd-only-transport_local-can-disconnect-in-outputth.patch

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-02-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.主题
  • 2.问题背景
  • 3.问题描述
    • 3.1复现步骤
      • 3.2具体表现
      • 4.问题分析
      • 5.根本原因
      • 6.解决办法
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档