Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NativeCall segfault on rw struct pointer #4260

Closed
p6rt opened this issue May 24, 2015 · 7 comments
Closed

NativeCall segfault on rw struct pointer #4260

p6rt opened this issue May 24, 2015 · 7 comments
Labels
SEGV Segmentation fault, bus error, etc.

Comments

@p6rt
Copy link

p6rt commented May 24, 2015

Migrated from rt.perl.org#125243 (status was 'rejected')

Searchable as RT125243$

@p6rt
Copy link
Author

p6rt commented May 24, 2015

From jns@gellyfish.co.uk

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.
 
 
 
 

@p6rt
Copy link
Author

p6rt commented Jun 17, 2015

From @hoelzro

On 2015-05-24 04​:54​:10, jns@​gellyfish.co.uk wrote​:

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.

I'm wondering if the reason for this is that struct utsname's members are char [] of unspecified sizes, rather than char *.

@p6rt
Copy link
Author

p6rt commented Jun 17, 2015

The RT System itself - Status changed from 'new' to 'open'

@p6rt
Copy link
Author

p6rt commented Aug 8, 2016

From @skids

The problem is that struct utsname is different sizes on different kernels.
Padding the structure out gets rid of the SEGV. I'm not sure there is much
more sensible that NativeCall/rakudo can be expected to do other than SEGV
when a C function writes outside a protected region. I see it is possible
to catch a SEGV, but at that point are we confident enough in the memory
protection setup/layout to even continue running with that turned into an
unresumable exception or are we just asking for security issues if we do?

At any rate in this specific case, you'd need shaped native CArray attributes
(NYI), and a CUnion of all possible layouts (and knowhow to figure out
which was in use) just to make the structure work at all. Also the return
type should be uint3 not Int.

@p6rt
Copy link
Author

p6rt commented Oct 6, 2016

From @niner

I'm rejecting this ticket because the given example is simply wrong.
NativeCall translates a Str to char *, i.e. a pointer to a character array. Thus it will reserve the memory to hold such a pointer.

The fields in struct utsname are character arrays. The docs specify them as e.g. char sysname[]; which is a bit misleading as one would assume that this is the same as char *sysname. The NOTES section however explains that the length of those arrays differs from system to system.

/usr/include/linux/utsname.h defines it as char sysname[__NEW_UTS_LEN + 1]; with #define __NEW_UTS_LEN 64

So the fields in the Utsname structs must be 65 bytes in length. The only way I know to express this with current NativeCall features is this piece of beauty​:

use v6.c;
 
use NativeCall;

class Utsname is repr('CStruct') {
  has int8 $.sysname_0; has int8 $.sysname_1; has int8 $.sysname_2; has int8 $.sysname_3; has int8 $.sysname_4; has int8 $.sysname_5; has int8 $.sysname_6; has int8 $.sysname_7; has int8 $.sysname_8; has int8 $.sysname_9; has int8 $.sysname_10; has int8 $.sysname_11; has int8 $.sysname_12; has int8 $.sysname_13; has int8 $.sysname_14; has int8 $.sysname_15; has int8 $.sysname_16; has int8 $.sysname_17; has int8 $.sysname_18; has int8 $.sysname_19; has int8 $.sysname_20; has int8 $.sysname_21; has int8 $.sysname_22; has int8 $.sysname_23; has int8 $.sysname_24; has int8 $.sysname_25; has int8 $.sysname_26; has int8 $.sysname_27; has int8 $.sysname_28; has int8 $.sysname_29; has int8 $.sysname_30; has int8 $.sysname_31; has int8 $.sysname_32; has int8 $.sysname_33; has int8 $.sysname_34; has int8 $.sysname_35; has int8 $.sysname_36; has int8 $.sysname_37; has int8 $.sysname_38; has int8 $.sysname_39; has int8 $.sysname_40; has int8 $.sysname_41; has int8 $.sysname_42; has int8 $.sysname_43; has int8 $.sysname_44; has int8 $.sysname_45; has int8 $.sysname_46; has int8 $.sysname_47; has int8 $.sysname_48; has int8 $.sysname_49; has int8 $.sysname_50; has int8 $.sysname_51; has int8 $.sysname_52; has int8 $.sysname_53; has int8 $.sysname_54; has int8 $.sysname_55; has int8 $.sysname_56; has int8 $.sysname_57; has int8 $.sysname_58; has int8 $.sysname_59; has int8 $.sysname_60; has int8 $.sysname_61; has int8 $.sysname_62; has int8 $.sysname_63; has int8 $.sysname_64;
  has int8 $.nodename_0; has int8 $.nodename_1; has int8 $.nodename_2; has int8 $.nodename_3; has int8 $.nodename_4; has int8 $.nodename_5; has int8 $.nodename_6; has int8 $.nodename_7; has int8 $.nodename_8; has int8 $.nodename_9; has int8 $.nodename_10; has int8 $.nodename_11; has int8 $.nodename_12; has int8 $.nodename_13; has int8 $.nodename_14; has int8 $.nodename_15; has int8 $.nodename_16; has int8 $.nodename_17; has int8 $.nodename_18; has int8 $.nodename_19; has int8 $.nodename_20; has int8 $.nodename_21; has int8 $.nodename_22; has int8 $.nodename_23; has int8 $.nodename_24; has int8 $.nodename_25; has int8 $.nodename_26; has int8 $.nodename_27; has int8 $.nodename_28; has int8 $.nodename_29; has int8 $.nodename_30; has int8 $.nodename_31; has int8 $.nodename_32; has int8 $.nodename_33; has int8 $.nodename_34; has int8 $.nodename_35; has int8 $.nodename_36; has int8 $.nodename_37; has int8 $.nodename_38; has int8 $.nodename_39; has int8 $.nodename_40; has int8 $.nodename_41; has int8 $.nodename_42; has int8 $.nodename_43; has int8 $.nodename_44; has int8 $.nodename_45; has int8 $.nodename_46; has int8 $.nodename_47; has int8 $.nodename_48; has int8 $.nodename_49; has int8 $.nodename_50; has int8 $.nodename_51; has int8 $.nodename_52; has int8 $.nodename_53; has int8 $.nodename_54; has int8 $.nodename_55; has int8 $.nodename_56; has int8 $.nodename_57; has int8 $.nodename_58; has int8 $.nodename_59; has int8 $.nodename_60; has int8 $.nodename_61; has int8 $.nodename_62; has int8 $.nodename_63; has int8 $.nodename_64;
  has int8 $.release_0; has int8 $.release_1; has int8 $.release_2; has int8 $.release_3; has int8 $.release_4; has int8 $.release_5; has int8 $.release_6; has int8 $.release_7; has int8 $.release_8; has int8 $.release_9; has int8 $.release_10; has int8 $.release_11; has int8 $.release_12; has int8 $.release_13; has int8 $.release_14; has int8 $.release_15; has int8 $.release_16; has int8 $.release_17; has int8 $.release_18; has int8 $.release_19; has int8 $.release_20; has int8 $.release_21; has int8 $.release_22; has int8 $.release_23; has int8 $.release_24; has int8 $.release_25; has int8 $.release_26; has int8 $.release_27; has int8 $.release_28; has int8 $.release_29; has int8 $.release_30; has int8 $.release_31; has int8 $.release_32; has int8 $.release_33; has int8 $.release_34; has int8 $.release_35; has int8 $.release_36; has int8 $.release_37; has int8 $.release_38; has int8 $.release_39; has int8 $.release_40; has int8 $.release_41; has int8 $.release_42; has int8 $.release_43; has int8 $.release_44; has int8 $.release_45; has int8 $.release_46; has int8 $.release_47; has int8 $.release_48; has int8 $.release_49; has int8 $.release_50; has int8 $.release_51; has int8 $.release_52; has int8 $.release_53; has int8 $.release_54; has int8 $.release_55; has int8 $.release_56; has int8 $.release_57; has int8 $.release_58; has int8 $.release_59; has int8 $.release_60; has int8 $.release_61; has int8 $.release_62; has int8 $.release_63; has int8 $.release_64;
  has int8 $.version_0; has int8 $.version_1; has int8 $.version_2; has int8 $.version_3; has int8 $.version_4; has int8 $.version_5; has int8 $.version_6; has int8 $.version_7; has int8 $.version_8; has int8 $.version_9; has int8 $.version_10; has int8 $.version_11; has int8 $.version_12; has int8 $.version_13; has int8 $.version_14; has int8 $.version_15; has int8 $.version_16; has int8 $.version_17; has int8 $.version_18; has int8 $.version_19; has int8 $.version_20; has int8 $.version_21; has int8 $.version_22; has int8 $.version_23; has int8 $.version_24; has int8 $.version_25; has int8 $.version_26; has int8 $.version_27; has int8 $.version_28; has int8 $.version_29; has int8 $.version_30; has int8 $.version_31; has int8 $.version_32; has int8 $.version_33; has int8 $.version_34; has int8 $.version_35; has int8 $.version_36; has int8 $.version_37; has int8 $.version_38; has int8 $.version_39; has int8 $.version_40; has int8 $.version_41; has int8 $.version_42; has int8 $.version_43; has int8 $.version_44; has int8 $.version_45; has int8 $.version_46; has int8 $.version_47; has int8 $.version_48; has int8 $.version_49; has int8 $.version_50; has int8 $.version_51; has int8 $.version_52; has int8 $.version_53; has int8 $.version_54; has int8 $.version_55; has int8 $.version_56; has int8 $.version_57; has int8 $.version_58; has int8 $.version_59; has int8 $.version_60; has int8 $.version_61; has int8 $.version_62; has int8 $.version_63; has int8 $.version_64;
  has int8 $.machine_0; has int8 $.machine_1; has int8 $.machine_2; has int8 $.machine_3; has int8 $.machine_4; has int8 $.machine_5; has int8 $.machine_6; has int8 $.machine_7; has int8 $.machine_8; has int8 $.machine_9; has int8 $.machine_10; has int8 $.machine_11; has int8 $.machine_12; has int8 $.machine_13; has int8 $.machine_14; has int8 $.machine_15; has int8 $.machine_16; has int8 $.machine_17; has int8 $.machine_18; has int8 $.machine_19; has int8 $.machine_20; has int8 $.machine_21; has int8 $.machine_22; has int8 $.machine_23; has int8 $.machine_24; has int8 $.machine_25; has int8 $.machine_26; has int8 $.machine_27; has int8 $.machine_28; has int8 $.machine_29; has int8 $.machine_30; has int8 $.machine_31; has int8 $.machine_32; has int8 $.machine_33; has int8 $.machine_34; has int8 $.machine_35; has int8 $.machine_36; has int8 $.machine_37; has int8 $.machine_38; has int8 $.machine_39; has int8 $.machine_40; has int8 $.machine_41; has int8 $.machine_42; has int8 $.machine_43; has int8 $.machine_44; has int8 $.machine_45; has int8 $.machine_46; has int8 $.machine_47; has int8 $.machine_48; has int8 $.machine_49; has int8 $.machine_50; has int8 $.machine_51; has int8 $.machine_52; has int8 $.machine_53; has int8 $.machine_54; has int8 $.machine_55; has int8 $.machine_56; has int8 $.machine_57; has int8 $.machine_58; has int8 $.machine_59; has int8 $.machine_60; has int8 $.machine_61; has int8 $.machine_62; has int8 $.machine_63; has int8 $.machine_64;
  has int8 $.domainname_0; has int8 $.domainname_1; has int8 $.domainname_2; has int8 $.domainname_3; has int8 $.domainname_4; has int8 $.domainname_5; has int8 $.domainname_6; has int8 $.domainname_7; has int8 $.domainname_8; has int8 $.domainname_9; has int8 $.domainname_10; has int8 $.domainname_11; has int8 $.domainname_12; has int8 $.domainname_13; has int8 $.domainname_14; has int8 $.domainname_15; has int8 $.domainname_16; has int8 $.domainname_17; has int8 $.domainname_18; has int8 $.domainname_19; has int8 $.domainname_20; has int8 $.domainname_21; has int8 $.domainname_22; has int8 $.domainname_23; has int8 $.domainname_24; has int8 $.domainname_25; has int8 $.domainname_26; has int8 $.domainname_27; has int8 $.domainname_28; has int8 $.domainname_29; has int8 $.domainname_30; has int8 $.domainname_31; has int8 $.domainname_32; has int8 $.domainname_33; has int8 $.domainname_34; has int8 $.domainname_35; has int8 $.domainname_36; has int8 $.domainname_37; has int8 $.domainname_38; has int8 $.domainname_39; has int8 $.domainname_40; has int8 $.domainname_41; has int8 $.domainname_42; has int8 $.domainname_43; has int8 $.domainname_44; has int8 $.domainname_45; has int8 $.domainname_46; has int8 $.domainname_47; has int8 $.domainname_48; has int8 $.domainname_49; has int8 $.domainname_50; has int8 $.domainname_51; has int8 $.domainname_52; has int8 $.domainname_53; has int8 $.domainname_54; has int8 $.domainname_55; has int8 $.domainname_56; has int8 $.domainname_57; has int8 $.domainname_58; has int8 $.domainname_59; has int8 $.domainname_60; has int8 $.domainname_61; has int8 $.domainname_62; has int8 $.domainname_63; has int8 $.domainname_64;
}

sub uname(Utsname $utsname is rw --> int32) is native { ... }

my $a = Utsname.new;

uname($a);

say join '', $a.^attributes.map({chr $_.get_value($a)});

@p6rt
Copy link
Author

p6rt commented Oct 6, 2016

@niner - Status changed from 'open' to 'rejected'

@p6rt p6rt closed this as completed Oct 6, 2016
@p6rt
Copy link
Author

p6rt commented Oct 7, 2016

From jns@gellyfish.co.uk

No I think you're right.

A naive ticket :)

On Thu, 2016-10-06 at 13​:45 -0700, Stefan Seifert via RT wrote​:

I'm rejecting this ticket because the given example is simply wrong.
NativeCall translates a Str to char *, i.e. a pointer to a character
array. Thus it will reserve the memory to hold such a pointer.

The fields in struct utsname are character arrays. The docs specify
them as e.g. char sysname[]; which is a bit misleading as one would
assume that this is the same as char *sysname. The NOTES section
however explains that the length of those arrays differs from system
to system.

/usr/include/linux/utsname.h defines it as char sysname[__NEW_UTS_LEN
+ 1]; with #define __NEW_UTS_LEN 64

So the fields in the Utsname structs must be 65 bytes in length. The
only way I know to express this with current NativeCall features is
this piece of beauty​:

use v6.c;
        
use NativeCall;

class Utsname is repr('CStruct') {
    has int8 $.sysname_0; has int8 $.sysname_1; has int8 $.sysname_2;
has int8 $.sysname_3; has int8 $.sysname_4; has int8 $.sysname_5; has
int8 $.sysname_6; has int8 $.sysname_7; has int8 $.sysname_8; has
int8 $.sysname_9; has int8 $.sysname_10; has int8 $.sysname_11; has
int8 $.sysname_12; has int8 $.sysname_13; has int8 $.sysname_14; has
int8 $.sysname_15; has int8 $.sysname_16; has int8 $.sysname_17; has
int8 $.sysname_18; has int8 $.sysname_19; has int8 $.sysname_20; has
int8 $.sysname_21; has int8 $.sysname_22; has int8 $.sysname_23; has
int8 $.sysname_24; has int8 $.sysname_25; has int8 $.sysname_26; has
int8 $.sysname_27; has int8 $.sysname_28; has int8 $.sysname_29; has
int8 $.sysname_30; has int8 $.sysname_31; has int8 $.sysname_32; has
int8 $.sysname_33; has int8 $.sysname_34; has int8 $.sysname_35; has
int8 $.sysname_36; has int8 $.sysname_37; has int8 $.sysname_38; has
int8 $.sysname_39; has int8 $.sysname_40; has int8 $.sysname_41; has
int8 $.sysname_42; has int
 8 $.sysname_43; has int8 $.sysname_44; has int8 $.sysname_45; has
int8 $.sysname_46; has int8 $.sysname_47; has int8 $.sysname_48; has
int8 $.sysname_49; has int8 $.sysname_50; has int8 $.sysname_51; has
int8 $.sysname_52; has int8 $.sysname_53; has int8 $.sysname_54; has
int8 $.sysname_55; has int8 $.sysname_56; has int8 $.sysname_57; has
int8 $.sysname_58; has int8 $.sysname_59; has int8 $.sysname_60; has
int8 $.sysname_61; has int8 $.sysname_62; has int8 $.sysname_63; has
int8 $.sysname_64;
    has int8 $.nodename_0; has int8 $.nodename_1; has int8
$.nodename_2; has int8 $.nodename_3; has int8 $.nodename_4; has int8
$.nodename_5; has int8 $.nodename_6; has int8 $.nodename_7; has int8
$.nodename_8; has int8 $.nodename_9; has int8 $.nodename_10; has int8
$.nodename_11; has int8 $.nodename_12; has int8 $.nodename_13; has
int8 $.nodename_14; has int8 $.nodename_15; has int8 $.nodename_16;
has int8 $.nodename_17; has int8 $.nodename_18; has int8
$.nodename_19; has int8 $.nodename_20; has int8 $.nodename_21; has
int8 $.nodename_22; has int8 $.nodename_23; has int8 $.nodename_24;
has int8 $.nodename_25; has int8 $.nodename_26; has int8
$.nodename_27; has int8 $.nodename_28; has int8 $.nodename_29; has
int8 $.nodename_30; has int8 $.nodename_31; has int8 $.nodename_32;
has int8 $.nodename_33; has int8 $.nodename_34; has int8
$.nodename_35; has int8 $.nodename_36; has int8 $.nodename_37; has
int8 $.nodename_38; has int8 $.nodename_39; has int8 $.nodename_40;
has int8 $.n
 odename_41; has int8 $.nodename_42; has int8 $.nodename_43; has int8
$.nodename_44; has int8 $.nodename_45; has int8 $.nodename_46; has
int8 $.nodename_47; has int8 $.nodename_48; has int8 $.nodename_49;
has int8 $.nodename_50; has int8 $.nodename_51; has int8
$.nodename_52; has int8 $.nodename_53; has int8 $.nodename_54; has
int8 $.nodename_55; has int8 $.nodename_56; has int8 $.nodename_57;
has int8 $.nodename_58; has int8 $.nodename_59; has int8
$.nodename_60; has int8 $.nodename_61; has int8 $.nodename_62; has
int8 $.nodename_63; has int8 $.nodename_64;
    has int8 $.release_0; has int8 $.release_1; has int8 $.release_2;
has int8 $.release_3; has int8 $.release_4; has int8 $.release_5; has
int8 $.release_6; has int8 $.release_7; has int8 $.release_8; has
int8 $.release_9; has int8 $.release_10; has int8 $.release_11; has
int8 $.release_12; has int8 $.release_13; has int8 $.release_14; has
int8 $.release_15; has int8 $.release_16; has int8 $.release_17; has
int8 $.release_18; has int8 $.release_19; has int8 $.release_20; has
int8 $.release_21; has int8 $.release_22; has int8 $.release_23; has
int8 $.release_24; has int8 $.release_25; has int8 $.release_26; has
int8 $.release_27; has int8 $.release_28; has int8 $.release_29; has
int8 $.release_30; has int8 $.release_31; has int8 $.release_32; has
int8 $.release_33; has int8 $.release_34; has int8 $.release_35; has
int8 $.release_36; has int8 $.release_37; has int8 $.release_38; has
int8 $.release_39; has int8 $.release_40; has int8 $.release_41; has
int8 $.release_42; has int
 8 $.release_43; has int8 $.release_44; has int8 $.release_45; has
int8 $.release_46; has int8 $.release_47; has int8 $.release_48; has
int8 $.release_49; has int8 $.release_50; has int8 $.release_51; has
int8 $.release_52; has int8 $.release_53; has int8 $.release_54; has
int8 $.release_55; has int8 $.release_56; has int8 $.release_57; has
int8 $.release_58; has int8 $.release_59; has int8 $.release_60; has
int8 $.release_61; has int8 $.release_62; has int8 $.release_63; has
int8 $.release_64;
    has int8 $.version_0; has int8 $.version_1; has int8 $.version_2;
has int8 $.version_3; has int8 $.version_4; has int8 $.version_5; has
int8 $.version_6; has int8 $.version_7; has int8 $.version_8; has
int8 $.version_9; has int8 $.version_10; has int8 $.version_11; has
int8 $.version_12; has int8 $.version_13; has int8 $.version_14; has
int8 $.version_15; has int8 $.version_16; has int8 $.version_17; has
int8 $.version_18; has int8 $.version_19; has int8 $.version_20; has
int8 $.version_21; has int8 $.version_22; has int8 $.version_23; has
int8 $.version_24; has int8 $.version_25; has int8 $.version_26; has
int8 $.version_27; has int8 $.version_28; has int8 $.version_29; has
int8 $.version_30; has int8 $.version_31; has int8 $.version_32; has
int8 $.version_33; has int8 $.version_34; has int8 $.version_35; has
int8 $.version_36; has int8 $.version_37; has int8 $.version_38; has
int8 $.version_39; has int8 $.version_40; has int8 $.version_41; has
int8 $.version_42; has int
 8 $.version_43; has int8 $.version_44; has int8 $.version_45; has
int8 $.version_46; has int8 $.version_47; has int8 $.version_48; has
int8 $.version_49; has int8 $.version_50; has int8 $.version_51; has
int8 $.version_52; has int8 $.version_53; has int8 $.version_54; has
int8 $.version_55; has int8 $.version_56; has int8 $.version_57; has
int8 $.version_58; has int8 $.version_59; has int8 $.version_60; has
int8 $.version_61; has int8 $.version_62; has int8 $.version_63; has
int8 $.version_64;
    has int8 $.machine_0; has int8 $.machine_1; has int8 $.machine_2;
has int8 $.machine_3; has int8 $.machine_4; has int8 $.machine_5; has
int8 $.machine_6; has int8 $.machine_7; has int8 $.machine_8; has
int8 $.machine_9; has int8 $.machine_10; has int8 $.machine_11; has
int8 $.machine_12; has int8 $.machine_13; has int8 $.machine_14; has
int8 $.machine_15; has int8 $.machine_16; has int8 $.machine_17; has
int8 $.machine_18; has int8 $.machine_19; has int8 $.machine_20; has
int8 $.machine_21; has int8 $.machine_22; has int8 $.machine_23; has
int8 $.machine_24; has int8 $.machine_25; has int8 $.machine_26; has
int8 $.machine_27; has int8 $.machine_28; has int8 $.machine_29; has
int8 $.machine_30; has int8 $.machine_31; has int8 $.machine_32; has
int8 $.machine_33; has int8 $.machine_34; has int8 $.machine_35; has
int8 $.machine_36; has int8 $.machine_37; has int8 $.machine_38; has
int8 $.machine_39; has int8 $.machine_40; has int8 $.machine_41; has
int8 $.machine_42; has int
 8 $.machine_43; has int8 $.machine_44; has int8 $.machine_45; has
int8 $.machine_46; has int8 $.machine_47; has int8 $.machine_48; has
int8 $.machine_49; has int8 $.machine_50; has int8 $.machine_51; has
int8 $.machine_52; has int8 $.machine_53; has int8 $.machine_54; has
int8 $.machine_55; has int8 $.machine_56; has int8 $.machine_57; has
int8 $.machine_58; has int8 $.machine_59; has int8 $.machine_60; has
int8 $.machine_61; has int8 $.machine_62; has int8 $.machine_63; has
int8 $.machine_64;
    has int8 $.domainname_0; has int8 $.domainname_1; has int8
$.domainname_2; has int8 $.domainname_3; has int8 $.domainname_4; has
int8 $.domainname_5; has int8 $.domainname_6; has int8
$.domainname_7; has int8 $.domainname_8; has int8 $.domainname_9; has
int8 $.domainname_10; has int8 $.domainname_11; has int8
$.domainname_12; has int8 $.domainname_13; has int8 $.domainname_14;
has int8 $.domainname_15; has int8 $.domainname_16; has int8
$.domainname_17; has int8 $.domainname_18; has int8 $.domainname_19;
has int8 $.domainname_20; has int8 $.domainname_21; has int8
$.domainname_22; has int8 $.domainname_23; has int8 $.domainname_24;
has int8 $.domainname_25; has int8 $.domainname_26; has int8
$.domainname_27; has int8 $.domainname_28; has int8 $.domainname_29;
has int8 $.domainname_30; has int8 $.domainname_31; has int8
$.domainname_32; has int8 $.domainname_33; has int8 $.domainname_34;
has int8 $.domainname_35; has int8 $.domainname_36; has int8
$.domainname_37; has int8
  $.domainname_38; has int8 $.domainname_39; has int8
$.domainname_40; has int8 $.domainname_41; has int8 $.domainname_42;
has int8 $.domainname_43; has int8 $.domainname_44; has int8
$.domainname_45; has int8 $.domainname_46; has int8 $.domainname_47;
has int8 $.domainname_48; has int8 $.domainname_49; has int8
$.domainname_50; has int8 $.domainname_51; has int8 $.domainname_52;
has int8 $.domainname_53; has int8 $.domainname_54; has int8
$.domainname_55; has int8 $.domainname_56; has int8 $.domainname_57;
has int8 $.domainname_58; has int8 $.domainname_59; has int8
$.domainname_60; has int8 $.domainname_61; has int8 $.domainname_62;
has int8 $.domainname_63; has int8 $.domainname_64;
}

sub uname(Utsname $utsname is rw --> int32) is native { ... }

my $a = Utsname.new;

uname($a);

say join '', $a.^attributes.map({chr $_.get_value($a)});

@p6rt p6rt added the SEGV Segmentation fault, bus error, etc. label Jan 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
SEGV Segmentation fault, bus error, etc.
Projects
None yet
Development

No branches or pull requests

1 participant