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

SEGV with "output" CArray[Cstruct] in NativeCall #5182

Open
p6rt opened this issue Mar 17, 2016 · 2 comments
Open

SEGV with "output" CArray[Cstruct] in NativeCall #5182

p6rt opened this issue Mar 17, 2016 · 2 comments
Labels

Comments

@p6rt
Copy link

p6rt commented Mar 17, 2016

Migrated from rt.perl.org#127730 (status was 'new')

Searchable as RT127730$

@p6rt
Copy link
Author

p6rt commented Mar 17, 2016

From @jonathanstowe

I found this trying to make a binding for portmidi.

If one has library function that takes an argument of an array of structs that has been allocated by the caller and populated by the function like​:

#include <stdint.h>
#include <stdio.h>

typedef struct {
  int32_t message;
  int32_t timestamp;
} Event;

int Pm_Read(Event *buffer, int length) {
  Event event;
  event.message = 16;
  event.timestamp = 8;
  buffer[0] = event;
  return 1;
}

And then attempt to use it in a Perl 6 progran like​:
#!perl6

use NativeCall;

class Event is repr('CStruct') {
  has int32 $.message;
  has int32 $.timestamp;
}

sub Pm_Read(CArray[Event] $e, int32 $l) returns int32 is native('./test') { * }

my $a = CArray[Event].new;
$a[0] = Event.new;

Pm_Read($a, 1);

say $a[0];

It will segfault trying to print the populated struct with​:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7b463b0 in get_int () from /home/jonathan/.rakudobrew/moar-nom/install/lib/libmoar.so
Missing separate debuginfos, use​: dnf debuginfo-install glibc-2.21-13.fc22.x86_64
(gdb) bt full
#​0 0x00007ffff7b463b0 in get_int () from /home/jonathan/.rakudobrew/moar-nom/install/lib/libmoar.so
No symbol table info available.
#​1 0x00007ffff7b51f2b in get_attribute () from /home/jonathan/.rakudobrew/moar-nom/install/lib/libmoar.so
No symbol table info available.
#​2 0x00007ffff7af6c02 in MVM_interp_run () from /home/jonathan/.rakudobrew/moar-nom/install/lib/libmoar.so
No symbol table info available.
#​3 0x00007ffff7bae6e9 in MVM_vm_run_file () from /home/jonathan/.rakudobrew/moar-nom/install/lib/libmoar.so
No symbol table info available.
#​4 0x0000000000400fdf in main ()
No symbol table info available.

(The backtrace is basically the same in the "real" code.)

If the Perl code is altered so that it is passing an array of int64 instead then it gets the "right" response​:

use NativeCall;

sub Pm_Read(CArray[int64] $e, int32 $l) returns int32 is native('./test') { * }

my $a = CArray[int64].new;
$a[0] = 0;

Pm_Read($a, 1);

say $a[0];
say 16 + (8 +< 32); # the "right" answer

it would seem that the CStruct case is doing something like de-referencing the value.

This case doesn't appear to be tested for in the NC tests.

@p6rt
Copy link
Author

p6rt commented Mar 17, 2016

From @jonathanstowe

I've realised that this is because it is actually expecting

  Event **buffer

Rather than

  Event *buffer

Which is a flat array of structs rather than pointers to the structs.

So it's still a bug, it's just the bug is that it can only deal with arrays of pointers to structs and not the structs themselves.

In this particular case it can be worked round (as demonstrated,) however this would be a problem if the struct was larger than 64bits.

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

No branches or pull requests

1 participant