# 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.
        
        
        
                

Reply via email to