1

私はコードを書いており、libudev.h を使用しています。これまでのところ、デバイスを検出して開き、開いているデバイスの fd をデータの読み取りと書き込みのために devlist に入れることができます。私の問題は、デバイスのプラグを抜くと、セグメンテーション エラーが発生することです。

if (FD_ISSET(fd, &fds))
{
    dev = udev_monitor_receive_device(mon);
    if (dev)
    {
        if(strcmp(udev_device_get_action(dev),"add")==0)
        {
            if(strcmp(udev_device_get_devnode(dev), "/dev/ttyUSB0")==0)
            {
                fd1 = open(udev_device_get_devnode(dev), O_RDWR | O_NONBLOCK);
                if(fd1<0)
                {
                    printf("Can't open Device\n");
                    exit(0);
                }
            }
            printf("Device plugged\n");
            printf("   Node: %s\n", udev_device_get_devnode(dev));
            printf("   Action: %s\n", udev_device_get_action(dev));
            printf("device opened\n");

            int opt =1;

            ioctl(fd1, FIONBIO,(char *) &opt);
            for(loop=0; loop<MAXDEV; loop++)
                if(devlist[loop] == 0)
                {
                    devlist[loop] = fd1;
                    fd1 = -1;
                }
        }
        else {
            printf("Device unplugged\n");
            printf("   Node: %s\n", udev_device_get_devnode(dev));
            printf("   Action: %s\n", udev_device_get_action(dev));
            FD_CLR(devlist[loop],&fds);
            close(devlist[loop]);
            devlist[loop] = -1;
        }
        udev_device_unref(dev);
}

デバイスを開くと、そのfdを読み取ることができ、問題はありませんが、デバイスのプラグを抜くとエラーが発生します。

これは私が問題を抱えている部分です。

printf("Device unplugged\n");
printf("   Node: %s\n", udev_device_get_devnode(dev));
printf("   Action: %s\n", udev_device_get_action(dev));
FD_CLR(devlist[loop],&fds);
close(devlist[loop]);
devlist[loop] = -1;

ありがとう..

4

1 に答える 1

2

プラグを抜いた後に USB シリアル アダプタにアクセスしても、セグメンテーション フォールトは発生しません。これは、以前の仕事でかなり厳しくテストしました。

プラグを抜いたデバイスに対応する「devlist」の要素に「ループ」を初期化していないように見えることに気付きました。plug イベントと unplug イベントの間の関数から戻っておらず、最後に接続したのと同じデバイスを取り外した場合、これが機能する可能性があります。

私が疑うもう1つの候補は、デバイスを読み書きするためのコードです。デバイスが取り外された後、読み取りおよび書き込みシステムコールは -1 を返します。そのエラーをチェックしていないか、エラー処理コードにバグがある場合は、それも問題になる可能性があります。

一般に、gdb の下でプログラムを実行し、クラッシュしたときにスタック トレースを取得することをお勧めします。これにより、エラーが発生した行番号がわかります。

于 2012-11-09T17:08:32.710 に答える