Re: [fpc-devel] https support; call for testers

2014-05-12 Thread Marco van de Voort
In our previous episode, Michael Van Canneyt said:
> >
> > #0 HANDLEERRORADDRFRAME(201, 0x15ff0dc, 0x2e2f48) at ..\inc\system.inc:962
> > #1 HANDLEERRORFRAME(201, 0x15ff0dc) at ..\inc\system.inc:992
> > #2 fpc_rangeerror at ..\inc\system.inc:653
> > #3 CONNECT(0x2e72a8) at ..\source\ssockets.pp:860
> 
> That is the line:
> 
>addr.sin_addr.s_addr := HostToNet(a.s_addr);

HostToNet is only defined for in_addr and longint, and s_addr is cuint32.

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] https support; call for testers

2014-05-12 Thread Michael Van Canneyt



On Mon, 12 May 2014, Marco van de Voort wrote:


In our previous episode, Michael Van Canneyt said:


#0 HANDLEERRORADDRFRAME(201, 0x15ff0dc, 0x2e2f48) at ..\inc\system.inc:962
#1 HANDLEERRORFRAME(201, 0x15ff0dc) at ..\inc\system.inc:992
#2 fpc_rangeerror at ..\inc\system.inc:653
#3 CONNECT(0x2e72a8) at ..\source\ssockets.pp:860


That is the line:

   addr.sin_addr.s_addr := HostToNet(a.s_addr);


HostToNet is only defined for in_addr and longint, and s_addr is cuint32.


On all platforms ?

Strange then that this error didn't happen before. 
Well, a simple typecast will solve this.


Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] https support; call for testers

2014-05-12 Thread Dimitrios Chr. Ioannidis

Hi,

Στις 12/5/2014 10:11 πμ, ο/η Michael Van Canneyt έγραψε:



On Mon, 12 May 2014, Marco van de Voort wrote:


In our previous episode, Michael Van Canneyt said:


#0 HANDLEERRORADDRFRAME(201, 0x15ff0dc, 0x2e2f48) at 
..\inc\system.inc:962

#1 HANDLEERRORFRAME(201, 0x15ff0dc) at ..\inc\system.inc:992
#2 fpc_rangeerror at ..\inc\system.inc:653
#3 CONNECT(0x2e72a8) at ..\source\ssockets.pp:860


That is the line:

addr.sin_addr.s_addr := HostToNet(a.s_addr);


HostToNet is only defined for in_addr and longint, and s_addr is 
cuint32.


On all platforms ?

Strange then that this error didn't happen before. Well, a simple 
typecast will solve this.


you're correct if changed it to

addr.sin_addr.s_addr := HostToNet(LongInt(a.s_addr));

i get a 504 Error also.

regards,

--
Dimitrios Chr. Ioannidis



smime.p7s
Description: Κρυπτογραφημένη υπογραφή S/MIME
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] https support; call for testers

2014-05-12 Thread Marco van de Voort
In our previous episode, Michael Van Canneyt said:
> > HostToNet is only defined for in_addr and longint, and s_addr is cuint32.
> 
> On all platforms ?
> 
> Strange then that this error didn't happen before. 
> Well, a simple typecast will solve this.

They are old, and carry this comment: 

{ these for are for netdb legacy compat}

IIRC they were kept for 1.0.x compatibility, and the 32-bit unsigned support
of that was not so great. Moreover I didn't care enough to deprecate them,
but maybe we should.

The newer (1.9.2+) htons etc functions (introduced with that name for Kylix
compat) are unsigned.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] https support; call for testers

2014-05-12 Thread Michael Van Canneyt



On Mon, 12 May 2014, Marco van de Voort wrote:


In our previous episode, Michael Van Canneyt said:

HostToNet is only defined for in_addr and longint, and s_addr is cuint32.


On all platforms ?

Strange then that this error didn't happen before.
Well, a simple typecast will solve this.


They are old, and carry this comment:

{ these for are for netdb legacy compat}

IIRC they were kept for 1.0.x compatibility, and the 32-bit unsigned support
of that was not so great. Moreover I didn't care enough to deprecate them,
but maybe we should.


Eh, what are you talking about ? HostToNet ? 
The 'On all platforms' was referring to 's_addr is cuint32'.



The newer (1.9.2+) htons etc functions (introduced with that name for Kylix
compat) are unsigned.


We could deprecate HostToNet and let it call htons.

Michael.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] https support; call for testers

2014-05-12 Thread Marco van de Voort
In our previous episode, Michael Van Canneyt said:
> >
> > { these for are for netdb legacy compat}
> >
> > IIRC they were kept for 1.0.x compatibility, and the 32-bit unsigned support
> > of that was not so great. Moreover I didn't care enough to deprecate them,
> > but maybe we should.
> 
> Eh, what are you talking about ? HostToNet ? 

Yes. That's also the part that carried the "netdb legacy" comment.

> The 'On all platforms' was referring to 's_addr is cuint32'.
> 
> > The newer (1.9.2+) htons etc functions (introduced with that name for Kylix
> > compat) are unsigned.
> 
> We could deprecate HostToNet and let it call htons.

Yup. Same for short* etc. I'll deprecate them when I have time somewhere
today, and then will try to fix all warnings to the new ones.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


[fpc-devel] Stack dump with possible segfault

2014-05-12 Thread Johann Glaser
Hi!

I'm working on a project with an external library (libtcl, it is written
in C) which creates some problems with back traces for exceptions.

If a custom TCL command raises an exception, I catch it and use the
function DumpExceptionBackTrace to print the back trace. This function
uses RaiseList which returns the ExceptObjectStack pointer. The stack
frame information is filled by fpc_PushExceptObj in except.inc using the
functions get_frame, get_caller_addr and get_caller_frame.

These three functions are also used by dump_stack which can be used at
any point in the code (outside of exceptions).

These three functions assume, that the stack frame is stored in the RBP
register (x86_64 architecture) and that every function call starts with
these two assembler instructions
  push   %rbp
  mov%rsp,%rbp
which leads to the stack layout of the return address (pushed by the
"call" instruction) followed by the RBP value.

As this is true for FreePascal code (I guess), this doesn't necessarily
hold for external libraries as the TCL library mentioned above.

In my particular case, GDB shows the following back trace after hitting
a breakpoint in my custom TCL function implemented in
INSERTTRFSMWRAPPER:

#1  0x0040eb3c in INSERTTRFSMWRAPPER (this=0x77fe8340, OBJC=1, 
OBJV=0x79d080) at trfsmgen.lpr:2552
#2  0x0048f86f in CMDCALLER (CLIENTDATA=0x77fe8cc0, 
INTERP=0x78f700, OBJC=1, OBJV=0x79d080) at ../pas-tcl/src/tcloop.pas:317
#3  0x77aea8f8 in TclEvalObjvInternal (interp=interp@entry=0x78f700, 
objc=objc@entry=1, objv=objv@entry=0x79d080, command=0x77fe9890 
'insert_trfsm_wrapper', length=20, flags=flags@entry=0) at 
/tmp/buildd/tcl8.5-8.5.15/unix/../generic/tclBasic.c:3708
#4  0x77aeb85b in TclEvalEx (interp=0x78f700, script=0x77fe9890 
'insert_trfsm_wrapper', numBytes=, flags=, 
line=line@entry=1, clNextOuter=clNextOuter@entry=0x0, 
outerScript=0x77fe9890 'insert_trfsm_wrapper')
at /tmp/buildd/tcl8.5-8.5.15/unix/../generic/tclBasic.c:4407
#5  0x77aeb096 in Tcl_EvalEx (interp=, script=, numBytes=, flags=) at 
/tmp/buildd/tcl8.5-8.5.15/unix/../generic/tclBasic.c:4064
#6  0x0048fe65 in EVAL (this=0x77fe8380, SCRIPT=0x77fe9890 
'insert_trfsm_wrapper') at ../pas-tcl/src/tcloop.pas:385
#7  0x004db8a2 in EXECUTE (this=0x77fde1c0, COMMAND=0x77fe9890 
'insert_trfsm_wrapper') at ../pas-tcl/src/tclcmdline.pas:230
#8  0x004da790 in EXECUTE (this=0x77fde1c0, COMMAND=0x77fe9890 
'insert_trfsm_wrapper') at ../pas-tcl/src/tclcmdlinepredef.pas:184
#9  0x004dbe49 in COMMANDLOOP (this=0x77fde1c0) at 
../pas-readline/src/cmdline.pas:81
#10 0x004daf89 in COMMANDLOOP (this=0x77fde1c0) at 
../pas-tcl/src/tclcmdline.pas:76
#11 0x004923ad in RUN (this=0x77fe8340) at 
../pas-tcl/src/tclapp.pas:63
#12 0x004133ed in main () at trfsmgen.lpr:3319

This list is very reasonable.

TclEvalObjvInternal() is disassembled as follows:

Dump of assembler code for function TclEvalObjvInternal:
   0x77aea6c0 <+0>: push   %r15
   0x77aea6c2 <+2>: mov%rcx,%r15
   0x77aea6c5 <+5>: push   %r14
   0x77aea6c7 <+7>: push   %r13
   0x77aea6c9 <+9>: push   %r12
   0x77aea6cb <+11>:mov%esi,%r12d
   0x77aea6ce <+14>:push   %rbp
   0x77aea6cf <+15>:mov%rdi,%rbp
   0x77aea6d2 <+18>:push   %rbx
   0x77aea6d3 <+19>:mov%r9d,%ebx
   ...

RBP is the 5th register pushed to the stack instead of the first one.
The function TclEvalEx() looks similar but pushes different registers
before RBP.

Now there are two problems:
 1) DumpExceptionBackTrace and dump_stack don't show the full stack
trace.
 2) Both functions dereference values which were taken from the stack
and go through a linked list (which is not guaranteed to be
working), therefore dereferencing values which might not even be
pointers.

Problem 1) is inconvenient but just a cosmetic thing. I had a look at
the GDB sources (backtrace_command() in gdb/stack.c and
get_current_frame() and get_prev_frame_1() in gdb/frame.c), but
especially the latter function is extremely complicated and trying
multiple approaches to unwind the stack. I gave up on this. :-(

The more important thing is problem 2) since it potentially creates a
segfault. Two counter-measures are already met in dump_stack: the
previous frame must be at a lower memory address as the current frame
(because "push" decreases RSP), and zero-pointers are used as stop
conditions.

I suggest that additionally the RBP values are checked that they are
within the program stack address range and divisible by SizeOf(PtrUInt).
Further, the caller address (=return address) should be checked that it
is within the program code address range. This might get a bit tricky
for shared libraries.

For this debugging stuff I've worked on a small routine which parses
(and cach