Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2013-06

Some RTL functions cry big tears when mixing Pchar and Ansistring/String

9 messages · 5 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Unknown author

Under Linux using Lazarus 1.0.8/Fpc 2.6.2/Fedora 14 x64:

it seems like mixing Ansistrings and Pchars on certain run time functions is a real no-no.

I just spent HOURs, trying to see why I was not getting good program behavior.

Lesson #1: Never call function like Copy( pchar, start, length),

ONLY use Copy( ansistring/string, start, length)

Other functions like PosEx( ) do not generate compiler errors but you really do NOT want a Pchar to this function, only an ansistring/string.

Passing a Pchar gives weird, erratic behavior

Maybe the RTL library team could put compiler WARNINGS about only allowing for strings/ansistrings
on copy( ), posex( ), and other functions who have really no business taking pchar arguments.

Cheers,

md

Reply by email

Unknown author
to Marco van de Voort

To Marco and Jeppe:

As for 2 examples:

res := PosEx(mypchar,'NEEDLE',35) ;
res := Copy (mypchar, 10,15) ;

What are the byte boundaries here?
Zero Based from the pointer?
1 Based from the pointer?

As far as behavior, it would throw the program in unstable land over time and gdb
would show worthless garbage on Backtrace with a stack that was totally upside down.

When I stumbled across these calls and cleaned them up to keep pchar and ansistring operations
clearly separate, magically, stability returned to my program.

The reason I posted this to the list is that it is my responsibility to the community to raise
the chatter, even though I cannot right now produce a working sample to reproduce the bug.

I absolutely love the combination of Lazarus 1.08/FPC 2.6.2. Awesome, awesome, awesome.
My productivity just went up 10x.

And we get Mac OSX targets, IOS targets, and Android NDK targets!

Cheers,

md

Could you maybe describe this weird, erratic behavior?

Marco van de Voort wrote 7 lines
In our previous episode, said: > Passing a Pchar gives weird, erratic behavior Please make minimal examples in a few lines, and add them to the bugtracker. _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email

Marco van de Voort
to Unknown author

In our previous episode, said:

Show quoted text 5 lines
As for 2 examples: res := PosEx(mypchar,'NEEDLE',35) ; res := Copy (mypchar, 10,15) ;

These are not examples. These are snippets. Examples I can compile and debug.

What are the byte boundaries here? Zero Based from the pointer?

I think it will scan the pointer till a zero character, and then copy that to an ansistring. Next pass the ansistring to posex.

Reply by email

Unknown author
to Unknown author: To Marco and Jeppe: As for 2 examples: res := PosEx(mypchar,'NEEDLE',35) ; res := Copy…

Oops, those parameters for Posex were backwards:

res := PosEx('NEEDLE',mypchar,35) ;
Show quoted text 55 lines
To Marco and Jeppe: As for 2 examples: res := PosEx(mypchar,'NEEDLE',35) ; res := Copy (mypchar, 10,15) ; What are the byte boundaries here? Zero Based from the pointer? 1 Based from the pointer? As far as behavior, it would throw the program in unstable land over time and gdb would show worthless garbage on Backtrace with a stack that was totally upside down. When I stumbled across these calls and cleaned them up to keep pchar and ansistring operations clearly separate, magically, stability returned to my program. The reason I posted this to the list is that it is my responsibility to the community to raise the chatter, even though I cannot right now produce a working sample to reproduce the bug. I absolutely love the combination of Lazarus 1.08/FPC 2.6.2. Awesome, awesome, awesome. My productivity just went up 10x. And we get Mac OSX targets, IOS targets, and Android NDK targets! Cheers, md Could you maybe describe this weird, erratic behavior? On 6/11/2013 12:58 AM, Marco van de Voort wrote: > In our previous episode, said: >> Passing a Pchar gives weird, erratic behavior > Please make minimal examples in a few lines, and add them to the > bugtracker. > _______________________________________________ > fpc-pascal maillist - > http://lists.freepascal.org/mailman/listinfo/fpc-pascal >

Reply by email

Antonio Fortuny
to Unknown author: To Marco and Jeppe: As for 2 examples: res := PosEx(mypchar,'NEEDLE',35) ; res := Copy…

Hi Folks.

I don't know how Jeppe is playing around but because I want to make sure FPC works preoperly I decided to take some time to see what happens Yhis is the code snippet I use in Win32 and Linux x86_64 All are Lazaur 1.0.8

Put the code under a TButton and send results to a TMemo:

procedure TFrmMain.BtnTestClick(Sender: TObject);
var
   P: Integer;
   str: String;
   pc: PChar;
   len: Integer;
begin
   str := 'http://bcms.webdev.tralala.com/testudf.php?action=goodanswer';
   len := Length(str);
   P := PosEx('bcms', str, 3);
   Memo1.Lines.Add(Format('search "bcms" in %s: position %d', [str, P]));
   pc := nil;
   ReAllocMem(pc, len + 1);
   Move(PChar(str)^, pc^, len);
   pc[len] := #0;
   P := PosEx('bcms', pc, 3);
   Memo1.Lines.Add(Format('search "bcms" in %s: position %d', [str, P]));
end;

I've made the test with a PChar too

TMemo.Lines shows:
search "bcms" in
http://bcms.webdev.tralala.com/testudf.php?action=goodanswer: position 8 search "bcms" in
http://bcms.webdev.tralala.com/testudf.php?action=goodanswer: position 8

which, obviously looks correct. That's what I expect since more than 15 years (beginning with Delphi and Pos function)

Enjoy,

Antonio.

Sita Software *Antonio Fortuny* Senior Software engineer 220, avenue de la Liberté L-4602 Niederkorn Tel.: +352 58 00 93 - 93 www.sitasoftware.lu <http://www.sitasoftware.lu> Your IT Partner

Reply by email

Unknown author
to Antonio Fortuny

I totally understand, but I did not discover the problem until I was well into a larger project that I could not de-construct to try to generate a reproducible sample.

I am under a time pressure, decided to start using using LAZ/FPC about 3 months ago,
and when I starting running the program under load, it started to die.

So I cleaned up my string function calls, separated out the pchar calls, and things just magically healed themselves.

The program passes ALL of my load testing and just keeps running.

Do not ask me to reproduce it since I cannot
and I do not dispute that in a single threaded
test application, that it works.

The problem is when you start building up a large pile of code and then start up the high volume testing, things really show themselves.

The problem in this particular case is the the GDB back trace on segment fault was total garbage,
so I cannot use that to tell you where the bug is.

Trust me, I am putting my financial basis into the binary output of the FPC compiler since I can produce a much larger quantity of code faster
for LInux and Mac than I can with GCC/Xcode.

But for those like me, this serves as a warning to pay attention to this aspect.

There is not some underlying instability, but I believe a certain combination of things
causes a pointer reference that is off into la-la land.

My problems were in Copy( ) and PosEx( ), nothing more.

You guys rock!

md

Antonio Fortuny wrote 58 lines
Hi Folks. I don't know how Jeppe is playing around but because I want to make sure FPC works preoperly I decided to take some time to see what happens Yhis is the code snippet I use in Win32 and Linux x86_64 All are Lazaur 1.0.8 Put the code under a TButton and send results to a TMemo: procedure TFrmMain.BtnTestClick(Sender: TObject); var P: Integer; str: String; pc: PChar; len: Integer; begin str := 'http://bcms.webdev.tralala.com/testudf.php?action=goodanswer'; len := Length(str); P := PosEx('bcms', str, 3); Memo1.Lines.Add(Format('search "bcms" in %s: position %d', [str, P])); pc := nil; ReAllocMem(pc, len + 1); Move(PChar(str)^, pc^, len); pc[len] := #0; P := PosEx('bcms', pc, 3); Memo1.Lines.Add(Format('search "bcms" in %s: position %d', [str, P])); end; I've made the test with a PChar too TMemo.Lines shows: search "bcms" in http://bcms.webdev.tralala.com/testudf.php?action=goodanswer: position 8 search "bcms" in http://bcms.webdev.tralala.com/testudf.php?action=goodanswer: position 8 which, obviously looks correct. That's what I expect since more than 15 years (beginning with Delphi and Pos function) Enjoy, Antonio. -- Sita Software *Antonio Fortuny* Senior Software engineer 220, avenue de la Liberté L-4602 Niederkorn Tel.: +352 58 00 93 - 93 www.sitasoftware.lu <http://www.sitasoftware.lu> Your IT Partner _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email

Felipe Monteiro de Carvalho
to Unknown author
Show quoted text 8 lines
I totally understand, but I did not discover the problem until I was well into a larger project that I could not de-construct to try to generate a reproducible sample. I am under a time pressure, decided to start using using LAZ/FPC about 3 months ago, and when I starting running the program under load, it started to die.

In my experience when such strange issues appeared and I started distrusting the RTL, every single time I eventually could track the bug to .... an error in my own code. Don't remember the RTL ever causing such issues in all those years. You probably have a memory corruption, uninitialized variable or some other error in your code which causes the problem, but depending on the problem it might be really hard to debug.

Sometimes when debugging didn't help, I simply resorted to reading the entire code base again ... until I found the error.

Running in a different operating system also helps, sometimes it debugs better in another OS. Sometimes it even works fine in another OS, despite the error being present at all times =D

Felipe Monteiro de Carvalho

Reply by email