This is all covered in Pointers. in fact, I checked there myself to remind me, as I dont use the Mercury language much myself, day to day.
This would be in regards to your malloc example. A quick glance for use of malloc/free in this context can clarify it more in my opinion. I’ve haven’t used VB.NET in awhile myself so I’m also refreshing myself.
malloc()
is a system API specific to Island. But i’ll add a section, yes. good idea.
Great, also I’m genuinely amazed by the flexibility this toolchain can offer. Although not a pointer issue, I attempted to make a small test with the InlineAsm attribute. However, the MSBuild task returns as failed for some reason. I’ve marked the method as External which does function properly using it as a DLL import.
Module Program
<InlineAsm("
movl $749, %eax
retl
","",False,False), External>
Function testAsm() As Integer
End Function
Sub Main(args as String())
writeLn($"Test: {testAsm()}")
End Sub
End Module
|Error||(MSB4181) The MSBuildTask task returned false but did not log an error.|ConsoleApplication1|C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\RemObjects Software\Elements\RemObjects.Elements.Island.Windows.targets|53||
thanx! I am happy to hear that! Please spurred the word ;).
Reproduced. looks like this crashes LLVM, and the error is not properly reported back. in the full log I see
-> Phase Generating Output started.
LLVM ERROR: Invalid $ operand number in inline asm string: '
movl $749, %eax
=================================================================
I’ll log an issue for passing these errors back more cleanly, if possible.
I have no idea if the error is valid, I’d have to check with my colleague @ck.
bugs://E26719
I was able to compile it by adding an additional $. Likely it confused the parser.
Module Program
<InlineAsm("
movl $$749, %eax
ret
","",False,False), External>
Function testAsm() As Integer
End Function
Sub Main(args as String())
writeLn($"Test: {testAsm()}")
End Sub
End Module
That sounds more correct yes. This should match the clang behavior.
Also, while reviewing a couple of old posts here regarding InlineAsm, has there ever been a decision to allow the use of clobbering and I/O variables? Full assembly should work fine for most needs and as a workaround I can define a variable as static to use it directly.
@ck?
I reviewed the source of the Island RTL, along with reading the VoidAsm documentation. It seems that you do support it, however I’m not sure of the correct syntax of a constraint string for Clang as it’s hard to find clear documentation for this form, just the Extended Asm form for GCC. I’ve tried the following, but the variables still seem not to pass:
Function testAsm(x As Integer, y As Integer) As Integer
Dim c As Integer
InternalCalls.VoidAsm(" mov $1, %eax
add $2, %eax
mov %eax, $0
","=r,r,r,~{eax}",False,False, c, x, y) '~{} means clobbered register?
Return c
End Function
EDIT: I found the LLVM IR document which mentions the constraint syntax. However, I’m still noticing the constraints seemingly have no affect in passing the variables to assembly from the argument array.
Porting the above code to Oxygene also fails. Even when substituting Integer with NativeInt and using the 64bit registers instead. I’m using https://github.com/remobjects/IslandRTL/blob/master/Source/WindowsHelpers.pas as a guide as well.
I would have no expectation that this would not behave the same on Mercury and Oxygene, yes.
Also when testing the workaround method with static variables, under Linux the code runs fine in debug mode. Yet when it’s compiled as release, a segfault occurs:
Code:
Module Program
/*<InlineAsm("
add %ecx, %edx
mov %edx, %eax
ret
","",False,False), External>*/
Function testAsm(x As Integer, y As Integer) As Integer
Static a, b, c As Integer = 0
a = x : b = y
InternalCalls.VoidAsm("
movl f_t1d_ConsoleApplication3_d_Program.a$$3(%rip), %eax
movl f_t1d_ConsoleApplication3_d_Program.b$$4(%rip), %ebx
addl %ebx, %eax
movl %eax, f_t1d_ConsoleApplication3_d_Program.c$$5(%rip)
","",False,False)
Return c
End Function
Sub Main(args as String())
writeLn($"Test: {testAsm(271, 332)}")
End Sub
End Module
GDB Info from release build:
Program received signal SIGSEGV, Segmentation fault.
0x00000000002bb852 in GC_find_limit_with_bound ()
(gdb) backtrace
#0 0x00000000002bb852 in GC_find_limit_with_bound ()
#1 0x00000000002bb626 in GC_init_linux_data_start ()
#2 0x00000000002b3336 in GC_init ()
#3 0x00000000002b230d in ms_ta__1sBoehmGC6_LoadGC ()
#4 0x00000000002b270f in ms_ta__1sBoehmGC3_Newnp_vni () at boehmgc.pas:379
#5 0x000000000038e022 in __elements_entry_point_helper () at posixhelpers.pas:603
#6 0x00007ffff7c5b0b3 in __libc_start_main (main=0x38df60 <__elements_entry_point_helper>, argc=1,
argv=0x7fffffffdfa8, init=, fini=, rtld_fini=,
stack_end=0x7fffffffdf98) at …/csu/libc-start.c:308
#7 0x00000000002dcb29 in _start () at posixhelpers.pas:134
You can continue or ignore that signal. It’s as designed and caught by the GC itself.
Ok, is there a way to trap the GC segfault in code to bypass the error message? As stated the addition returns normally when compiled with debug symbols. Windows is normal in either debug or release mode. I would prefer to use constraints, however the variables do not seem to pass.
Use this in GDB:
handle SIGSEGV nostop noprint
Okay, but the problem is that this code is compiled for release so it will not be ran using GDB. It seg faults on execution only as a release binary.
Right but this callstack:
Program received signal SIGSEGV, Segmentation fault.
0x00000000002bb852 in GC_find_limit_with_bound ()
(gdb) backtrace
#0 0x00000000002bb852 in GC_find_limit_with_bound ()
#1 0x00000000002bb626 in GC_init_linux_data_start ()
#2 0x00000000002b3336 in GC_init ()
#3 0x00000000002b230d in ms_ta__1sBoehmGC6_LoadGC ()
#4 0x00000000002b270f in ms_ta__1sBoehmGC3_Newnp_vni () at boehmgc.pas:379
#5 0x000000000038e022 in __elements_entry_point_helper () at posixhelpers.pas:603
#6 0x00007ffff7c5b0b3 in __libc_start_main (main=0x38df60 <__elements_entry_point_helper>, argc=1,
argv=0x7fffffffdfa8, init=, fini=, rtld_fini=,
stack_end=0x7fffffffdf98) at …/csu/libc-start.c:308
#7 0x00000000002dcb29 in _start () at posixhelpers.pas:134
Should be caught by the GC. It’s probably not your release crash…
I confirmed that it is the release build. I’ve included a link to both the debug and release binaries.
But does this error actually crash the app, when not running in the debugger?