Recent

Author Topic: Inexplicable error  (Read 7654 times)

Spoonhorse

  • Full Member
  • ***
  • Posts: 123
Inexplicable error
« on: June 26, 2021, 05:14:15 pm »
I've written a zillion bits of code that read in a text file using a loop that starts "while not eof(f) do". I had one that worked fine yesterday. Today, used to open the same file, it gives a runtime "Argument out of range" error the first time it hits the line, with the usual invitation to OK or Abort. If I choose OK it then reads the file in fine, never giving an error again despite the fact it must be checking for eof each time it goes round the loop.

And yes, it is that line. If I write:

Code: Pascal  [Select][+][-]
  1. showmessage('Check A');
  2. while not eof(f) do
  3.    begin
  4.    showmessage('Check B');
  5.    ... etc
  6.  

.. then I see Check A, then the runtime error, and then as many Check B's as there are iterations of the loop.

It's perplexing. Which argument is out of range? Why has this bug suddenly arisen? What could possibly cause it?

Thanks for your help.

---

ETA: This gets weirder. Since it went wrong the first time it goes round the while loop I tried replacing it with a repeat loop, but it does the same thing — throws a runtime error when it first enters the loop, even though I'm not performing an eof check. That is, if I put

Code: Pascal  [Select][+][-]
  1. showmessage('Check A');
  2. repeat
  3.    showmessage('Check B');
  4.    ... etc
  5.  
  6.    until eof(f)

... then it produces the exact same behavior. It's just objecting to ... starting the loop? Now I feel more baffled.

What argument is out of range? There is no argument.

---

ETA2: Changed it again so the repeat loop doesn't look at eof but just stops after reading a given number of lines in. Same thing. How can starting a loop cause a runtime error? Why is it "Argument out of range"? Am I cursed?
« Last Edit: June 26, 2021, 05:42:40 pm by Spoonhorse »

MarkMLl

  • Hero Member
  • *****
  • Posts: 6682
Re: Inexplicable error
« Reply #1 on: June 26, 2021, 06:20:04 pm »
Am I cursed?

By many people, for not showing us the whole program including the bit that sets up f, providing some sort of test file, telling us what version of FPC etc. you're using, and what OS you're using.

For example, assuming (for a moment) that you ran multiple OSes, it might be that you're trying to open one with unix-style line endings using a DOS program. Or it might turn out to be some weird character set issue that the core developers have been chasing for years. Or... you get the idea :-)

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Spoonhorse

  • Full Member
  • ***
  • Posts: 123
Re: Inexplicable error
« Reply #2 on: June 26, 2021, 06:34:50 pm »
MarkMLI, I see your point, and I'm sorry but that would be a sledgehammer to crack a nut in that ... I am halfway through two simultaneous refactorizations so there are lots of other parts of the code that don't work and can't make sense which would deeply confuse anyone doing code review ... the code base is large ... there's a gajillion resource files necessary to make it work ... I'd have to find some way to conceal the bits with my passwords in to my server and database while still allowing the program to work ... and I've decided that one of the refactorizations was a dumb idea made moot by the other one and I should probably just revert my code a day and start again. So if nothing leaps out at you I'll have to go on being puzzled.

440bx

  • Hero Member
  • *****
  • Posts: 4014
Re: Inexplicable error
« Reply #3 on: June 26, 2021, 07:24:04 pm »
By the description you give, the behavior is perplexing but, there is a relatively simple way to find out what is causing the problem, which is, look at the generated assembly and if that is not sufficient then debug that section of code in assembler. 

The first step would be to put a breakpoint at the first showmessage, open the assembler window and look at what's happening in there then proceed to execute one assembly instruction at a time.  What's causing that problem is there and will reveal itself.

HTH.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Inexplicable error
« Reply #4 on: June 26, 2021, 10:26:37 pm »
I guess the problem has nothing to do with the code you are showing. It is caused by something *before* this code.

440bx

  • Hero Member
  • *****
  • Posts: 4014
Re: Inexplicable error
« Reply #5 on: June 26, 2021, 10:32:03 pm »
I guess the problem has nothing to do with the code you are showing. It is caused by something *before* this code.
Quite likely.  Sounds like some internal data used by the file functions got overwritten with garbage.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Inexplicable error
« Reply #6 on: June 26, 2021, 11:19:53 pm »
Checking the source code of EOF shows that most file procedures use IOCHECK, as in:
Code: Pascal  [Select][+][-]
  1. Function Eof(Var t: Text): Boolean;[IOCheck];

The check will happen *after* these calls AND before the loop.

If there is an error, EOF will not bother doing anything:
Code: Pascal  [Select][+][-]
  1. Function Eof(Var t: Text): Boolean;[IOCheck];
  2. Begin
  3.   If (InOutRes<>0) then
  4.    exit(true);

So again, the problem is *before* the loop.
Check InOutRes before the loop.


engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Inexplicable error
« Reply #7 on: June 26, 2021, 11:22:42 pm »
I guess I shouldn't ask the question but, is Range change on and are you using HeapTrc ?

You did ask the question.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6682
Re: Inexplicable error
« Reply #8 on: June 26, 2021, 11:46:31 pm »
Iamhalfwaythroughtwosimultaneousrefactorizationssotherearelotsofotherpartsofthecodethatdon'tworkandcan'tmakesensewhichwoulddeeplyconfuseanyonedoingcodereview...thecodebaseislarge...there'sagajillionresource filesnecessarytomakeitwork...I'd have to find some way to conceal the bits with my passwords

Yers, I think you have problems there... just a moment, did you really say you had hardcoded passwords in your program?

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Inexplicable error
« Reply #9 on: June 27, 2021, 06:44:20 pm »
In the RTL help file if you disable IO checking, they don't want you to use the variable InOutRes. Instead, they want you to call the function IOResult which gives you the value and clears the InOutRes variable.

dseligo

  • Hero Member
  • *****
  • Posts: 1219
Re: Inexplicable error
« Reply #10 on: June 28, 2021, 09:24:04 am »
Quote from: jamie
I always do a InOutRes := 0 before using the old Pascal IO stuff..
Quote from: engkin
In the RTL help file if you disable IO checking, they don't want you to use the variable InOutRes. Instead, they want you to call the function IOResult which gives you the value and clears the InOutRes variable.

So, to be clear to OP, he should try to do something like this before 'while':

Code: Pascal  [Select][+][-]
  1. showmessage('Check A');
  2. showmessage('Previous I/O result: '+IntToStr(IOResult));
  3. while not eof(f) do
  4. ...
« Last Edit: June 28, 2021, 09:25:35 am by dseligo »

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Inexplicable error
« Reply #11 on: June 28, 2021, 09:55:41 am »
So, to be clear to OP, he should try to do something like this before 'while':
Code: Pascal  [Select][+][-]
  1. showmessage('Check A');
  2. showmessage('Previous I/O result: '+IntToStr(IOResult));
  3. while not eof(f) do
  4. ...

Not really. What he (or anybody) should do, if in {$I-} state, is to check IOResult after each file access: Assign(), Reset()/Rewrite(), Read/Write, etc. which includes checking for Eof() or EOLn(), so for example:
Code: Pascal  [Select][+][-]
  1. {
  2. var
  3.   SaveIORes: word;
  4. }
  5. {$I-}
  6. Assign(f, 'somefile');
  7. Reset(f);
  8. SaveIOREs := IOResult;
  9. if SaveIORes <> 0 then
  10.   { Open error, do something}
  11. else begin
  12.   while not eof(f) do begin
  13.     SaveIOREs := IOResult;
  14.     if SaveIORes <> 0 then
  15.       { eof() error, do something}
  16.     else begin
  17.       {[block]read/readln/etc}
  18.       SaveIOREs := IOResult;
  19.       if SaveIORes <> 0 then
  20.         {reading error, do something}
  21.       else
  22.         {all went ok, do your thing}
  23.     end;
  24.   end;
  25. end;

Yes, it ends in a little deep nesting when doing it right, which is why (among other things) it's usually preferred to use streams along with try...except blocks or resort to functions/procedures to decrease the nesting of ifs.
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

 

TinyPortal © 2005-2018