This code is supposed to check a setting of the FTDI USB-serial converter driver. It fails when there is no converter in the system. Can you spot the bug?

This code is supposed to check a setting of the FTDI USB-serial converter driver. It fails when there is no converter in the system. Can you spot the bug?

procedure Tf_ArgVideoMainBase.CheckFtdiLatencies;
var
Ftdi: TSigFtdi;
cnt: DWORD;
i: Integer;
dev: ISigFtdiDeviceAccess;
PortName: string;
Latency: Integer;
begin
try
Ftdi := TSigFtdi.Create;
except
Ftdi := nil;
end;
try
if Assigned(Ftdi) then begin
cnt := Ftdi.GetDeviceCount;
for i := 0 to cnt - 1 do begin
if Ftdi.TryGetDevice(i, dev)
and dev.TryGetPortName(PortName)
and dev.TryGetPortLatency(Latency) then begin
if Latency > 4 then
Tf_dzDialog.ShowMessage(mtWarning,
Format(_('Latency timer of serial port %s is set to %d ms, should be <= 4 ms.'),
[PortName, Latency]), [dbeOK], Self);
end;
end;
end;
finally
dev := nil;
FreeAndNil(Ftdi);
end;
end;

Comments

  1. I'm struggling to get past the swallow all exception handling

    ReplyDelete
  2. Thomas Mueller - if TryGetDevice fails - the two following and parts will still execute - with an invalid dev. err... or not - if boolean shortcuts are enabled.

    ReplyDelete
  3. Are device indexes 0 to count-1 or 1 to count?

    ReplyDelete
  4. ...
    try
    Ftdi := TSigFtdi.Create;
    except
    ...

    Instantiation inside try...xxx block?!?

    ReplyDelete
  5. Iggy White what's wrong with hat? It's a try except, not a try finally block.

    ReplyDelete
  6. Please note that I posted this in "Delphi Tips", not in "Delphi Help". I know the answer. I just thought it might be interesting for others to have a go at this. It took me only a few seconds to figure it out, but I had two unfair advantages: 1. I knew the code (don't remember if I wrote it or one of my colleagues) 2. I knew the error message.

    ReplyDelete
  7. cnt: DWORD; //Unsigned 32bit
    for i := 0 to cnt - 1 do begin //0 - 1 = 2^32

    ReplyDelete
  8. Thomas Mueller What's wrong with it is the fact that exceptions are swallowed

    ReplyDelete
  9. Too bad that with default settings, the compiler does not warn you about this.

    ReplyDelete
  10. Sean Bogie No, its the loop variable's type that matters, it needs to be unsigned.

    ReplyDelete
  11. David Heffernan I'm not sure, whether changing the loop variable to DWord would solve the problem. Wouldn't that result in a loop 0 to 2^32-1 ?

    ReplyDelete
  12. Lars Fosdal integer overflow due to cnt being 0.
    I discovered this today because it was the first time the program ran on a computer without any ftdi USB to serial converters attached. Usually we have several, up to 5.

    ReplyDelete
  13. David Heffernan I could log the exceptions instead, but that wouldn't make a bit of a difference in this case. I simply don't care about any problems in TSigFtdi.Create. If it is serious, there will be more meaningful errors somewhere else.

    ReplyDelete
  14. Thomas Mueller NO! I'm not proposing that. I'm saying that the loop variable needs to be signed. The code as it stands runs fine when cnt is zero. I guess if you have $Q+ then you might hit an exception. But otherwise that loop is fine.

    ReplyDelete
  15. Swallowing exceptions is usually bad. Your excuses don't convince me.

    ReplyDelete
  16. David Heffernan I'm fine with that (re disagreement on swallowing exceptions)

    ReplyDelete
  17. Thomas Mueller I can see it's except not finally (and that nothing is wrong per se) but I never do it like this. Sorry if it offends you. :)

    ReplyDelete
  18. If you don't care about exceptions there, don't handle them. Remove the try, remove the if Assigned.

    ReplyDelete
  19. Thomas Mueller I work a lot with RS232.
    Interested very much in what you did.
    So where are those
    TSigFtdi ISigFtdiDeviceAccess;
    Where can i get the pas file to use those functions?
    Are they part of which Delphi?

    ReplyDelete
  20. shlomo abuisak these are proprietary interfaces / units developed internally. "SIG" = "Schniering Ingenieur*g*esellschaft", the former name of my employer TÃœV Rheinland Schniering.
    They access the DLL that comes with the ftdi device drivers (don't remember the name) and also reads and writes to the associated registry entries.

    ReplyDelete

Post a Comment