Recent

Author Topic: FPC 3.2.2 + GDB  (Read 552 times)

paule32

  • Hero Member
  • *****
  • Posts: 516
  • One in all. But, not all in one.
FPC 3.2.2 + GDB
« on: May 19, 2025, 08:13:34 am »
what is the error ?
- a range overflow ?

Code: Bash  [Select][+][-]
  1. Thread 1 received signal SIGSEGV, Segmentation fault.
  2. 0x00000001100041ee in STRCAT_ (DEST=0x11000a5e8 '1', SOURCE=0x110007a38 '') at SysUtils.pas:216
  3. 216       D[i + J + 2] := #0;
  4. (gdb)
This is the source code:
Code: Pascal  [Select][+][-]
  1. function StrCat_(var Dest: PChar; Source: PChar): PChar; stdcall; export;
  2. var
  3.   D       : PChar;
  4.   L, I, J : Integer;
  5. begin
  6.   L := StrLen(Dest) + StrLen(Source) + 1;
  7.   D := StrAlloc(L);
  8.  
  9.   for i := 0 to StrLen(Dest) - 1 do
  10.   D[i] := Dest[i];
  11.  
  12.   for J := 0 to StrLen(Source) - 1 do
  13.   D[i + j + 1] := Source[J];
  14.   D[i + J + 2] := #0;
  15.  
  16.   Dest := D;
  17.   Exit(D);
  18. end;
MS-IIS - Internet Information Server, Apache, PHP/HTML/CSS, MinGW-32/64 MSys2 GNU C/C++ 13 (-stdc++20), FPC 3.2.2
A Friend in need, is a Friend indeed.

440bx

  • Hero Member
  • *****
  • Posts: 5477
Re: FPC 3.2.2 + GDB
« Reply #1 on: May 19, 2025, 08:39:06 am »
In a Pascal "for" loop the value of the index variable, in your case "i", is undefined when the loop ends.

Therefore, the lines 13 and 14 of your code are using a value which could be anything.  That's the reason you are getting a violation.

If you need to depend on the value of "i" when the loop ends, change it from a "for" to a "while" where you update the index yourself.

HTH.

(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v4.0rc3) on Windows 7 SP1 64bit.

Khrys

  • Full Member
  • ***
  • Posts: 243
Re: FPC 3.2.2 + GDB
« Reply #2 on: May 19, 2025, 08:41:55 am »
Like @440bx said, you cannot just use  i  and  j  after their respective loops have exited.
And if you want to be really pedantic, you shouldn't reuse the loop variable for anything else either; just for the loop itself. This has been discussed to death numerous times.

Also there's no reason to call  StrLen  twice for each parameter - you should cache the results.

paule32

  • Hero Member
  • *****
  • Posts: 516
  • One in all. But, not all in one.
Re: FPC 3.2.2 + GDB
« Reply #3 on: May 19, 2025, 09:14:22 am »
Thanks for replies:

In my case, Source was empty/null, so I had add two conditionals that check the Dest and Source Arguments.
And I use repeat until instead while.
So, the result will work, now.

Thank you.

Code: Pascal  [Select][+][-]
  1. function StrCat(var Dest: PChar; Source: PChar): PChar; stdcall; export;
  2. var
  3.   D       : PChar;
  4.   L, I, J : Integer;
  5. begin
  6.   if Dest = nil then
  7.   begin
  8.     MessageBoxA(0,'Error: StrCat Dest not initialized.','Error',0);
  9.     Exit;
  10.   end;
  11.  
  12.   if Strlen(Source) < 1 then
  13.   begin
  14.     Dest := '';
  15.     Exit(Dest);
  16.   end;
  17.  
  18.   L := StrLen(Dest) + StrLen(Source) + 1;
  19.   D := StrAlloc(L);
  20.  
  21.   L := StrLen(Dest);
  22.   i := 0;
  23.   repeat
  24.     D[i] := Dest[i];
  25.     inc(i);
  26.   until i = L;
  27.  
  28.   L := StrLen(Source);
  29.   j := 0;
  30.   repeat
  31.     D[i + j] := Source[j];
  32.     inc(j);
  33.   until j = L;
  34.  
  35.   D[i + j] := #0;
  36.   Dest := D;
  37.  
  38.   Exit(D);
  39. end;
MS-IIS - Internet Information Server, Apache, PHP/HTML/CSS, MinGW-32/64 MSys2 GNU C/C++ 13 (-stdc++20), FPC 3.2.2
A Friend in need, is a Friend indeed.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12269
  • FPC developer.
Re: FPC 3.2.2 + GDB
« Reply #4 on: May 19, 2025, 11:27:41 am »
And of course not caching strlen's.  Contrary to length() on Pascal strings, Strlen on zero terminated strings is an expensive operation.

 

TinyPortal © 2005-2018