c - 打开 /dev/hidraw2 可以用 steamcontroller 挂起
问题描述
我的问题是在“/dev/hidraw2”上打开一个蒸汽控制器,这有时会导致程序挂起。我最大的问题是我不知道在哪里报告这个问题,所以我希望有人知道去哪里解决这个问题。
问题:
我有一个正在运行的 Arch Linux,它连接了一个蒸汽控制器(与提供的加密狗连接)。当试图通过打开 '/dev/hidraw2' 来访问设备时,我的程序卡在了“open”调用中。我的程序就是不返回。也无法用 杀死它kill -9
。恢复的唯一方法是重新启动我的机器。
我将有问题的代码减少为:
// compiled with gcc main.c
#include <stdio.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <fcntl.h>
int main() {
for(;;) {
printf("opening steam controller\n");
# It doesn't return from the following open
int fd = open("/dev/hidraw2", O_RDWR | O_NONBLOCK | O_CLOEXEC);
printf("closing steam controller\n");
if (fd != -1) {
close(fd);
}
usleep(100000);
}
return 0;
}
要重现,您必须插入蒸汽控制器加密狗,启动上述程序,然后打开蒸汽控制器(它不会每次都挂起,因此您可能需要关闭控制器并重新打开)。
关于我的机器的更多信息:
$ uname -a
Linux schenker 4.20.7-arch1-1-ARCH #1 SMP PREEMPT Wed Feb 6 18:42:40 UTC 2019 x86_64 GNU/Linux
$ gcc --version
gcc (GCC) 8.2.1 20181127
我该如何调查有关此问题的更多信息?我必须深入了解蒸汽控制器驱动程序吗?还是 hidraw 层的更多问题?
更新:
请求dmesg
的输出。重现错误需要 3 次尝试。我似乎注意到了可疑之处:
[ 141.161817] hid-steam 0003:28DE:1142.0002: Steam Controller 'XXXXXXXXXX' connected
[ 141.163527] input: Wireless Steam Controller as /devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.1/0003:28DE:1142.0002/input/input34
[ 151.291873] input: Wireless Steam Controller as /devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.1/0003:28DE:1142.0002/input/input35
[ 152.940759] input: Wireless Steam Controller as /devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.1/0003:28DE:1142.0002/input/input36
[ 155.287349] input: Wireless Steam Controller as /devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.1/0003:28DE:1142.0002/input/input37
[ 160.634001] hid-steam 0003:28DE:1142.0002: Steam Controller 'XXXXXXXXXX' disconnected
[ 172.665613] hid-steam 0003:28DE:1142.0002: Steam Controller 'XXXXXXXXXX' connected
[ 172.667006] input: Wireless Steam Controller as /devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.1/0003:28DE:1142.0002/input/input38
[ 181.306918] hid-steam 0003:28DE:1142.0002: Steam Controller 'XXXXXXXXXX' disconnected
[ 185.465807] hid-steam 0003:28DE:1142.0002: Steam Controller 'XXXXXXXXXX' connected
[ 185.467249] input: Wireless Steam Controller as /devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.1/0003:28DE:1142.0002/input/input39
[ 187.030851] input: Wireless Steam Controller as /devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.1/0003:28DE:1142.0002/input/input40
[ 192.673722] hid-steam 0003:28DE:1142.0002: Steam Controller 'XXXXXXXXXX' disconnected
[ 196.937743] hid-steam 0003:28DE:1142.0002: Steam Controller 'XXXXXXXXXX' connected
[ 196.939272] input: Wireless Steam Controller as /devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.1/0003:28DE:1142.0002/input/input41
Update2 还有一些 strace 输出:
openat(AT_FDCWD, "/dev/hidraw1", O_RDWR|O_NONBLOCK|O_CLOEXEC) = 3
write(1, "closing steam controller /dev/hi"..., 38closing steam controller /dev/hidraw1
) = 38
close(3) = 0
nanosleep({tv_sec=0, tv_nsec=100000000}, NULL) = 0
write(1, "opening steam controller /dev/hi"..., 38opening steam controller /dev/hidraw1
) = 38
openat(AT_FDCWD, "/dev/hidraw1", O_RDWR|O_NONBLOCK|O_CLOEXEC
这个问题不仅限于 hidraw2 也可能发生在 hidraw1 上(我想这取决于实际的蒸汽控制器连接到哪里)
我还注意到,当我的程序卡住并且我在另一个控制台上调用启动第二个实例时,它会立即挂起,open()
独立于控制器的关闭/开启状态。
解决方案
原来是与 acpid 交互时 hid_steam 驱动程序之间的错误。
我联系了hid_steam驱动的作者(Rodrigo Rivas Costa),这是LKML协议正确的做法(见http://vger.kernel.org/lkml/#s2-1)
对我来说,短期解决方案是卸载 hid_steam,因为我直接访问 /dev/hidrawX:
# modprobe -R hid_steam
Rodrigo 已经在开发补丁。向罗德里戈大声疾呼,因为他如此迅速地解决了这个问题。谢谢!
推荐阅读
- reactjs - 如何将图像传递给样式化组件?
- php - 我的表单 show.blade 中的 MediumText 和 textArea
- c# - 在不使用目录对话框的情况下打印 FixedDocument
- mysql - 从 Nodejs 中的 mySQL 获取数据时如何从 Async/await 函数获取返回值
- c# - 退出在异步方法内开始的 while 循环
- html - 我需要起飞
从数据使用反应
- php - 每天仅随机生成一次数组
- android - Sqlite 查询以获取包含在名字或姓氏中的搜索文本的下一个可用字符
- multithreading - 我们的意思是休眠会话不是线程安全的,应该尽快关闭
- ios - 如何填充在其行中嵌入了 collectionViews 的 tableView 并按类型或类别组织它们?