android投屏程序线程无故卡死不执行,如何分析?

2024-04-08 20:52

本文主要是介绍android投屏程序线程无故卡死不执行,如何分析?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

背景:

hi,粉丝朋友们:
大家好!近期做了一个车载互联,云手机相关的投屏的小项目demo,具体效果如下:
在这里插入图片描述

是不是感觉有点厉害哈,可以云手机远程控制,但是意外就出现了。。。

比如像如下这样拼命操作一下:
真正勇士应该经得住任意的考验

在这里插入图片描述

很遗憾发现一阵疯狂触摸操作后,居然客户端再也没有办法触控了,处于gg状态,触控后服务端的手机再也没有相关的反应,但是服务端依然是可以自己操作,也可以传递画面的变化给客户端

针对这这个无法操控问题要展开分析应该如何呢?

分析问题

针对这个客户端控制服务端触摸操作无反应问题,有以下几个方面定位排查:

1、怀疑进程直接异常崩溃

这个可以从日志,和操作行为可以看出,客户端和服务端,画面还是可以同步的,说明不存在异常退出这种情况发生,客户端日志也没有发现有任何报错,故排除程序自身异常退出导致问题

2、客户端没有传递相关的触摸数据

这个看着现象是有这个可能,但是经过客户端日志打印,发现也是正常进行了触摸数据的传递

3、服务端不接受触摸数据

这个也只能加日志相关的打印看看,发现日志在客户端无法触摸控制后就完全停止了,再也没有打印出相关的日志。故问题就明显指向是不是这个线程卡死了,连日志都不打印了,,,这个怀疑是正常的。
但是为啥会卡死呢?
怀疑又有以下两个方面:
怀疑1:
是不是接受不到数据,一直处于read服务端数据发过,一直处于阻塞状态?
这个也对read方法的前后加了很多打印,伪代码如下

Log.i("read ------start ");
read()//读取网络数据
Log.i("read ------end ");

发现卡死最后一句日志,并不一定是start这里停留,理论上如果read卡死那每次卡死肯定是有start没有end。所以经过日志也要排除这个可能

怀疑2:
是不是线程有其他方法阻塞?是否可以通过systrace/perfetto查看?
现在没有更多线索只能继续排查,用perfetto抓trace看线程是不是有啥卡住任务,具体trace如下图所示:
在这里插入图片描述
所以systrace其实也没有看出卡住时候是在等待啥,有啥一直运行的任务,所以perfetto好像也没有解决线程为啥卡死在一个地方

绝招方式解决

上面几种常见的分析思路和工具好像都没有很好的办法来分析出根本问题,现在就只知道线程卡死不动了,还不是网络阻塞。。。也不知到线程这个时候到底怎么了。。
想想线程卡住不动肯定处于某个状态,是否可以根据线程这个时候的具体状态信息反推出可能问题呢?
可以通过ps -T方式查看相关进程的线程目前运行情况和状态
具体命令如下:

adb shell ps -T  -p 进程号

注意:这个可能需要是userdebug机器

在程序卡住时候可以看看进程状态:
在这里插入图片描述
可以看到客户端触摸服务端无响应时候,这个时候服务端线程状态居然是pipe_write这样一个执行状态,说明是一直阻塞在这个地方。

那么问题来了,程序中哪里有啥地方会进行这个pipe_write操作呢?
哈哈,说实话这个就比较难想到了,一般要app层面追踪也很难,这里一般能想到程序中会有这个写入一般只有一个控制台的输出了。

             System.out.println(PREFIX + "WARN: " + message);

如上面这个 System.out.println方法,他就是需要进行pipe_write
一般android里面不是不用这个打印日志么?都是Log.i,一般情况是这样,但是投屏时候为了方便直接shell触发执行,方便直接terminal看输出情况,所以使用了这个System.out.println

问题分析到这里,那么考虑把程序中所有的System.out.println屏蔽了试试
在这里插入图片描述
其实也可以用kill -3这种获取堆栈看看到底卡在哪里:
在这里插入图片描述
一样发现是System.out.println这方法

屏蔽后发现一切运行完美。

总结:

在针对线程无故卡死情况,日志方面也不打印输出情况,需要考虑多个手段来尝试定位分析出目前的线程状态,然后根据状态反推出程序中可能的疑点,最后尝试修改验证。

本文章更多详细代码和资料需要购买课程获取
hal+perfetto+surfaceflinger
https://mp.weixin.qq.com/s/LbVLnu1udqExHVKxd74ILg
在这里插入图片描述

私聊作者+v(androidframework007)

其他课程七件套专题:在这里插入图片描述
点击这里
https://mp.weixin.qq.com/s/Qv8zjgQ0CkalKmvi8tMGaw

视频试看:
https://www.bilibili.com/video/BV1wc41117L4/

这篇关于android投屏程序线程无故卡死不执行,如何分析?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/886426

相关文章

Linux线程之线程的创建、属性、回收、退出、取消方式

《Linux线程之线程的创建、属性、回收、退出、取消方式》文章总结了线程管理核心知识:线程号唯一、创建方式、属性设置(如分离状态与栈大小)、回收机制(join/detach)、退出方法(返回/pthr... 目录1. 线程号2. 线程的创建3. 线程属性4. 线程的回收5. 线程的退出6. 线程的取消7.

Linux下进程的CPU配置与线程绑定过程

《Linux下进程的CPU配置与线程绑定过程》本文介绍Linux系统中基于进程和线程的CPU配置方法,通过taskset命令和pthread库调整亲和力,将进程/线程绑定到特定CPU核心以优化资源分配... 目录1 基于进程的CPU配置1.1 对CPU亲和力的配置1.2 绑定进程到指定CPU核上运行2 基于

golang程序打包成脚本部署到Linux系统方式

《golang程序打包成脚本部署到Linux系统方式》Golang程序通过本地编译(设置GOOS为linux生成无后缀二进制文件),上传至Linux服务器后赋权执行,使用nohup命令实现后台运行,完... 目录本地编译golang程序上传Golang二进制文件到linux服务器总结本地编译Golang程序

MySQL中的LENGTH()函数用法详解与实例分析

《MySQL中的LENGTH()函数用法详解与实例分析》MySQLLENGTH()函数用于计算字符串的字节长度,区别于CHAR_LENGTH()的字符长度,适用于多字节字符集(如UTF-8)的数据验证... 目录1. LENGTH()函数的基本语法2. LENGTH()函数的返回值2.1 示例1:计算字符串

mybatis执行insert返回id实现详解

《mybatis执行insert返回id实现详解》MyBatis插入操作默认返回受影响行数,需通过useGeneratedKeys+keyProperty或selectKey获取主键ID,确保主键为自... 目录 两种方式获取自增 ID:1. ​​useGeneratedKeys+keyProperty(推

Android kotlin中 Channel 和 Flow 的区别和选择使用场景分析

《Androidkotlin中Channel和Flow的区别和选择使用场景分析》Kotlin协程中,Flow是冷数据流,按需触发,适合响应式数据处理;Channel是热数据流,持续发送,支持... 目录一、基本概念界定FlowChannel二、核心特性对比数据生产触发条件生产与消费的关系背压处理机制生命周期

Android ClassLoader加载机制详解

《AndroidClassLoader加载机制详解》Android的ClassLoader负责加载.dex文件,基于双亲委派模型,支持热修复和插件化,需注意类冲突、内存泄漏和兼容性问题,本文给大家介... 目录一、ClassLoader概述1.1 类加载的基本概念1.2 android与Java Class

Javaee多线程之进程和线程之间的区别和联系(最新整理)

《Javaee多线程之进程和线程之间的区别和联系(最新整理)》进程是资源分配单位,线程是调度执行单位,共享资源更高效,创建线程五种方式:继承Thread、Runnable接口、匿名类、lambda,r... 目录进程和线程进程线程进程和线程的区别创建线程的五种写法继承Thread,重写run实现Runnab

SpringBoot线程池配置使用示例详解

《SpringBoot线程池配置使用示例详解》SpringBoot集成@Async注解,支持线程池参数配置(核心数、队列容量、拒绝策略等)及生命周期管理,结合监控与任务装饰器,提升异步处理效率与系统... 目录一、核心特性二、添加依赖三、参数详解四、配置线程池五、应用实践代码说明拒绝策略(Rejected

使用Docker构建Python Flask程序的详细教程

《使用Docker构建PythonFlask程序的详细教程》在当今的软件开发领域,容器化技术正变得越来越流行,而Docker无疑是其中的佼佼者,本文我们就来聊聊如何使用Docker构建一个简单的Py... 目录引言一、准备工作二、创建 Flask 应用程序三、创建 dockerfile四、构建 Docker