我正努力为Linux制作一个C ++程序,该程序使用udev监视新的输入设备,并在插入一个设备后运行一个程序。但是,每当我插入Xbox 360控制器( linux box识别为输入设备。不是“ hidraw”。)出现此错误:
抛出'std :: logic_error'实例后调用terminate what():basic_string :: _ M_construct null无效 中止(核心已弃用)
此错误报告随附错误代码134。我在互连网上搜索过高和低,试图找到解决方案。我找到了一些谈论“悬空参考”的站点,但没有找到(尽管我不是最观察的,所以如果我错了,请告诉我)。
我能够将错误的范围缩小到scanner()
,可能在if (ret > 0 && FD_ISSET(fd, &fds))
的某个区域
我的代码:
#include <iostream>
#include <libudev.h>
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <unistd.h>
#include <cstdlib>
#include <fstream>
#include <sys/types.h>
#include <pwd.h>
using namespace std;
//for error reporting to the log file at ~/.xboxdrv/LOGFILE.txt
int error(std::string out)
{
int SENT = 1;
while ( SENT == 1)
{
std::string home = getenv("HOME");
if (home.empty())
{
home = getpwuid(getuid())->pw_dir;
}
ofstream errout ((home + "/.xboxdrv/LOGFILE.txt").c_str(), ios::out | ios::app);
if (errout.is_open())
{
errout << out << std::endl;
SENT = 0;
}
else continue;
errout.close();
}
//check file size, if > ~30MB, compress into a zip
return 0;
}
//check newly mounted USB device for standard support
int check_standard(std::string check)
{
int success = std::system( ("python3 /etc/usb-scanner/check_support_standard.py " + check).c_str() );
if (success == 1)
{
std::cout << 0;
}
else
{
std::cout << 1;
}
return 0;
}
//check newly mounted USB for non-standard
int check_non_standard(std::string check)
{
int success = std::system( ("python3 /etc/usb-scanner/check_support_nonstandard.py " + check).c_str() );
if (success == 1)
{
std::cout << 0;
}
else
{
std::cout << 1;
}
return 0;
}
//LISTEN for newly mounted USB devices
int scanner()
{
cout << "Start Scanner(). . . ";
struct udev *udev;
struct udev_device *dev;
struct udev_monitor *mon;
int fd;
//Create the udev object
udev = udev_new();
if (!udev)
{
error("ERROR: Can't create new udev object");
cout << "Can't create udev";
return 1;
}
//Set up a monitor to monitor input devices
cout << "Starting monitor. . . ";
mon = udev_monitor_new_from_netlink(udev, "udev");
udev_monitor_filter_add_match_subsystem_devtype(mon, "input", NULL);
udev_monitor_enable_receiving(mon);
/* Get the file descriptor (fd) for the monitor.
This fd will get passed to select() */
fd = udev_monitor_get_fd(mon);
int SENT = 1;
cout << "Starting while 2. . . ";
while (SENT == 1)
{
/* Set up the call to select(). In this case, select() will
only operate on a single file descriptor, the one
associated with our udev_monitor. Note that the timeval
object is set to 0, which will cause select() to not
block. */
fd_set fds;
struct timeval tv;
int ret;
FD_ZERO(&fds);
FD_SET(fd, &fds);
tv.tv_sec = 0;
tv.tv_usec = 0;
ret = select(fd+1, &fds, NULL, NULL, &tv);
cout << ret;
//Check if our file descriptor has received data.
if (ret > 0 && FD_ISSET(fd, &fds))
{
/* Make the call to receive the device.
select() ensured that this will not block. */
dev = udev_monitor_receive_device(mon);
if (dev)
{
error("NOTICE: Got Device");
std::string action = udev_device_get_action(dev);
std::string v = udev_device_get_sysattr_value(dev,"idVendor");
std::string p = udev_device_get_sysattr_value(dev,"idProduct");
std::string vpid = (v + ":" + p).c_str();
if (action == "add")
{
SENT = 0;
}
udev_device_unref(dev);
std::cout << vpid;
}
else
{
error("ERROR: No Device from receive_device().");
cout << "ERROR: No Device from receive_device().";
}
}
usleep(100000);
fflush(stdout);
}
udev_unref(udev);
return 0;
}
//main function
int main ()
{
cout << "Start. . . ";
int SENT = 1;
while (SENT == 1)
{
cout << "Start While 1. . . ";
string new_usb;
new_usb = scanner();
cout << new_usb;
int stand_sup = check_standard(new_usb);
if (stand_sup == 1)
{
int non_stand_sup = check_non_standard(new_usb);
if (non_stand_sup == 0)
{
int pid = fork();
if (pid == 0)
{
execl("bash", "/etc/usb-scanner/unsupported.sh", new_usb, (char *) 0);
}
}
}
else if (stand_sup == 0)
{
int pid = fork();
if (pid == 0)
{
execl("bash", "/etc/usb-scanner/supported.sh", (char *) 0);
}
}
}
}
最后一点要注意:当我实际使用此功能时,所有将打印到控制台的cout
东西都将被删除。它只是为了调试目的而存在,在将它放在这里之前,我实在太懒了,无法将其拿出来。
感谢您的所有帮助!
编辑
将其放入gdb
后,我发现错误行分别为145和146(我在这里运行udev_device_get_sysattr_value
以获得供应商和产品ID)。我环顾四周,看看是否有任何文档详细说明了需要通过此函数的哪些数据,但所有内容只是说它需要是一个udev_device
结构和一个const char
,但仅以此为基础,变量dev和我传递的字符串应该可以工作。除了这些数据及其返回的数据之外,我找不到有关此函数的更多信息。
我感到,udev_monitor_receive_device(mon)
的收益被保存到更高的开发人员那里,并不能完全满足udev_device_get_sysattr_value
才能正常工作所需的信息。
如何获取正确的信息以传递给此函数并调用此错误?如果这不是问题,是否还有其他方法可以在C ++中获取供应商/产品ID?