应用层打印PC指针LR指针解决段错误总结

本文针对ARM环境且GDB不便使用的情况,探讨复杂代码段错误的定位方法。用户态段错误原因主要有两种,对应内核和上层程序两种解决办法,分别介绍了内核信息和用户态信息的打印方法,并对输出信息进行分析,最后给出使用注意事项。

1.需求的产生

写程序难免会出现段错误的情况,这时候很想知道,到底在什么地方崩溃了,对于代码很少,或者你很有把握的时候,或许用二分法配合printf就可以搞定了;而对于非常复杂的代码,比如像Xserver这样的程序,可能就不太好定位了;
(本文讨论的情况都是针对arm环境,并且gdb不方便使用的情况)

2. 解决思路

思路其实很简单,对于用户态段错误的原因,大约可以分为两种,

a) 没有权限访问这个地址;
b) 访问的地址没有映射,比如NULL地址;
当出现这两种情况的时候,linux内核都会向用户态的程序发送SIGSEGV的信号,于是程序执行默认的信号处理函数,就退出了;
所以有两个解决办法:
A) 在内核里面把这些寄存器打印出来;
B) 在上层程序里面把寄存器打印出来;
下面来分别说明:

3. 内核信息打印

内核的执行路径如下:
在这里插入图片描述
我们只需要在__do_user_fault的时候把打印信息打开就可以了,如下:

#ifdef CONFIG_DEBUG_USER
       if (user_debug & UDBG_SEGV) {
              printk(KERN_DEBUG "%s: unhandled page fault (%d) at 0x%08lx, code 0x%03x\n",
                    tsk->comm, sig, addr, fsr);
              show_pte(tsk->mm, addr);
              show_regs(regs);
       }
#endi
<think>我们正在处理一个关于Android InputReader中notifyMotion事件坐标与实际指针位置不一致的问题。 根据用户提供的信息,我们需要分析InputReader处理输入事件(特别是触摸事件)的流程,并找出可能导致坐标不一致的原因。 参考引用[2]中提到了InputReader、InputDevice和InputMapper之间的关系,这有助于我们理解事件的处理流程。 问题分析: 1. InputReader负责从设备读取原始输入事件,然后通过InputMapper将原始事件转换成Android事件。 2. 在触摸事件中,InputMapper(如TouchInputMapper)负责处理触摸事件,包括坐标转换等。 3. 坐标不一致可能发生在多个环节:原始数据读取、坐标转换、屏幕旋转处理、多显示器支持等。 可能的原因: 1. 屏幕旋转处理:当设备旋转时,坐标可能需要旋转,如果旋转处理不当,会导致坐标不一致。 2. 显示器配置:如果有多个显示器,事件可能被映射到错误的显示器上。 3. 输入校准:设备可能需要校准,如触摸屏校准参数不正确。 4. 输入子系统的配置:在InputReader的配置文件中(如.idc文件)可能配置了错误的转换参数。 5. 输入事件处理过程中的错误:在InputMapper中,坐标转换可能出错。 解决方案: 1. 检查屏幕旋转设置:确保在屏幕旋转时,InputReader正确应用了旋转矩阵。在TouchInputMapper中,会使用`orientation`和`transform`来转换坐标。 2. 检查显示器信息:确保事件被分配到正确的显示器,并且使用正确的显示参数(如宽高、方向)进行转换。 3. 检查输入设备的配置文件(.idc文件):查看是否有错误的校准参数,如`touch.position.calibration`、`touch.size.calibration`等。可以尝试重新校准或修改配置文件。 4. 调试InputReader:在InputReader处理事件的过程中添加日志,查看原始事件坐标和转换后的坐标,定位问题环节。 具体步骤: 1. 查看设备旋转时的日志,确认旋转矩阵是否正确应用。 2. 检查InputDispatcher最终分发的事件坐标,与InputReader处理后的坐标进行对比,确定问题发生在InputReader阶段还是后续阶段。 3. 检查InputReader的配置文件(/system/usr/idc/目录下的.idc文件)是否有异常配置。 代码层面: 在`TouchInputMapper`中,坐标转换发生在`cookPointerData`方法中。这里会应用旋转矩阵和缩放因子。可以检查这个方法的实现。 注意:由于Android版本差异,具体实现可能有所不同,但总体思路一致。 参考引用[1]和[2]中关于InputReader处理流程的描述,我们可以更深入地理解事件处理机制。 因此,我们建议: 1. 首先确认问题发生的场景(是否只在旋转时出现?是否在多显示器中出现?) 2. 检查相关配置文件。 3. 在代码中增加调试日志,定位问题。 如果问题仍然无法解决,可能需要深入分析具体设备的驱动和InputReader的实现。 相关问题: 1. 如何调试Android输入事件处理流程? 2. 如何为触摸屏设备编写正确的.idc配置文件? 3. 屏幕旋转对输入事件坐标的影响机制是什么?</think>### Android InputReader notifyMotion 坐标与指针位置不一致问题分析 #### 问题原因分析 1. **坐标转换错误** InputReader 从设备驱动读取原始坐标后,需通过 `TouchInputMapper` 进行坐标转换。若转换矩阵(如旋转矩阵、缩放因子)计算错误,会导致实际坐标与预期不符。常见于屏幕旋转场景,未正确处理 `DisplayViewport` 的 `orientation` 参数[^1]。 2. **显示器配置异常** 在多显示器系统中(如车载双屏),`InputReader::notifyMotion` 可能将事件映射到错误的显示器。检查 `InputDispatcher` 的 `setInputWindows` 是否传递了正确的 `displayId` 和 `viewport` 信息[^2]。 3. **输入校准失效** 触摸屏校准参数(存储在 `/system/usr/idc/` 下的 .idc 文件)可能被破坏。例如: ```ini # 示例配置 touch.deviceType = touchScreen touch.position.calibration = scaled | none ``` 若 `calibration` 参数错误或未应用,会导致原始坐标未正确缩放。 4. **事件加工层错误** 在 `InputReader::processEventsLocked()` 中,`TouchInputMapper` 的 `cookPointerData()` 方法可能未正确处理以下环节: - 坐标轴映射(X/Y 反转) - 边缘过滤(如虚拟导航栏区域) - 多点触摸插值错误 #### 解决方案 1. **验证坐标转换流程** 在 `TouchInputMapper.cpp` 的 `cookPointerData()` 添加调试日志: ```cpp ALOGD("Raw: (%f,%f) -> Cooked: (%f,%f)", rawX, rawY, transformedX, transformedY); ``` 对比原始坐标与转换后坐标,定位转换错误环节。 2. **检查显示器配置** 使用 `dumpsys input` 命令检查当前活跃的 `DisplayViewport`: ```bash adb shell dumpsys input | grep -A 10 "Viewports" ``` 确保目标显示器的 `displayId` 与事件中的 `displayId` 一致。 3. **重新校准触摸屏** - 删除错误的校准文件: ```bash adb root adb remount adb shell rm /system/usr/idc/*.idc ``` - 使用 `getevent` 获取原始坐标,重新生成校准参数。 4. **处理屏幕旋转** 在 `InputReader::configureParameters()` 中确保监听显示方向变更: ```cpp mParameters.orientationAware = true; // 启用方向感知 ``` 5. **检查输入子系统版本** Android 10+ 使用新的 `InputFlinger` 架构,需验证 `InputReaderPolicy` 是否兼容: ```java // 在 InputManagerService.java 中 mInputManager = new InputManager(context, inputFlinger, handler); ``` #### 关键代码路径 ```mermaid graph LR A[设备驱动] -->|原始事件| B(InputReader) B --> C{InputMapper} C -->|TouchInputMapper| D[坐标转换] D -->|cookPointerData| E[notifyMotion] E --> F[InputDispatcher] ``` #### 验证方法 1. 使用 `getevent -ltr` 获取原始坐标 2. 通过 `dumpsys input events` 查看加工后坐标 3. 对比两者差异是否在预期转换范围内
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值