Sign in Join

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

Mailing lists / fpc-pascal / 2005-05

SizeOf(File) SizeOf(FileRec)

18 messages · 5 people · –

Reply by email Subscribe to this list Your subscription

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

Søren Ager

Hi,

I have been playing around with Free Pascal for OS/2 but have stumbled into a problem. I can't compile sockets.pas as SizeOf(File) SizeOf(FileRec). So I made a test program - and it shows me that userdata is only 16 bytes - how can that be? If I change the definition of filerec other parts break! What is going on???

{$I filerec.inc}
type
   mytest = array[1..32] of byte;
begin
   writeln(sizeof(file));
   writeln(sizeof(filerec));
   writeln('----');
   writeln(sizeof(filerec.Handle));
   writeln(sizeof(filerec.Mode));
   writeln(sizeof(filerec.RecSize));
   writeln(sizeof(filerec._private));
   writeln(sizeof(filerec.UserData));
   writeln(sizeof(filerec.name));
   writeln(sizeof(mytest));
end.

Output:
332
316
----
4
4
4
32
16
256
32

Reply by email

Søren Ager
to Søren Ager
Søren Ager wrote
I can't compile sockets.pas as SizeOf(File) SizeOf(FileRec).

Turns out my problem was that I had the rtl directories in my unit paths. After I copied socket.pas and so32dll.pas to a new directory I am now able to compile them (after I added the missing pieces of code).

Take care,
Søren

Reply by email

Tomas Hajny
to Søren Ager

Date sent: Sun, 22 May 2005 09:34:38 +0200
From: Sřren Ager
To: FPC-Pascal users discussions
Subject: Re: [fpc-pascal] SizeOf(File) SizeOf(FileRec) Send reply to: FPC-Pascal users discussions

Hi Soren

Glad to see you here!

Show quoted text 6 lines
> I can't compile sockets.pas as SizeOf(File) SizeOf(FileRec). Turns out my problem was that I had the rtl directories in my unit paths. After I copied socket.pas and so32dll.pas to a new directory I am now able to compile them (after I added the missing pieces of code).

Are you willing to contribute your changes, so we could add unit sockets to supported units for the OS/2 target? That should open existing considerable codebase using this unit (primarily written for Unix platforms) to OS/2.

Regards

Tomas

Reply by email

Søren Ager
to Tomas Hajny
Tomas Hajny wrote
Are you willing to contribute your changes, so we could add unit sockets to supported units for the OS/2 target?

Sure - as soon as it actually works... Right now it compiles but my program crashes :-(

Take care,
Soren

Reply by email

Tomas Hajny
to Søren Ager

Date sent: Mon, 23 May 2005 10:40:07 +0200
From: Søren Ager
To: FPC-Pascal users discussions
Subject: Re: [fpc-pascal] SizeOf(File) SizeOf(FileRec) Send reply to: FPC-Pascal users discussions

Show quoted text 7 lines
Tomas Hajny wrote: > Are you willing to contribute your changes, so we could add unit > sockets to supported units for the OS/2 target? Sure - as soon as it actually works... Right now it compiles but my program crashes :-(

OK, let me know if there's anything I could help you with. Unfortunately, PMGDB is somewhat less comfortable than VP/2 IDE. :-(

Tomas

Reply by email

Søren Ager
to Tomas Hajny
Tomas Hajny wrote
OK, let me know if there's anything I could help you with. Unfortunately, PMGDB is somewhat less comfortable than VP/2 IDE. :-(

Thank you!!! I had not seen the PM version of GDB - it is still not the same as VP/2 but it is a lot better that the text mode version.

Take care,
Søren

Reply by email

Tomas Hajny
to Søren Ager

Date sent: Tue, 24 May 2005 06:56:40 +0200
From: Søren Ager
To: FPC-Pascal users discussions
Subject: Re: [fpc-pascal] SizeOf(File) SizeOf(FileRec) Send reply to: FPC-Pascal users discussions

Show quoted text 5 lines
> OK, let me know if there's anything I could help you with. > Unfortunately, PMGDB is somewhat less comfortable than VP/2 IDE. :-( Thank you!!! I had not seen the PM version of GDB - it is still not the same as VP/2 but it is a lot better that the text mode version.

Yes, it is. :-) If you encounter particular issues with GDB syntax, just ask here. BTW (just in case you didn't know), one good thing about GDB and the current environment is the possibility of post- mortem debugging in case it crashed completely with a core dump ("core core" in (PM)GDB).

Tomas

Reply by email

Søren Ager
to Tomas Hajny
Tomas Hajny wrote
BTW (just in case you didn't know), one good thing about GDB and the current environment is the possibility of post- mortem debugging in case it crashed completely with a core dump ("core core" in (PM)GDB).

I didn't know that - thanks for the tip.

I have now compiled and run my first program without errors - but it required me to manually modify the .s file before assembly and linking... Here are the details:

In so32dll.pas I have:
function connect(sock:Longint; const s_addr:sockaddr;
s_addr_len:Longint):Longint; cdecl; external 'SO32DLL' index 3;
That is called from sockets.pas:
Function Connect(Sock:Longint;const Addr; Addrlen:Longint):Boolean;
begin
   Connect:=so32dll.Connect(Sock,so32dll.SockAddr(Addr),AddrLen)=0;
   if not Connect then
     SocketError:=so32dll.sock_errno
   else
     SocketError:=0;
end;

The code generated for that call is:
# [214] Connect:=so32dll.Connect(Sock,so32dll.SockAddr(Addr),AddrLen)=0; pushl -12(%ebp)
movl -8(%ebp),%esi
subl $16,%esp
movl %esp,%edi
cld
movl $16,%ecx
rep
movsb
pushl -4(%ebp)
call SO32DLL_CONNECT$LONGINT$SOCKADDR$LONGINT$$LONGINT

BUT that crashes the program in SO32DLL

I then changed it to:
# [214] Connect:=so32dll.Connect(Sock,so32dll.SockAddr(Addr),AddrLen)=0; pushl -12(%ebp)
pushl -8(%ebp)
pushl -4(%ebp)
call SO32DLL_CONNECT$LONGINT$SOCKADDR$LONGINT$$LONGINT

Ant then it works!!

What do I need to do to make the compiler output that code so my program can run without errors?

Take care,
Søren

Reply by email

Tomas Hajny
to Søren Ager

Date sent: Tue, 24 May 2005 20:03:28 +0200
From: Søren Ager
To: FPC-Pascal users discussions
Subject: Re: [fpc-pascal] SizeOf(File) SizeOf(FileRec) Send reply to: FPC-Pascal users discussions

Show quoted text 46 lines
I have now compiled and run my first program without errors - but it required me to manually modify the .s file before assembly and linking... Here are the details: In so32dll.pas I have: function connect(sock:Longint; const s_addr:sockaddr; s_addr_len:Longint):Longint; cdecl; external 'SO32DLL' index 3; That is called from sockets.pas: Function Connect(Sock:Longint;const Addr; Addrlen:Longint):Boolean; begin Connect:=so32dll.Connect(Sock,so32dll.SockAddr(Addr),AddrLen)=0; if not Connect then SocketError:=so32dll.sock_errno else SocketError:=0; end; The code generated for that call is: # [214] # Connect:=so32dll.Connect(Sock,so32dll.SockAddr(Addr),AddrLen)=0; pushl -12(%ebp) movl -8(%ebp),%esi subl $16,%esp movl %esp,%edi cld movl $16,%ecx rep movsb pushl -4(%ebp) call SO32DLL_CONNECT$LONGINT$SOCKADDR$LONGINT$$LONGINT BUT that crashes the program in SO32DLL I then changed it to: # [214] # Connect:=so32dll.Connect(Sock,so32dll.SockAddr(Addr),AddrLen)=0; pushl -12(%ebp) pushl -8(%ebp) pushl -4(%ebp) call SO32DLL_CONNECT$LONGINT$SOCKADDR$LONGINT$$LONGINT Ant then it works!! What do I need to do to make the compiler output that code so my program can run without errors?

I believe the C const construct (const declaration in a call marked as cdecl) is wrongly used in so32dll.connect (the meaning of this construct in C is different from the Pascal "const" modifier). If address of the record should be passed, use either "var" modifier (which doesn't have a particular meaning in C and is thus "safe"), or pass the pointer directly.

In addition, I'd be careful about alignment of record fields. It seems the right size of 16 is used for SockAddr now, but it could depend on used compiler options, so it's probably better to add explicit {$PACKRECORDS 1} to so32dll.pas.

Tomas

Reply by email

Søren Ager
to Tomas Hajny
Tomas Hajny wrote
I believe the C const construct (const declaration in a call marked as cdecl) is wrongly used in so32dll.connect (the meaning of this construct in C is different from the Pascal "const" modifier).

I am programming in Pascal so I can't see what C has to do with it ;-) I am only interested in changing the caling convention - not the meaning of the const which should be the same as var - with the exception that you are not allowed to change the parameter. So you are saying there is no way to make it behave like that? :-(

If address of the record should be passed, use either "var" modifier

That works - but it is not optimal as I have to double buffer all calls in the standard units from const to var. Sockets.pas:

Function Connect(Sock:Longint;const Addr; Addrlen:Longint):Boolean;
var
   sa : so32dll.SockAddr;
begin
   sa:=so32dll.SockAddr(Addr);
   Connect:=so32dll.Connect(Sock,sa,AddrLen)=0;
   if not Connect then
     SocketError:=so32dll.sock_errno
   else
     SocketError:=0;
end;

And it gets worse when I have an untyped buffer (as send does) - then I will have to allocate memory - copy the contents - call the dll - deallocate...

depend on used compiler options, so it's probably better to add explicit {$PACKRECORDS 1} to so32dll.pas.

Done

Take care,
Soren

Reply by email

Jonas Maebe
to Søren Ager
Søren Ager wrote
I am programming in Pascal so I can't see what C has to do with it ;-) I am only interested in changing the caling convention - not the meaning of the const which should be the same as var - with the exception that you are not allowed to change the parameter

No, const does not mean the same as var. For example, a "const a: longint" parameter is passed by value.

Jonas

Reply by email

Tomas Hajny
to Søren Ager: I am programming in Pascal so I can't see what C has to do with it ;-) I am only…

Date sent: Wed, 25 May 2005 09:29:00 +0200
From: Søren Ager
To: FPC-Pascal users discussions
Subject: [fpc-pascal] cdecl calling and const parameters - was SizeOf(File) SizeOf(FileRec)
Send reply to: FPC-Pascal users discussions

Show quoted text 5 lines
> I believe the C const construct (const declaration in a call marked > as cdecl) is wrongly used in so32dll.connect (the meaning of this > construct in C is different from the Pascal "const" modifier). I am programming in Pascal so I can't see what C has to do with it ;-)

You expect them to behave the same way as you're used to from Pascal, but ask FPC to call the function in a way compatible to C by using a cdecl modifier. ;-) Yes, the meaning of a cdecl modifier is somewhat different in FPC from some other Pascal compilers - but it's designed so for better compatibility with those C compilers?

Show quoted text 21 lines
I am only interested in changing the caling convention - not the meaning of the const which should be the same as var - with the exception that you are not allowed to change the parameter. So you are saying there is no way to make it behave like that? :-( > If address of the record should be passed, use either "var" modifier That works - but it is not optimal as I have to double buffer all calls in the standard units from const to var. Sockets.pas: Function Connect(Sock:Longint;const Addr; Addrlen:Longint):Boolean; var sa : so32dll.SockAddr; begin sa:=so32dll.SockAddr(Addr); Connect:=so32dll.Connect(Sock,sa,AddrLen)=0; if not Connect then SocketError:=so32dll.sock_errno else SocketError:=0; end;

My suggestion would be:

1) Provide the (relevant) library calls in so32dll.pas with two (overloaded) versions, one with the more C-like approach using pointers, the other more pascallish with var pointers.

2) Use the pointer version in sockets.pas - that's perfectly compatible to the const parameters and is by the way the same what's done for the Unix implementations using C library - /rtl/inc/stdsock.inc (Unix implementations using kernel syscalls have different calling convention).

And it gets worse when I have an untyped buffer (as send does) - then I will have to allocate memory - copy the contents - call the dll - deallocate...

Actually, it gets better there. ;-) Parameters cannot be passed on stack if they are untyped, so they are passed by reference as expected by you. That's another potential solution to your issue, although I wouldn't recommend discarding the types in declarations in cases these are known (e.g. in Connect), because that would remove the advantage of Pascal type checking.

Tomas

Reply by email

Søren Ager
to Tomas Hajny
Tomas Hajny wrote
My suggestion would be:

I copied what the win32 socket does: connect calls fpconnect calls so32dll.connect. That takes care of my problems and should make the os/2 socket unit 100% compatible with other fp units.

So how/who do I submit the source to?

Take care,

Soren

Reply by email

Tomas Hajny
to Søren Ager

Date sent: Wed, 25 May 2005 11:40:12 +0200
From: Søren Ager
To: FPC-Pascal users discussions
Subject: Re: [fpc-pascal] cdecl calling and const parameters - was SizeOf(File) SizeOf(FileRec)
Send reply to: FPC-Pascal users discussions

Show quoted text 7 lines
Tomas Hajny wrote: > My suggestion would be: I copied what the win32 socket does: connect calls fpconnect calls so32dll.connect. That takes care of my problems and should make the os/2 socket unit 100% compatible with other fp units.

Yes, that's probably the best.

So how/who do I submit the source to?

Send it to my address. I guess that in this case it's probably better to send the whole file(s) and not just diffs. I'll modify the Makefiles accordingly (unless you did that too) and commit it to SVN.

Tomas

Reply by email

chromdildo
to Tomas Hajny: Date sent: Wed, 25 May 2005 09:29:00 +0200 From: Søren Ager To: …

Hello everybody.

I discovered a very strange bug/issue and I don't know how to describe it best as a bug-report.
(or am I doing something wrong?)
I try: a variable declared within a record, AccessViolates when set later in code,
if declared at the "wong" place..?..

(environment: linux/i686 - fpc 2.0.0)
look at this small snipplet: (attached full testing.pas source for reproduction):

//<-snip->
type Teumex_memory = record
     pin          : Tchange_string;
     // amtsbelegung : Tchange_bool;    // <-- leave it here, everything
is ok.
     msn          : array [0..9] of Tchange_string;
     port         : array [0..9] of Tchange_string;
     amtsbelegung : Tchange_bool;    // <-- put it there: Access
violation when amtsbelegung is set
end;
//<-snip->

Best regards
./chrom

Reply by email

Florian Klaempfl
to chromdildo

chromdildo wrote:

Well, in your program :) Compile with range checking ot see it.

Show quoted text 108 lines
Hello everybody. I discovered a very strange bug/issue and I don't know how to describe it best as a bug-report. (or am I doing something wrong?) I try: a variable declared within a record, AccessViolates when set later in code, if declared at the "wong" place..?.. (environment: linux/i686 - fpc 2.0.0) look at this small snipplet: (attached full testing.pas source for reproduction): //<-snip-> type Teumex_memory = record pin : Tchange_string; // amtsbelegung : Tchange_bool; // <-- leave it here, everything is ok. msn : array [0..9] of Tchange_string; port : array [0..9] of Tchange_string; amtsbelegung : Tchange_bool; // <-- put it there: Access violation when amtsbelegung is set end; //<-snip-> Best regards ./chrom ------------------------------------------------------------------------ program bugtest; {$mode objfpc}{$H+} uses classes, sysutils; type Tchange_string = record value: string; changed : boolean; end; type Tchange_int= record value: integer; changed : boolean; end; type Tchange_bool= record value: boolean; changed : boolean; end; //The internal memory of the eumex (sample) type Teumex_memory = record pin : Tchange_string; // amtsbelegung : Tchange_bool; // <-- leave it here, everything is ok. msn : array [0..9] of Tchange_string; port : array [0..9] of Tchange_string; amtsbelegung : Tchange_bool; // <-- put it there: Access violation when setting end; TEumex = class private FMemory : Teumex_memory; public property Memory : Teumex_memory read FMemory write FMemory; end; var Eumex1 : TEumex; ic : integer; begin Eumex1 := TEumex.create; writeln ('setting PIN:'); Eumex1.Memory.pin.value := '1234'; Eumex1.Memory.pin.changed := true; writeln ('setting amtsbelgegung'); Eumex1.Memory.amtsbelegung.value := true; // <-- Access violation, if declared like above Eumex1.Memory.amtsbelegung.changed := true; for ic:= 1 to 10 do begin Eumex1.Memory.msn[ic].value := ''; Eumex1.Memory.msn[ic].changed := false; Eumex1.Memory.port[ic].value := '0'; Eumex1.Memory.port[ic].changed := false; end; end. ------------------------------------------------------------------------ _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email

Jonas Maebe
to chromdildo: Hello everybody. I discovered a very strange bug/issue and I don't know how to describe…
chromdildo wrote
msn : array [0..9] of Tchange_string; port : array [0..9] of Tchange_string;

This array goes from 0 till 9

Show quoted text 6 lines
for ic:= 1 to 10 do begin Eumex1.Memory.msn[ic].value := ''; Eumex1.Memory.msn[ic].changed := false; Eumex1.Memory.port[ic].value := '0'; Eumex1.Memory.port[ic].changed := false; end;

And here you go from 1 to 10. The reason it doesn't crash in one case and that it does crash in another case, is due to alignment differences (in the "crash case", your record is bigger, so there is more chance you will write beyond the boundary of allocated memory).

Jonas

Reply by email

chromdildo
to Florian Klaempfl: Well, in your program :) Compile with range checking ot see it.

Thanks for the quick reply.
...I see, stupid me. :)

But when the position of "amtsbelegung : Tchange_bool;" is changed, no AV occurs ..?
Reproducable?
Something about Memory Acces.... I think I got it.

Best regards
./chrom

Florian Klaempfl wrote 124 lines
chromdildo wrote: Well, in your program :) Compile with range checking ot see it. >Hello everybody. > >I discovered a very strange bug/issue and I don't know how to describe >it best as a bug-report. >(or am I doing something wrong?) >I try: a variable declared within a record, AccessViolates when set >later in code, >if declared at the "wong" place..?.. > >(environment: linux/i686 - fpc 2.0.0) >look at this small snipplet: (attached full testing.pas source for >reproduction): > >//<-snip-> >type Teumex_memory = record > pin : Tchange_string; > // amtsbelegung : Tchange_bool; // <-- leave it here, everything >is ok. > msn : array [0..9] of Tchange_string; > port : array [0..9] of Tchange_string; > amtsbelegung : Tchange_bool; // <-- put it there: Access >violation when amtsbelegung is set >end; >//<-snip-> > > >Best regards >./chrom > > >------------------------------------------------------------------------ > >program bugtest; > >{$mode objfpc}{$H+} > >uses classes, sysutils; > > > >type Tchange_string = record > value: string; > changed : boolean; >end; > >type Tchange_int= record > value: integer; > changed : boolean; >end; > >type Tchange_bool= record > value: boolean; > changed : boolean; >end; > >//The internal memory of the eumex (sample) >type Teumex_memory = record > pin : Tchange_string; > > // amtsbelegung : Tchange_bool; // <-- leave it here, everything is ok. > > msn : array [0..9] of Tchange_string; > port : array [0..9] of Tchange_string; > > amtsbelegung : Tchange_bool; // <-- put it there: Access violation when setting >end; > > > >TEumex = class > private > FMemory : Teumex_memory; > public > property Memory : Teumex_memory read FMemory write FMemory; >end; > > >var Eumex1 : TEumex; > ic : integer; > > >begin > Eumex1 := TEumex.create; > > writeln ('setting PIN:'); > Eumex1.Memory.pin.value := '1234'; > Eumex1.Memory.pin.changed := true; > > writeln ('setting amtsbelgegung'); > Eumex1.Memory.amtsbelegung.value := true; // <-- Access violation, if declared like above > Eumex1.Memory.amtsbelegung.changed := true; > > for ic:= 1 to 10 do begin > Eumex1.Memory.msn[ic].value := ''; > Eumex1.Memory.msn[ic].changed := false; > Eumex1.Memory.port[ic].value := '0'; > Eumex1.Memory.port[ic].changed := false; > end; > > >end. > > >------------------------------------------------------------------------ > >_______________________________________________ >fpc-pascal maillist - >http://lists.freepascal.org/mailman/listinfo/fpc-pascal > > _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email