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

[OpenBSD] Cannot run much of anything without MVM_JIT_DISABLE #2824

Closed
Kaiepi opened this issue Apr 7, 2019 · 15 comments
Closed

[OpenBSD] Cannot run much of anything without MVM_JIT_DISABLE #2824

Kaiepi opened this issue Apr 7, 2019 · 15 comments
Labels

Comments

@Kaiepi
Copy link
Contributor

Kaiepi commented Apr 7, 2019

The Problem

This is really two separate issues, but I didn't want to be too spammy with them. See title.

Everything worked fine in 2019.03.

Expected Behavior

zef should be possible to install and it should be possible to run scripts without MVM_JIT_DISABLE=1 in the env.

Actual Behavior

See "Steps to Reproduce" since I don't want to repeat myself.

Steps to Reproduce

Let's try installing zef normally:

bastille% perl6 -Ilib bin/zef install .
zsh: trace trap (core dumped)  perl6 -Ilib bin/zef install .

Oops. This also happens when trying to install nqp and Rakudo, for the record. The backtrace from the core dump doesn't give much info:

(gdb) bt
#0  0x0000009fc176ecb0 in MVM_exception_throwpayload (tc=0x0, mode=0 '\0', cat=301, payload=0x9fdb268fad, 
    resume_result=0x7f7ffffc4160) at src/core/exceptions.c:785
#1  0x000000a094a2cc16 in ?? ()
#2  0x0000000000000004 in ?? ()
#3  0x0000000000000000 in ?? ()

When I had moar compiled without --optimize=0 --debug=3, one of the JIT ops popped up in the backtrace, so the JIT appears to be to blame. The output of MVM_SPESH_LOG shows that it can't find the templates for getattr_o and sp_fastbox_i_ic in particular, with these also failing, but for different reasons (such as being legojit and thus having no expr template, for instance):

  • bindlex
  • coerce_in
  • coerce_ni
  • eq_n
  • gt_n
  • lt_n
  • prepargs
  • sp_bind_s_nowb
  • sp_getlex_ins
  • sp_getlex_o
  • sp_guardsf
  • throwpayloadlex

Anyway, let's try again with MVM_JIT_DISABLE=1:

bastille% MVM_JIT_DISABLE=1 perl6 -Ilib bin/zef install .
===SORRY!===
illegal operation on a directory
bastille% MVM_JIT_DISABLE=1 perl6 --ll-exception -Ilib bin/zef install . 
no such file or directory
   at SETTING::src/core/Exception.pm6:71  (/home/morfent/.perl6/share/perl6/runtime/CORE.setting.moarvm:rethrow)
 from SETTING::src/core/Awaiter.pm6:24  (/home/morfent/.perl6/share/perl6/runtime/CORE.setting.moarvm:)
 from SETTING::src/core/Awaiter.pm6:10  (/home/morfent/.perl6/share/perl6/runtime/CORE.setting.moarvm:await)
 from SETTING::src/core/asyncops.pm6:33  (/home/morfent/.perl6/share/perl6/runtime/CORE.setting.moarvm:await)
 from SETTING::src/core/asyncops.pm6:16  (/home/morfent/.perl6/share/perl6/runtime/CORE.setting.moarvm:await)
 from SETTING::src/core/Supply.pm6:2289  (/home/morfent/.perl6/share/perl6/runtime/CORE.setting.moarvm:REACT)
 from SETTING::src/core/CompUnit/PrecompilationRepository.pm6:263  (/home/morfent/.perl6/share/perl6/runtime/CORE.setting.moarvm:precompile)
 from SETTING::src/core/CompUnit/PrecompilationRepository.pm6:210  (/home/morfent/.perl6/share/perl6/runtime/CORE.setting.moarvm:precompile)
 from SETTING::src/core/CompUnit/PrecompilationRepository.pm6:46  (/home/morfent/.perl6/share/perl6/runtime/CORE.setting.moarvm:try-load)
 from SETTING::src/core/CompUnit/Repository/FileSystem.pm6:79  (/home/morfent/.perl6/share/perl6/runtime/CORE.setting.moarvm:)
 from SETTING::src/core/CompUnit/Repository/FileSystem.pm6:73  (/home/morfent/.perl6/share/perl6/runtime/CORE.setting.moarvm:need)
 from src/Perl6/World.nqp:1385  (/home/morfent/.perl6/share/nqp/lib/Perl6/World.moarvm:load_module)
 from src/Perl6/World.nqp:1323  (/home/morfent/.perl6/share/nqp/lib/Perl6/World.moarvm:do_pragma_or_load_module)
 from gen/moar/Perl6-Grammar.nqp:1291  (/home/morfent/.perl6/share/nqp/lib/Perl6/Grammar.moarvm:statement_control:sym<use>)
 from gen/moar/stage2/QRegex.nqp:1695  (/home/morfent/.perl6/share/nqp/lib/QRegex.moarvm:!protoregex)
 from <unknown>:1  (/home/morfent/.perl6/share/nqp/lib/Perl6/Grammar.moarvm:statement_control)
 from gen/moar/Perl6-Grammar.nqp:955  (/home/morfent/.perl6/share/nqp/lib/Perl6/Grammar.moarvm:statement)
 from gen/moar/Perl6-Grammar.nqp:883  (/home/morfent/.perl6/share/nqp/lib/Perl6/Grammar.moarvm:statementlist)
 from gen/moar/stage2/NQPHLL.nqp:1215  (/home/morfent/.perl6/share/nqp/lib/NQPHLL.moarvm:LANG)
 from gen/moar/Perl6-Grammar.nqp:1319  (/home/morfent/.perl6/share/nqp/lib/Perl6/Grammar.moarvm:FOREIGN_LANG)
 from gen/moar/Perl6-Grammar.nqp:825  (/home/morfent/.perl6/share/nqp/lib/Perl6/Grammar.moarvm:comp_unit)
 from gen/moar/Perl6-Grammar.nqp:555  (/home/morfent/.perl6/share/nqp/lib/Perl6/Grammar.moarvm:TOP)
 from gen/moar/stage2/QRegex.nqp:2300  (/home/morfent/.perl6/share/nqp/lib/QRegex.moarvm:parse)
 from gen/moar/stage2/NQPHLL.nqp:2030  (/home/morfent/.perl6/share/nqp/lib/NQPHLL.moarvm:parse)
 from gen/moar/stage2/NQPHLL.nqp:1950  (/home/morfent/.perl6/share/nqp/lib/NQPHLL.moarvm:execute_stage)
 from gen/moar/stage2/NQPHLL.nqp:1983  (/home/morfent/.perl6/share/nqp/lib/NQPHLL.moarvm:run)
 from gen/moar/stage2/NQPHLL.nqp:1975  (/home/morfent/.perl6/share/nqp/lib/NQPHLL.moarvm:)
 from gen/moar/stage2/NQPHLL.nqp:1970  (/home/morfent/.perl6/share/nqp/lib/NQPHLL.moarvm:compile)
 from gen/moar/stage2/NQPHLL.nqp:1666  (/home/morfent/.perl6/share/nqp/lib/NQPHLL.moarvm:eval)
 from gen/moar/stage2/NQPHLL.nqp:1888  (/home/morfent/.perl6/share/nqp/lib/NQPHLL.moarvm:evalfiles)
 from gen/moar/stage2/NQPHLL.nqp:1848  (/home/morfent/.perl6/share/nqp/lib/NQPHLL.moarvm:command_eval)
 from src/Perl6/Compiler.nqp:38  (/home/morfent/.perl6/share/nqp/lib/Perl6/Compiler.moarvm:command_eval)
 from gen/moar/stage2/NQPHLL.nqp:1773  (/home/morfent/.perl6/share/nqp/lib/NQPHLL.moarvm:command_line)
 from gen/moar/main.nqp:77  (/home/morfent/.perl6/share/perl6/runtime/perl6.moarvm:MAIN)
 from gen/moar/main.nqp:35  (/home/morfent/.perl6/share/perl6/runtime/perl6.moarvm:<mainline>)
 from <unknown>:1  (/home/morfent/.perl6/share/perl6/runtime/perl6.moarvm:<main>)
 from <unknown>:1  (/home/morfent/.perl6/share/perl6/runtime/perl6.moarvm:<entry>)

And again, as root:

bastille% MVM_JIT_DISABLE=1 doas perl6 -Ilib bin/zef install . 
doas (morfent@bastille.kennel.qt) password: 
===> CompUnit::Repository install target is not writeable/installable: /home/morfent/Documents/zef/auto
Need a valid installation target to continue
bastille% MVM_JIT_DISABLE=1 doas perl6 --ll-exception -Ilib bin/zef install .  
doas (morfent@bastille.kennel.qt) password: 
===> CompUnit::Repository install target is not writeable/installable: /home/morfent/Documents/zef/auto
Need a valid installation target to continue
   at SETTING::src/core/Exception.pm6:62  (/home/morfent/.perl6/share/perl6/runtime/CORE.setting.moarvm:throw)
 from SETTING::src/core/control.pm6:178  (/home/morfent/.perl6/share/perl6/runtime/CORE.setting.moarvm:die)
 from bin/zef:474  (<ephemeral file>:make-install)
 from bin/zef:183  (<ephemeral file>:MAIN)
 from bin/zef:25  (<ephemeral file>:MAIN)
 from SETTING::src/core/Main.pm6:316  (/home/morfent/.perl6/share/perl6/runtime/CORE.setting.moarvm:)
 from SETTING::src/core/Main.pm6:312  (/home/morfent/.perl6/share/perl6/runtime/CORE.setting.moarvm:)
 from SETTING::src/core/Main.pm6:311  (/home/morfent/.perl6/share/perl6/runtime/CORE.setting.moarvm:RUN-MAIN)
 from bin/zef:3  (<ephemeral file>:<unit>)
 from bin/zef:1  (<ephemeral file>:<unit-outer>)
 from gen/moar/stage2/NQPHLL.nqp:1684  (/home/morfent/.perl6/share/nqp/lib/NQPHLL.moarvm:eval)
 from gen/moar/stage2/NQPHLL.nqp:1888  (/home/morfent/.perl6/share/nqp/lib/NQPHLL.moarvm:evalfiles)
 from gen/moar/stage2/NQPHLL.nqp:1848  (/home/morfent/.perl6/share/nqp/lib/NQPHLL.moarvm:command_eval)
 from src/Perl6/Compiler.nqp:38  (/home/morfent/.perl6/share/nqp/lib/Perl6/Compiler.moarvm:command_eval)
 from gen/moar/stage2/NQPHLL.nqp:1773  (/home/morfent/.perl6/share/nqp/lib/NQPHLL.moarvm:command_line)
 from gen/moar/main.nqp:77  (/home/morfent/.perl6/share/perl6/runtime/perl6.moarvm:MAIN)
 from gen/moar/main.nqp:35  (/home/morfent/.perl6/share/perl6/runtime/perl6.moarvm:<mainline>)
 from <unknown>:1  (/home/morfent/.perl6/share/perl6/runtime/perl6.moarvm:<main>)
 from <unknown>:1  (/home/morfent/.perl6/share/perl6/runtime/perl6.moarvm:<entry>)

These errors could possibly be OS-dependent since I just upgraded to OpenBSD 6.5. Someone else should test this to see if it works on other OSes.

Environment

  • Operating system:
    OpenBSD bastille.kennel.qt 6.5 GENERIC.MP#839 amd64
  • Compiler version (perl6 -v):
    This is Rakudo version 2019.03.1-167-gcd52d404b built on MoarVM version 2019.03-68-g25b486dee
    implementing Perl 6.d.
@Kaiepi
Copy link
Contributor Author

Kaiepi commented Apr 7, 2019

Whatever's responsible for the trace trap is legojit related since it still happens with MVM_JIT_EXPR_DISABLE=1. Reverting the MoarVM commit that adds templates for fileno_fh doesn't fix the file errors or the trace trap

@Kaiepi
Copy link
Contributor Author

Kaiepi commented Apr 7, 2019

I'll bisect the two bugs myself later. I'm writing a script that'll bisect them for me since I really don't want to bisect code that spans across three repos manually (which I'll distribute after this), so it may take a little while.

@AlexDaniel AlexDaniel added the BLOCKER Preventing the next release of rakudo, or just needing attention before the release label Apr 7, 2019
@ugexe
Copy link
Member

ugexe commented Apr 7, 2019

The error is telling me that the default site and home repos are not writable.

@Kaiepi
Copy link
Contributor Author

Kaiepi commented Apr 7, 2019

Where are those repos?

@ugexe
Copy link
Member

ugexe commented Apr 7, 2019

This will show you where a named repo is for a given perl6:

$ perl6 -e 'say CompUnit::RepositoryRegistry.repository-for-name("site")'
inst#/Users/ugexe/.rakudobrew/moar-blead-master/install/bin/../share/perl6/site

@Kaiepi
Copy link
Contributor Author

Kaiepi commented Apr 8, 2019

They should be writable, but aren't by perl6 for some reason:

bastille% MVM_JIT_DISABLE=1 perl6 -e 'say CompUnit::RepositoryRegistry.repository-for-name("site")'
inst#/home/morfent/.perl6/share/perl6/site
bastille% MVM_JIT_DISABLE=1 perl6 -e 'say CompUnit::RepositoryRegistry.repository-for-name("home")'
inst#/home/morfent/.perl6
bastille% stat ~/.perl6
1034 17233920 drwxr-xr-x 8 morfent morfent 68805339 512 "Apr  7 18:25:32 2019" "Apr  6 15:42:47 2019" "Apr  6 15:42:47 2019" 32768 8 0 /home/morfent/.perl6
bastille% stat ~/.perl6/share/perl6/site
1034 16661573 drwxr-xr-x 9 morfent morfent 66537963 512 "Apr  7 18:24:52 2019" "Apr  6 20:18:48 2019" "Apr  6 20:18:48 2019" 32768 8 0 /home/morfent/.perl6/share/perl6/site

Running chmod -R 0777 ~/.perl6 doesn't solve the error.

@Kaiepi
Copy link
Contributor Author

Kaiepi commented Apr 11, 2019

The trace traps can be fixed by passing --fno-ret-protector to ld.so in MoarVM and Rakudo for OpenBSD, but the problem with that is that disables a security feature that helps prevent ROP vulnerabilities.

perl6 is failing to find any modules because it's getting its own executable name wrong:

bastille% perl6 -e 'say $*EXECUTABLE'
"-e".IO

@lizmat
Copy link
Contributor

lizmat commented Apr 15, 2019

Cannot reproduce this:

$ 6 'say $*EXECUTABLE'
"/Users/liz/Github/rakudo.moar/install/bin/perl6".IO

@Kaiepi
Copy link
Contributor Author

Kaiepi commented Apr 16, 2019

I'm pretty sure this is a bug in libuv specific to OpenBSD. I wasted a good chunk of the day trying to get nqp::execname to output something useful, but the best i could do was just perl6. No path, just perl6.

I looked through libuv's code and what they do to get the path to the executable is to make a sysctl call to get information about the process' argv. That's fine in most cases, but what if the process is in $PATH and called using only its name, not its path? That may explain why I could only get perl6 and not the full path to it. There's a better API they could be using for this so I'll test it out and see if I can fix this.

Both of these bugs are OpenBSD specific, so someone should slap the BSD tag on this.

Edit: I've patched these bugs myself to get Perl 6 running on my machine, so this isn't highly urgent to fix

@lizmat lizmat added the BSD label Apr 16, 2019
@patrickbkr
Copy link
Contributor

@Kaiepi I also looked at the exec path thing on OpendBSD. (I didn't realize you were looking at this as well).
As far as I know there is no API on OpenBSD that can be used to retrieve the exec path. (see here)
I'd be interested in what you came up with.

@Kaiepi
Copy link
Contributor Author

Kaiepi commented Apr 16, 2019

I'm fairly sure it's possible to do with sysctl(2), but I need to learn its API and do more testing before I can say for sure whether or not it is

@patrickbkr
Copy link
Contributor

Also see (whereami is a minimal C library to return the current executable path):
gpakosz/whereami#13
gpakosz/whereami#7 (comment)

@Kaiepi
Copy link
Contributor Author

Kaiepi commented Apr 16, 2019

You're right, OpenBSD's kern.allowkmem would allow you to use sysctl or KVM to get the current path, but that's disabled by default and I don't think we should force users to enable it to use Perl 6, especially since it needs to be enabled in a different way from other sysctl settings.

We can't use sysctl to get the process' argv like libuv does either because surprise! There seems to be a bug in OpenBSD as well. I wrote a short program that just outputs the argv:

#include <sys/types.h>
#include <sys/mount.h>
#include <sys/param.h>
#include <sys/sysctl.h>
#include <errno.h>
#include <fcntl.h>
#include <kvm.h>
#include <limits.h>
#include <paths.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

char **
get_argv(int pid)
{
    int mib[4];
    size_t len;
    char **argv;
    char **p;

    mib[0] = CTL_KERN;
    mib[1] = KERN_PROC_ARGS;
    mib[2] = pid;
    mib[3] = KERN_PROC_ARGV;

    sysctl(mib, 4, &argv, &len, NULL, 0);

    return argv;
}


int
main(int argc, char **argv)
{
    int pid, fd, e;
    char **args, **p;

    if (argc != 2) {
        fprintf(stderr, "Usage: ./test <pid>\n");
        return 1;
    }

    pid = atoi(argv[1]);
    p = args = get_argv(pid);

    do {
        printf("%s\n", *p);
    } while (++p != NULL);

    free(args);

    return 0;
}

This is its output:

bastille% ./test 81968
1ýÿ��
test
zsh: segmentation fault (core dumped)  ./test 81968

So I think it'd be best just not to use nqp::execname to get $*EXECUTABLE and $*EXECUTABLE-NAME on OpenBSD and use the paths in config instead.

Kaiepi added a commit to Kaiepi/rakudo that referenced this issue Apr 16, 2019
@Kaiepi
Copy link
Contributor Author

Kaiepi commented Apr 16, 2019

I forgot to link it here, but I made a separate issue for the JIT problems on OpenBSD on MoarVM's repo because the cause of them is highly technical and only deals with a very specific part of MoarVM's JIT compiler MoarVM/MoarVM#1091

@lizmat lizmat changed the title Cannot install zef (or run much of anything without MVM_JIT_DISABLE) [OpenBSD] Cannot run much of anything without MVM_JIT_DISABLE Apr 23, 2019
@lizmat lizmat removed the BLOCKER Preventing the next release of rakudo, or just needing attention before the release label Apr 23, 2019
@lizmat
Copy link
Contributor

lizmat commented Apr 23, 2019

Closing this issue since the JIT issue is now handled with MoarVM/MoarVM#1091, and the execname issue has been fixed.

@lizmat lizmat closed this as completed Apr 23, 2019
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

5 participants