Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

#18 Crash if USB->Serial adaptor is removed

open
nobody
None
5
2006-06-22
2006-06-22
Anonymous
No

If you're using an USB to serial adaptor and unplug the
USB cable while the COM port is open your program will
crash seriously.

Discussion

  • odissey1
    odissey1
    2007-01-27

    Logged In: YES
    user_id=1659492
    Originator: NO

    Hi,

    Having the same problem I came to a solution so far as shown below.

    Corrections in CPort.pas v.3.10 to work with USB-RS232 correctly (//BMT-my changes)

    in:

    function TCustomComPort.Signals: TComSignals;
    var Status: DWORD;
    begin

    {//replace this->
    if not GetCommModemStatus(FHandle, Status) then
    raise EComPort.Create(CError_ModemStatFailed, GetLastError);}

    //to this->
    if not GetCommModemStatus(FHandle, Status) then
    DoError([ceBreak]);//fire ceBreak instead

    ...

    end;

    Comment: When USB is unplugged, ComPort1.OnError event will be fired, you can process disconnect there (change some buttons state or stop your transmit/receive operations). Also in OnError event, do not use ComPort1.Close, or ComPort1.Port='', because there is nothing to close anyway. Just ignore that.

    in AbortAllAsync just comment all lines - I don't see any problems so far with that:

    procedure TCustomComPort.AbortAllAsync;
    begin
    //BMT if not PurgeComm(FHandle, PURGE_TXABORT or PURGE_RXABORT) then
    //BMT raise EComPort.Create(CError_PurgeFailed, GetLastError);
    end;

    Comment: PurgeComm causes a problem ('Purge Coom funcion failed, (Win Err code:5)') when hot unplug of USB-RS232 devices. Just comment all lines to ignore everything in AbortAllAsync. I don't see any problem yet. We don't need to Purge Comm port which does not exist anyway.

    Regards,
    dissey1

     
  • Logged In: NO

    I use bcb5 and had this problem, it seem largely related to the strings being returned when the exception handler was fired.

    // create exception with windows error code
    constructor EComPort.Create(ACode: Integer; AWinCode: Integer);
    begin
    FWinCode := AWinCode;
    FCode := ACode;
    //inherited CreateFmt(ComErrorMessages[ACode] + WideString(' (win error code: %d)'), [AWinCode]);
    end;

    I commented out the call to inherited CreateFmt(ComErrorMessages[ACode] + WideString(' (win error code: %d)'), [AWinCode]);
    and the crashes/ blue screens went away.

    Not a deterministic solution but it seems to be robusts, I can pull the usb in and out and no crashes any more.