Closed GWRon closed 9 years ago
Compiling with option "-gdb" can sometimes be useful too.
Maybe you should add this option to MaxIDE then (Debug, Debug GDB). Recompiled the whole project with "-gdb" (recompile enforced as it else reused the normal debugbuild which existed already)
./bmk makeapp -t console -d -a -gdb "/path/to/my/project.bmx"
... happily recompiled the project ...
when running the project via "gdb" the crash details are the same (same for backtrace).
Did I miss a step?
EDIT: ok, recompiled the modules too:
Program received signal SIGSEGV, Segmentation fault.
0x0859cad9 in brl_reflection_TTypeId_ForObject (bbt_obj=0xce05330)
at /home/ronny/Arbeit/Programmieren/BlitzMaxNG/mod/brl.mod/reflection.mod/reflection.bmx:1813
1813 EndIf
Right before that endif the source is this:
Function ForObject:TTypeId( obj:Object )
_Update
Local class:Byte Ptr=bbRefGetObjectClass( obj )
If class=ArrayTypeId._class
If Not bbRefArrayLength( obj ) Return ArrayTypeId
Return TypeIdForTag( bbRefArrayTypeTag( obj ) ).ArrayType()
Else
Return TTypeId( _classMap.ValueForKey( New TClass.SetClass( class ) ) )
EndIf
So something there is not working as intended ?
Ok, So I appended some "debug print" right before that Return TTypeId(...)
if not _classMap then Print "ForObject: _classMap Missing"
'
if not class then Print "ForObject: class is null"
'
if not New TClass.SetClass( class ) then print "ForObject: SetClass failed"
'
if not _classMap.ValueForKey( New TClass.SetClass( class ) ) then Print "ForObject: _classMap.ValueForKey NULL"
Return TTypeId( _classMap.ValueForKey( New TClass.SetClass( class ) ) )
It fails at the first '
which I assume means, it failed the line before (like with that "endif"). Which means _classMap
is null
in that call. But this _classMap
is a global one ...so I assume this cannot be the case. Why is it failing at odd lines (like EndIf
or '
) ...
Ok ... so I expanded the first if to be:
If _classMap
Print "ForObject: _classMap exists"
Else
print "ForObject: _classMap Missing"
EndIf
Recompiled modules, recompiled (of course then) my project ... and it prints some "_classMap exists" when cloning objects ... but as soon as it has to clone the type with "cast:TProgrammePersonJob[]" it fails at the line: Print "ForObject: _classMap exists"
(which I think means it fails on If _classMap
) ... but how could such a thing fail?
I tried more and more things - I even created a new file only importing things used in the specific situation - and it does not crash there (cloning the basic objects by hand) but it fails as soon as it is done via the more complicated routines in the db-xml-loader.
I assume that there is something borked in reflection.mod and it needs a rare situation to make it break.
Feel free to download the most current version from: https://github.com/GWRon/TVTower and compile on your own. As compilation is a bit slow, I prepared a smaller example (still using much of the game objects) - this sample also segfaults. Place it next to "TVTower.bmx":
SuperStrict
Framework Brl.StandardIO
Import "source/game.database.bmx"
Global l:TDatabaseLoader = New TDatabaseLoader
l.Load("res/database/Default/database.xml")
The problematic line is in source/game.database.bmx
:
Method LoadV3ProgrammeLicenceFromNode:TProgrammeLicence(node:TxmlNode, xml:TXmlHelper, parentLicence:TProgrammeLicence = Null)
...
'try to clone the parent's data - if that fails, create
'a new instance
if parentLicence then programmeData = TProgrammeData(THelper.CloneObject(parentLicence.data))
"data" is valid (checked that before).
But it only fails if the "TProgrammeData" contains something in the field "cast:TProgrammePersonJob[]" (leave it empty be commenting out the "AddCast")
Edit: it is not important if the "cast" is of type "TProgrammePersonJob" - it segfaults in that type as soon as I append a "complex" type:
Type TProgrammeData extends TGameObject {_exposeToLua}
Field objectArray:TMap[] = [new TMap,new TMap]
will fail at "objectArray" then...
Ok, I shrinked my example to this one:
SuperStrict
Framework Brl.StandardIO
Import "source/game.programme.programmedata.bmx"
Import "source/game.programme.programmeperson.bmx"
'create a base person so the cast of the data block can get filled
Local person:TProgrammePerson = New TProgrammePerson
'create an entry
Local programmeData:TProgrammeData = New TProgrammeData
'add sample cast - only fails with something set in the cast (else it is not "cloned")
programmeData.AddCast(New TProgrammePersonJob.Init(person, TVTProgrammePersonJob.ACTOR))
'this fails (when "cast"-field is the thing to clone)
THelper.CloneObject(programmeData)
Print "cloned..."
Any hints to narrow it down even further?
Ok ... next try, this time I removed every external source, so the following code is a "single file" example:
EDIT: made the code even shorter:
SuperStrict
Framework Brl.StandardIO
Import Brl.Reflection
Type TDataBlock
Field cast:TSubData[]
End Type
Type TSubData
Field bla:Int
End Type
Local data:TDataBlock = New TDataBlock
'add sample entry - only works with this
data.cast :+ [New TSubData]
Print "Fetching objTypeIDs: "
Local objTypeID:TTypeId = TTypeId.ForObject(data)
For Local fld:TField = EachIn objTypeID.EnumFields()
Print " Field: "+fld.name
If fld.Get(data)
Print " Field: not empty!"
'this fails for our array
Local subObjTypeID:TTypeId = TTypeId.ForObject(fld.Get(data))
EndIf
Next
Print "Fetched."
It fails as soon as it has to get the "ForObject" of the array.
The latest bcc commit should hopefully resolve this issue.
BTW: If you want to close an issue in another repo: "Closes/Fixes bmx-ng/brl.mod#14" in your bcc-ng-commit would close this issue.
Sample of course compiles now...
ATM recompiling my game (takes a while) ... finished, failing in another situation now ... so prepare for new issues :laughing:
I am using this code to clone objects:
Using it, segfaults for me:
Backtrace:
The last line in the c-file references
fld.Set(clone, CloneObject(fld.Get(obj)))
(when iterating over fields). The second last line references the portionI printed out the field name right before "fld.Set()" and it was the field "cast" in my case, which is defined as
Field cast:TProgrammePersonJob[]
(an array).So somehow this crashes when "obj" is an array of this type. I tried to reproduce it in a simple example but it did not crash for this. Maybe I am interpreting the BackTrace in a wrong way?