記一次調試串口設備Bug的經歷


最近花了差不多1天的時間在折騰一個Bug,該Bug的表象如下: 

這個Bug還特別獨特,在開發電腦中無提示,在終端用戶那里每次使用軟件的時候都報這個。仔細思考了一下最近在源碼中新添加的功能,沒發現有啥特別明顯的問題。於是,根據字面意思的理解是“運行時錯誤”,所以一開始解決這個問題的思路是將所有應用程序的運行時拷貝至應用程序目錄。嘗試過之后,依然報這個異常。分析可能跟運行時的動態鏈接庫沒有關系。於是,調整解決問題的思路,考慮將工程中新添加的代碼進行分割。部分部分的測試新添加的代碼到底那里有問題,排查到最后是這個函數內部發生了異常。異常函數的代碼如下:

void CleanSerialPort()
{
    if(g_hEvent != NULL)
    {
        CloseHandle(g_hEvent);
        g_hEvent = NULL;
    }

    if(g_SerialPort.IsOpen())
    {
        COMMPROP properties;
        memset(&properties, 0, sizeof(properties));
        g_SerialPort.GetProperties();
        g_SerialPort.ClearWriteBuffer();
        g_SerialPort.ClearReadBuffer();
        g_SerialPort.Flush();
        g_SerialPort.CancelIo();
        g_SerialPort.Close();
    }
}

一開始仔細讀了幾遍代碼,沒發現有啥異常的地方。在這個時候,只能通過一點一點調試編譯器來最終確定問題在那里。調試編譯器的方式比較傳統,是通過MessageBox消息來實現。最終定位到g_SerialPort的Close函數。該函數的原型如下: 

void CSerialPort::Close()
{
    if(IsOpen())
    {
        CloseHandle(m_hComm);
        m_hComm = INVALID_HANDLE_VALUE;
    }
}

仔細讀了幾遍,依然沒發現問題在那里。但是,又反復琢磨了一段時間之后,把這個問題想清楚了。當把串口數據線拔出之后,串口設備已經在操作系統中不存在,這個時候卻還要去強行關閉串口設備,此時當然會發生異常,不發生異常才是不正常的情況。於是,考慮在這一大段代碼的外圍加一個try…catch…,果不其然,成功捕獲到異常,異常代碼的值為0x05,代表的含義為ERROR_ACCESS_DENIED,表示拒絕訪問。目前操作系統中已經不存在該串口設備,因此拒絕訪問是正常的狀態。最終的代碼如下:   

void CleanSerialPort()
{
    try
    {
        if(g_hEvent != NULL)
        {
            CloseHandle(g_hEvent);
            g_hEvent = NULL;
        }

        if(g_SerialPort.IsOpen())
        {
            COMMPROP properties;
            memset(&properties, 0, sizeof(properties));
            g_SerialPort.GetProperties();
            g_SerialPort.ClearWriteBuffer();
            g_SerialPort.ClearReadBuffer();
            g_SerialPort.Flush();
            g_SerialPort.CancelIo();
            g_SerialPort.Close();
        }
    }
    catch(CSerialException &e)
    {
        ATLTRACE("Unexpected CSerialPort exception, Error:%u\n", e.m_dwError);
        UNREFERENCED_PARAMETER(e);
    }
}

捕獲到這個異常之后,在不關閉應用程序的情況下,不影響再次初始化串口設備,而應用程序也不報一開始的Runtime error,因此默認目前的處理方案可行。 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM