This is a repost of the issue of libraries throwing a segfault regarding the GC when attempting to pass structures to functions under Linux. This specifically occurs when accessing an array in the structure, allocated either statically or via a pointer. The console project loads the library dynamically, which is in the binary folder.
Can we hold thisnuntal we have the issue wit the array sizes sorted out? im expecting this might be related, ie if the arrays are allocated on the heap when thye should not be, passing this between dll and exe, which both have their own heap management, might cause trouble and be “as expected”.
I assume when you pass a proven-flat structure (ie one where sizeof matches what you expect), no error happens?
Well the sizes do match as 80 in both the library and calling code (either the Mercury console app, or a C++ app compiled in GCC). However, assuming that you mean a structure without any arrays (static or dynamic), the code still segfaults without array references. Flattening the structure to just include 3 doubles and a byte still gives the same error.
Flat struct in library:
Module Test
Structure test
Dim x,y,z As Double
End Structure
Structure test2
' Dim v As test
Dim x, y, z As Double
Dim t As Byte
End Structure
<DLLExport("testFunc")>
'<SymbolName("test")>
Public Sub testFunc(t As test2)
writeLn("Struct values: ")
writeLn($"{t.t}")
writeLn($"{t.x} {t.y} {t.z}")
/*writeLn($"{t.v(0).x} {t.v(0).y} {t.v(0).z}")
writeLn($"{t.v(1).x} {t.v(1).y} {t.v(1).z}")
writeLn($"{t.v(2).x} {t.v(2).y} {t.v(2).z}")*/
End Sub
End Module
C++ console test (same result in Mercury console test):
Reading symbols from test...
(No debugging symbols found in test)
(gdb) run
Starting program: /home/sollapse/test
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Testing
32
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff78a20d2 in GC_find_limit_with_bound () from ./Library2.so
Okay. if I can get one completed test case that has all the pieces in one place and does not use arrays, that would be appreciated and I’ll log an issue to have the team have a look.
On Ubuntu 23.04 running in a VM, I’ve updated the code to include the original arrays which function properly. Although the same crash is occurring with the inline assembly functions. This works normally on Windows, and I’ve updated the code to highlight the different results received using either InlineAsm or InternalCalls.VoidAsm. I’ve used a fixed value to show the error more clearly and avoid any overflows from the RandomInt function.
This segfault is occurring in the main console binary with the added inline assembly code. I mentioned this in a previous post questioning how to properly use the clobbers/constraints in the assembly commands.
I completely understand that, however are your constraints functioning in regards to the library functions. I never got a response in regards to that question?
Edit: All errors are fixed now after changing the order of the expected registers for SystemV’s convention.
It would be in regards to the Island assembly functions as listed in the documentation:
VoidAsm
Inline assembly; this call is replaced by the AT&T syntax asm passed to this method.
[Oxygene]
[C#]
[Swift]
[Java]
[Mercury]
class method VoidAsm(aAsm: String; aConstraints: String; aSideEffects: Boolean; aAlign: Boolean; params aArgs: array of Object)
Parameters:
aAsm: The assembly to use; Note that $ has to be escaped with $ (so $$1 for decimal 1 in AT&T); $0 refers to the first parameter passed to aArgs, etc.
aConstraints: A clang compatible constraint string
aSideEffects: If true this asm block has side effects not visible in the constraint list
aAlign: If true, the stack has to be aligned before entering this blcok
aArgs: Argument array passed to asm.
For instance, the aConstraints parameter should be a string formatted in a LLVM IR compatible manner (ex. “+r” means a general register should be used as an input and output to a supplied variable). The variables to be used by assembly should be passed in aArgs. So if I wanted to return an integer defined as Dim a As Integer from assembly I would expect to do something like the following:
Dim a As Integer = 0
InternalCalls.VoidAsm( " mov $0, %ebx
add $$1, %ebx
mov %ebx, $0", "+r", false, false, a)
Understood. Although it’s great to have as an option if there’s any necessity for additional low-level code, especially regarding mobile platforms. I was able to get access to static defined variables by calling the symbol directly which serves the same purpose. It’s more tedious, but works.