SmartPointer_UDTname_ segmentation violation

Forum for discussion about the documentation project.
Post Reply
PeterHu
Posts: 159
Joined: Jul 24, 2022 4:57

SmartPointer_UDTname_ segmentation violation

Post by PeterHu »

Example crashed with fbc1.2.0(2024-03-09) both 32 & 64 bit under windows 10 64 bit.


https://www.freebasic.net/wiki/ProPgOperatorOverloading

Code: Select all


root constructor:           Mouse
  animal constructor:       Mouse
root constructor:           Buddy
  animal constructor:       Buddy
    dog constructor:        Buddy
root constructor:           Tiger
  animal constructor:       Tiger
    cat constructor:        Tiger

reference counter value: 3
  1883928422208             Mouse
  1883928422352             Buddy
  1883928422496             Tiger

Name:         Object (real):         Hierarchy:

Aborting due to runtime error 12 ("segmentation violation" signal) in E:\Learning\FreeBasic\ex\macroex\smartptr03.bas::PRINTINFO()
fxm
Moderator
Posts: 12132
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: SmartPointer_UDTname_ segmentation violation

Post by fxm »

THANK YOU

This "segmentation violation" signal only appears since version 1.10.0 of fbc.
The simple change:
Sub PrintInfo (ByVal ByRef p As root Ptr)
is enough to correct it (otherwise, the value of the pointer passed is polluted!!!).

I will try to isolate/simplify this abnormal behavior, but it will not be immediate because the code is quite complex.
SARG
Posts: 1768
Joined: May 27, 2005 7:15
Location: FRANCE

Re: SmartPointer_UDTname_ segmentation violation

Post by SARG »

Maybe this change :
https://github.com/freebasic/fbc/commit ... a66ea84827

There is this call just before printinfo : call _ZN17SMARTPOINTER_ROOTcvP4ROOTEv
Returned value is used as parameter.

A cast :
Operator SmartPointer_##_UDTname_.Cast () As _UDTname_ Ptr
Return This.p
End Operator
PeterHu
Posts: 159
Joined: Jul 24, 2022 4:57

Re: SmartPointer_UDTname_ segmentation violation

Post by PeterHu »

Thank you both!

It is fine.I want to learn how to write a complicated macro and found this.It will be great if fbc support syntactic check and points to the exact place when there is an error,rather than just points to the place where certain procedure/method been called.I knew there is some typo in #macro ...#endmacro but it is really hard to find.

Code: Select all

E:\Learning\FreeBasic\ex\macroex>fbc smartptr02.bas
smartptr02.bas(186) error 147: Default types or suffixes are only valid in -lang deprecat
ed or fblite or qb, found 'rhs'
smartptr02.bas(186) error 42: Variable not declared, rhs
smartptr02.bas(186) error 3: Expected End-of-Line, found 'rhs'
smartptr02.bas(186) error 9: Expected expression, found 'rhs'
smartptr02.bas(186) error 127: Expected 'END CONSTRUCTOR', found 'end'
smartptr02.bas(195) error 20: Type mismatch, found ','

dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: SmartPointer_UDTname_ segmentation violation

Post by dodicat »

That is when you use the option -pp to isolate an error.
simple example:
fillmatrix.bas

Code: Select all

'#cmdline "-pp"
Type Matrix 
    Dim As Double m( Any , Any )
    Declare Constructor ( )
    Declare Constructor ( Byval x As Uinteger , Byval y As Uinteger )
    Declare Operator Cast() As String
End Type

Constructor Matrix ( )
End Constructor

Constructor Matrix ( Byval x As Uinteger , Byval y As Uinteger )
    Redim this.m(1 To x,1 To y)
End Constructor

Operator matrix.cast() As String
Dim As String s,comma
        For r As Long=1 To Ubound(m,1)
            For c As Long=1 To Ubound(m,2)
                If c<Ubound(m,2) Then comma="," Else comma=""
                s+=Str(m(r,c))+comma
            Next
            s+=Chr(10)
        Next
        Return s
End Operator

 #macro fill(a,r,c,d...)
        a=matrix(r,c)
        Scope
        Dim As Double x(1 To r,1 To c)=d
        For n As Long=1 To Ubound(a.m,1)
            For m As Long=1 To Ubound(a.m,2)
                a.m(n,m)=x(n,m) mistake
            Next
            Next
          End Scope      
 #endmacro
    
        
Dim As matrix b
fill(b,3,6,{{1,2,3,8,0,4}, _
            {4,-5,6,-8,-2,1}, _
            {7,8,9,12,3.5,2}})
            
            Print b
        Sleep
             
 
It fails compile at line 45 ish
Then with -pp option (top line) compile again to get fillmatrix.pp.bas
You are directed to the error in fillmatrix.pp.bas when you compile it.
If you knew all this already then ignore this post.
PeterHu
Posts: 159
Joined: Jul 24, 2022 4:57

Re: SmartPointer_UDTname_ segmentation violation

Post by PeterHu »

No,I did not.

This is exactly what I need to learn.Thank you so much.
PeterHu
Posts: 159
Joined: Jul 24, 2022 4:57

Re: SmartPointer_UDTname_ segmentation violation

Post by PeterHu »

With my own version of the example(I wrote it line by line exactly according to the manual),not just copy and paste from the manual)Line 213~215, " " & sp(i) ---> Is this legal?I don't think so.The complier won't compile.

Code: Select all

For I As Integer = 0 To 2
        Print "  " & sp(I), sp(I)->ObjectName()
    Next I
Weird thing:
a. When I change

Code: Select all

 print " " & sp(i) 
to

Code: Select all

 print " " , sp(i)
build is successful.
b. Don't touch the source bas file,rather do

Code: Select all

 fbc -pp src.bas
and also do not touch the src.pp.bas ,just compile it,build successful.
c. but when compile the the original source that copied from the manual,the compile just compiled successfully even with

Code: Select all

 print " " & sp(i)
coderJeff
Site Admin
Posts: 4326
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: SmartPointer_UDTname_ segmentation violation

Post by coderJeff »

fxm wrote: Mar 23, 2024 10:02 I will try to isolate/simplify this abnormal behavior, but it will not be immediate because the code is quite complex.
Here is the shortest I found so far. Try fbc-1.10+ with 'SHOW_CHANGE = true|false'.

When SHOW_CHANGE=true, fbc-1.10+ assigns the result of CAST() as ROOT ptr to a temporary variable, and then passes the address of the temporary. The presence of declared constructors / operators affects the code generation even though those constructors and operators are never called and need not be defined for this example - which leads me to believe that this is a bug in the constructor/let/cast matching logic.

Code: Select all

const SHOW_CHANGE = true

type ROOT extends object
	#if SHOW_CHANGE
		Declare Constructor (Byref _name As String = "")
		Declare Operator Let (Byref rhs As root)
	#endif
end type

type SmartPointer_ROOT
	o as ROOT ptr
	declare constructor ( byval p as ROOT ptr )
	declare operator cast() as ROOT ptr
	#if SHOW_CHANGE
		declare operator cast() as string
	#endif
end type

constructor SmartPointer_ROOT( byval p as ROOT ptr )
	o = p
end constructor

operator SmartPointer_ROOT.cast( ) as ROOT ptr
	return o
end operator 

sub proc1( byval p as ROOT ptr )
	#if SHOW_CHANGE
		print "address of the temporary result of CAST() as ROOT ptr"
	#else
		print "result of CAST() as ROOT ptr"
	#endif
	print cunsg( p )
end sub

sub proc2( byref p as ROOT ptr )
	print "result of CAST() as ROOT ptr"
	print cunsg( p )
end sub

dim as SmartPointer_ROOT x = cast(ROOT ptr, 1)
proc1( x )

dim as SmartPointer_ROOT y = cast(ROOT ptr, 2)
proc2( y )

sleep
fxm
Moderator
Posts: 12132
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: SmartPointer_UDTname_ segmentation violation

Post by fxm »

Well done Jeff.

Otherwise I had already seen another configuration which presents the same behavior:

Code: Select all

const SHOW_CHANGE = true

type ROOT extends object
	Declare Constructor (Byref _name As String = "")
	#if SHOW_CHANGE
		Declare Operator Let (Byref rhs As root)
		'' same behavior with: Declare Constructor (Byref rhs As root), or both
	#endif
end type

type SmartPointer_ROOT
	o as ROOT ptr
	declare constructor ( byval p as ROOT ptr )
	declare operator cast() as ROOT ptr
	declare operator cast() as string
end type

constructor SmartPointer_ROOT( byval p as ROOT ptr )
	o = p
end constructor

operator SmartPointer_ROOT.cast( ) as ROOT ptr
	return o
end operator 

sub proc1( byval p as ROOT ptr )
	#if SHOW_CHANGE
		print "address of the temporary result of CAST() as ROOT ptr"
	#else
		print "result of CAST() as ROOT ptr"
	#endif
	print cunsg( p )
end sub

sub proc2( byref p as ROOT ptr )
	print "result of CAST() as ROOT ptr"
	print cunsg( p )
end sub

dim as SmartPointer_ROOT x = cast(ROOT ptr, 1)
proc1( x )

dim as SmartPointer_ROOT y = cast(ROOT ptr, 2)
proc2( y )

sleep
coderJeff
Site Admin
Posts: 4326
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: SmartPointer_UDTname_ segmentation violation

Post by coderJeff »

fxm wrote: Mar 23, 2024 16:39 Otherwise I had already seen another configuration which presents the same behavior:
Your example is better for debugging. Thank you.

I believe the logic is here:
ast-node-arg.bas#L869

1) If we are passing to a byval parameter, then check if there is a constructor that would work (assumption at this point is that a constructor will be used later; but evidently when building the procedure call, constructor is not used and we get some undesirable code generation).
2) If that fails, then check for a cast operator that would work
3) If that fails, then check for an exact match
4) If that fails, then error

I think we added logic in (1) to ensure that byval parameters of UDTs induce a copy - I don't know if UDT pointers were tested - because it seems like this won't make sense for byval UDT ptr types.
fxm
Moderator
Posts: 12132
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: SmartPointer_UDTname_ segmentation violation

Post by fxm »

Documentation updated:
ProPgOperatorOverloading → fxm [added in last example a workaround for a bug in fbc versions 1.10.0/1.10.1]

This is due to a bad code generation for an argument passed to a 'Byval UDT Ptr' parameter when a specific conversion environment is encountered.
The workaround consists in forcing an explicit cast before passing the argument:

Code: Select all

        #if __FB_VERSION__ = "1.10.0" Or __FB_VERSION__ = "1.10.1"
            PrintInfo(Cast(root Ptr, sp(I)))  '' bug workaround
        #else
            PrintInfo(sp(I))
        #endif

Note: In current working fbc version 1.20.0, this bug will be fixed very soon.
(fbc: fix bad code generation of operator cast() UDT ptr)
[edit] (25 Mar 2024)
Done.
Post Reply