# New Ticket Created by # Please include the string: [perl #125243] # in the subject line of all future correspondence about this issue. # <URL: https://rt.perl.org/Ticket/Display.html?id=125243 >
A large category of C library functions will take a pointer to a struct which will be populated by the function, a simple example is uname(3): use v6; use NativeCall; class Utsname is repr('CStruct') { has Str $.sysname; has Str $.nodename; has Str $.release; has Str $.version; has Str $.machine; } sub uname(Utsname $utsname is rw --> Int) is native { ... } my $a = Utsname.new; uname($a); The above code will segfault (gdb bt:) Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7b55a51 in MVM_nativecall_refresh () from /home/jonathan/.rakudobrew/moar-nom/install/lib/libmoar.so (gdb) bt #0 0x00007ffff7b55a51 in MVM_nativecall_refresh () from /home/jonathan/.rakudobrew/moar-nom/install/lib/libmoar.so #1 0x00007ffff7b5660e in MVM_nativecall_invoke () from /home/jonathan/.rakudobrew/moar-nom/install/lib/libmoar.so #2 0x00007ffff7b33477 in MVM_interp_run () from /home/jonathan/.rakudobrew/moar-nom/install/lib/libmoar.so #3 0x00007ffff7bd87ab in MVM_vm_run_file () from /home/jonathan/.rakudobrew/moar-nom/install/lib/libmoar.so #4 0x000000000040101f in main () And valgrind: ================================================================================================ This is Rakudo Perl 6 running in valgrind, a tool for debugging and profiling programs. Running a program in valgrind usually takes *a lot* more time than running it directly, so please be patient. This Rakudo version is 2015.5.14.g.800.f.703 built on MoarVM version 2015.5, running on fedora (21.Twenty.One) / linux (1.SMP.Thu.May.7.22.0.21.UTC.2015) ------------------------------------------------------------------------------------------------ ==16422== Memcheck, a memory error detector ==16422== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==16422== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info ==16422== Command: /home/jonathan/.rakudobrew/moar-nom/install/bin/moar --execname=/home/jonathan/.rakudobrew/bin/../moar-nom/install/bin/perl6-valgrind-m --libpath=/home/jonathan/.rakudobrew/moar-nom/install/share/nqp/lib --libpath=/home/jonathan/.rakudobrew/moar-nom/install/share/perl6/lib --libpath=/home/jonathan/.rakudobrew/moar-nom/install/share/perl6/runtime /home/jonathan/.rakudobrew/moar-nom/install/share/perl6/runtime/perl6.moarvm tt.p6 ==16422== ==16422== Syscall param uname(buf) points to unaddressable byte(s) ==16422== at 0x39628C3C67: uname (syscall-template.S:81) ==16422== by 0x4E13F58: ??? (in /home/jonathan/.rakudobrew/moar-nom/install/lib/libmoar.so) ==16422== by 0xFFEFFF51F: ??? ==16422== by 0x4E13E93: dc_callvm_call_x64 (in /home/jonathan/.rakudobrew/moar-nom/install/lib/libmoar.so) ==16422== by 0x39628C3C5F: ??? (in /usr/lib64/libc-2.20.so) ==16422== by 0xBE09B8F: ??? ==16422== by 0x4D747DE: MVM_nativecall_invoke (in /home/jonathan/.rakudobrew/moar-nom/install/lib/libmoar.so) ==16422== by 0x5788237: ??? ==16422== by 0x9F1A11F: ??? ==16422== by 0xA011E5F: ??? ==16422== by 0x16: ??? ==16422== by 0x7: ??? ==16422== Address 0xaabd268 is 0 bytes after a block of size 40 alloc'd ==16422== at 0x4A08946: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) ==16422== by 0x4DA692B: initialize (in /home/jonathan/.rakudobrew/moar-nom/install/lib/libmoar.so) ==16422== by 0x4D541A3: MVM_interp_run (in /home/jonathan/.rakudobrew/moar-nom/install/lib/libmoar.so) ==16422== by 0x4DF67AA: MVM_vm_run_file (in /home/jonathan/.rakudobrew/moar-nom/install/lib/libmoar.so) ==16422== by 0x40101E: main (in /home/jonathan/.rakudobrew/moar-nom/install/bin/moar) ==16422== ==16422== ==16422== HEAP SUMMARY: ==16422== in use at exit: 54,868,899 bytes in 185,882 blocks ==16422== total heap usage: 346,369 allocs, 160,487 frees, 119,286,300 bytes allocated ==16422== ==16422== LEAK SUMMARY: ==16422== definitely lost: 52,412 bytes in 1,045 blocks ==16422== indirectly lost: 24,439 bytes in 923 blocks ==16422== possibly lost: 171,800 bytes in 3,071 blocks ==16422== still reachable: 54,620,248 bytes in 180,843 blocks ==16422== suppressed: 0 bytes in 0 blocks ==16422== Rerun with --leak-check=full to see details of leaked memory ==16422== ==16422== For counts of detected and suppressed errors, rerun with: -v ==16422== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) I think that it may actually be specific to something in the libc as a much simpler case does actually work: foo.c: /* gcc -c -fPIC -O3 -DNDEBUG -D_REENTRANT -D_FILE_OFFSET_BITS=64 -fPIC -o foo.o foo.c gcc -shared -fPIC -O3 -DNDEBUG -Wl,-rpath,/home/jonathan/.rakudobrew/moar-nom/install/lib -lm -lpthread -lrt -ldl -o foo.so foo.o */ struct Foo { char *thing; }; extern void do_foo(struct Foo *param) { static char *bar = "Test"; param->thing = bar; } /* void main() { struct Foo baz; do_foo(&baz); printf("%s\n", baz.thing); } */ foo.p6: use v6; use NativeCall; class Foo is repr('CStruct') { has Str $.thing is rw; } sub do_foo(Foo $foo is rw) is native('./foo.so') { ... } my $a = Foo.new; do_foo($a); say $a.thing; Does actually work as expected, so I'm quite will to accept that it's my bug in the uname() code though I guess it shouldn't actually segfault anyway.