找不到逻辑错误/空字符串

时间:2018-08-03 20:19:36

标签: c++ linux udev

我正努力为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?

0 个答案:

没有答案