andrewchambers / janet-sh

Shorthand shell like functions for janet.
82 stars 6 forks source link

echo exit code(s) @[127] #20

Open jminh opened 1 year ago

jminh commented 1 year ago

Hi,

I met exit code 127 error while running below script. Do you know what could be the problem and how to fix it?

#!/usr/bin/env janet
(use sh)

($ echo "hello")
./hello.janet
error: command(s) (@[echo "hello"]) failed, exit code(s) @[127]
  in $* [/remote/vgsource10/jianmin/opt/janet/lib/janet/sh.janet] on line 255, column 5
  in _thunk [./hello.janet] (tailcall) on line 5, column 1

Regarding the env, it is a local installed janet and jpm and its setup is like

  git clone https://github.com/janet-lang/janet
  cd janet
  export PREFIX=$HOME/opt/janet
  make CC=/path/to/gcc/9.2.0

  make install
  make test
  make install-jpm-git

  export PATH=$HOME/opt/janet/bin:$PATH
  jpm install sh
ianthehenry commented 1 year ago

127 usually means command not found. Do you have the echo binary installed and available on your PATH? Like, do you have /bin/echo, and does your PATH contain /bin at the time that you invoke hello.janet?

There's a difference between running echo hi from an actual shell and running echo hi from janet-sh -- shells usually special-case echo as a shell-builtin, but janet-sh will try to execute the actual echo binary (since most things provided by shell built-ins have native Janet equivalents already).

andrewchambers commented 1 year ago

Perhaps there might be an easy way to improve the error message for this specific case, I can see how it would be confusing.

jminh commented 1 year ago

I'm using zsh and for echo I have

which echo
echo: shell built-in command

To simplify the situation, I try bash since I find it is a command as you can see below but the script still failed with 127 exit code.

$ bash
$ which echo
/usr/bin/echo

$ ./hello.janet
error: command(s) (@[echo "hello"]) failed, exit code(s) @[127]
  in $* [/remote/vgsource10/jianmin/opt/janet/lib/janet/sh.janet] on line 255, column 5
  in _thunk [./hello.janet] (tailcall) on line 5, column 1

Add /bin still see same error.

$ export PATH=/bin:$PATH
$ which echo
/bin/echo

$ ./hello.janet
error: command(s) (@[echo "hello"]) failed, exit code(s) @[127]
  in $* [/remote/vgsource10/jianmin/opt/janet/lib/janet/sh.janet] on line 255, column 5
  in _thunk [./hello.janet] (tailcall) on line 5, column 1

Do you have any idea? Do you think if there is any small simple code I can try?

jminh commented 1 year ago

Also here is the strace ouput.

$ strace -eprocess -ff -o x -s 80 ./hello.janet

$ cat x.35118
exit_group(127)                         = ?
+++ exited with 127 +++

$ cat x.35117
execve("./hello.janet", ["./hello.janet"], 0x7fffffffd3a0 /* 81 vars */) = 0
arch_prctl(ARCH_SET_FS, 0x7ffff7f9c740) = 0
execve("/home/ming/opt/janet/bin/janet", ["janet", "./hello.janet"], 0x7fffffffd3b8 /* 81 vars */) = 0
arch_prctl(ARCH_SET_FS, 0x7ffff7f9b100) = 0
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7ffff7f9b3d0) = 35118
wait4(35118, [{WIFEXITED(s) && WEXITSTATUS(s) == 127}], 0, NULL) = 35118
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=35118, si_uid=41058, si_status=127, si_utime=0, si_stime=0} ---
exit_group(1)                           = ?
+++ exited with 1 +++

I don't have any working run and thus I don't know what's the expected output. Hope this informatino can help here.

ianthehenry commented 1 year ago

I really don't know how to make sense of the strace output you posted. It never actually tries to exec echo, so it's not a PATH issue. The fork itself is failing? (I realize it's clone but on my system at least I still see the exec in the child process) I don't know how that would happen but it's weird enough that it makes me suspect a problem with your build of Janet. What operating system and architecture are you using? Can you try a pre-built Janet binary?

jminh commented 1 year ago

The fork itself is failing?

It looks fork is ok since we see two process (PID 35117, 35118).

I don't know how that would happen but it's weird enough that it makes me suspect a problem with your build of Janet.

For the local install, I did run "make test" and the result is fine as shown below.

make test                                                                                                                                                                        (master)
for f in test/suite*.janet; do ./build/janet "$f" || exit; done
Starting suite 0...
Finished suite 0 in 0.003 seconds - 190 of 190 tests passed.
Starting suite 1...
Finished suite 1 in 0.008 seconds - 154 of 154 tests passed.
Starting suite 2...
Finished suite 2 in 0.001 seconds - 136 of 136 tests passed.
Starting suite 3...
Finished suite 3 in 0.006 seconds - 187 of 187 tests passed.
Starting suite 4...
Finished suite 4 in 0.001 seconds - 26 of 26 tests passed.
Starting suite 5...
Finished suite 5 in 0.001 seconds - 46 of 46 tests passed.
Starting suite 6...
Finished suite 6 in 0.002 seconds - 104 of 104 tests passed.
Starting suite 7...
Finished suite 7 in 0.026 seconds - 213 of 213 tests passed.
Starting suite 8...
Finished suite 8 in 0.005 seconds - 130 of 130 tests passed.
Starting suite 9...
Finished suite 9 in 0.265 seconds - 492 of 492 tests passed.
Starting suite 10...
Finished suite 10 in 0.007 seconds - 93 of 93 tests passed.
Starting suite 11...
Finished suite 11 in 0.037 seconds - 23 of 23 tests passed.
Starting suite 12...
Finished suite 12 in 0.000 seconds - 12 of 12 tests passed.
Starting suite 13...
Finished suite 13 in 0.000 seconds - 5 of 5 tests passed.
Starting suite 14...
Finished suite 14 in 0.000 seconds - 4 of 4 tests passed.
Starting suite 15...
Finished suite 15 in 0.000 seconds - 6 of 6 tests passed.
for f in examples/*.janet; do ./build/janet -k "$f"; done

What operating system and architecture are you using? Can you try a pre-built Janet binary?

It is CentOS7 and it cannot run prebuild binary due to GLIBC issue.

lsb_release -a
LSB Version:    :core-4.1-amd64:core-4.1-ia32:core-4.1-noarch:cxx-4.1-amd64:cxx-4.1-ia32:cxx-4.1-noarch:desktop-4.1-amd64:desktop-4.1-ia32:desktop-4.1-noarch:languages-4.1-amd64:languages-4.1-noarch:printing-4.1-amd64:printing-4.1-noarch
Distributor ID: CentOS
Description:    CentOS Linux release 7.3.1611 (Core)
Release:        7.3.1611
Codename:       Core

janet-v1.27.0-linux-x64.tar.gz

./bin/janet
./bin/janet: /lib64/libm.so.6: version `GLIBC_2.35' not found (required by ./bin/janet)
./bin/janet: /lib64/libm.so.6: version `GLIBC_2.23' not found (required by ./bin/janet)
./bin/janet: /lib64/libm.so.6: version `GLIBC_2.29' not found (required by ./bin/janet)
./bin/janet: /lib64/libc.so.6: version `GLIBC_2.33' not found (required by ./bin/janet)
./bin/janet: /lib64/libc.so.6: version `GLIBC_2.34' not found (required by ./bin/janet)
jminh commented 1 year ago

Do you have any idea to proceed?

I think if I have debug builds, gdb "catch fork, catch exec" may help to locate the problem. But I'm not sure how to build a debug janet and debug janet-sh.

For janet, it seems there is no instruction for debug build. Only from "make help", I see there is a debug target and here is output.

make debug

gcc -DJANET_BOOTSTRAP -DJANET_BUILD="\"440af9f\"" -O0 -g -std=c99 -Wall -Wextra -Isrc/include -Isrc/conf -fvisibility=hidden -fPIC -o build/boot/system_test.boot.o -c src/boot/system_test.c
gcc -DJANET_BOOTSTRAP -DJANET_BUILD="\"440af9f\"" -O0 -g -std=c99 -Wall -Wextra -Isrc/include -Isrc/conf -fvisibility=hidden -fPIC -o build/boot/table_test.boot.o -c src/boot/table_test.c
gcc -DJANET_BOOTSTRAP -DJANET_BUILD="\"440af9f\"" -O0 -g -std=c99 -Wall -Wextra -Isrc/include -Isrc/conf -fvisibility=hidden -fPIC -o build/janet_boot build/core/abstract.boot.o build/core/array.boot.o build/core/asm.boot.o build/core/buffer.boot.o build/core/bytecode.boot.o build/core/capi.boot.o build/core/cfuns.boot.o build/core/compile.boot.o build/core/corelib.boot.o build/core/debug.boot.o build/core/emit.boot.o build/core/ev.boot.o build/core/ffi.boot.o build/core/fiber.boot.o build/core/gc.boot.o build/core/inttypes.boot.o build/core/io.boot.o build/core/marsh.boot.o build/core/math.boot.o build/core/net.boot.o build/core/os.boot.o build/core/parse.boot.o build/core/peg.boot.o build/core/pp.boot.o build/core/regalloc.boot.o build/core/run.boot.o build/core/specials.boot.o build/core/state.boot.o build/core/string.boot.o build/core/strtod.boot.o build/core/struct.boot.o build/core/symcache.boot.o build/core/table.boot.o build/core/tuple.boot.o build/core/util.boot.o build/core/value.boot.o build/core/vector.boot.o build/core/vm.boot.o build/core/wrap.boot.o build/boot/array_test.boot.o build/boot/boot.boot.o build/boot/buffer_test.boot.o build/boot/number_test.boot.o build/boot/system_test.boot.o build/boot/table_test.boot.o -lm -lpthread -lrt -ldl
build/janet_boot . JANET_PATH '/home/ming/opt/janet/lib/janet' > build/c/janet.c
cksum build/c/janet.c
2269891870 2730222 build/c/janet.c
gcc -O2 -std=c99 -Wall -Wextra -Isrc/include -Isrc/conf -fvisibility=hidden -fPIC -c build/c/janet.c -o build/janet.o
cp src/mainclient/shell.c build/c/shell.c
gcc -O2 -std=c99 -Wall -Wextra -Isrc/include -Isrc/conf -fvisibility=hidden -fPIC -c build/c/shell.c -o build/shell.o
gcc -rdynamic -O2 -std=c99 -Wall -Wextra -Isrc/include -Isrc/conf -fvisibility=hidden -fPIC -o build/janet build/janet.o build/shell.o -lm -lpthread -lrt -ldl
gdb ./build/janet
Reading symbols from ./build/janet...
(No debugging symbols found in ./build/janet)
(gdb)

But there is no debug symbol since there is no "-g" in "-o build/janet". I don't know if this is expectd or a bug.

For janet-sh, I found jpm has a "--build-type=debug" option and I give it a try but it failed to run.

jpm install --verbose --build-type=debug sh
git -c init.defaultBranch=master -C /home/ming/opt/janet/lib/janet/.cache/git__https___github.com_janet-lang_pkgs.git init
Initialized empty Git repository in /home/ming/opt/janet/lib/janet/.cache/git__https___github.com_janet-lang_pkgs.git/.git/
git -C /home/ming/opt/janet/lib/janet/.cache/git__https___github.com_janet-lang_pkgs.git remote add origin https://github.com/janet-lang/pkgs.git
git -C /home/ming/opt/janet/lib/janet/.cache/git__https___github.com_janet-lang_pkgs.git fetch --tags origin
remote: Enumerating objects: 301, done.
remote: Counting objects: 100% (95/95), done.
remote: Compressing objects: 100% (56/56), done.
remote: Total 301 (delta 49), reused 68 (delta 39), pack-reused 206
Receiving objects: 100% (301/301), 67.99 KiB | 0 bytes/s, done.
Resolving deltas: 100% (165/165), done.
From https://github.com/janet-lang/pkgs
 * [new branch]      add-shawn  -> origin/add-shawn
 * [new branch]      contrib-rules -> origin/contrib-rules
 * [new branch]      master     -> origin/master
git -C /home/ming/opt/janet/lib/janet/.cache/git__https___github.com_janet-lang_pkgs.git fetch origin HEAD
From https://github.com/janet-lang/pkgs
 * branch            HEAD       -> FETCH_HEAD
git -C /home/ming/opt/janet/lib/janet/.cache/git__https___github.com_janet-lang_pkgs.git reset --hard FETCH_HEAD
HEAD is now at 6b309a7 Merge pull request #57 from CosmicToast/patch-1
git -C /home/ming/opt/janet/lib/janet/.cache/git__https___github.com_janet-lang_pkgs.git submodule update --init --recursive
The install target is only enabled for release builds.
sogaiu commented 1 year ago

For janet, I use the following:

$ git diff
diff --git a/Makefile b/Makefile
index 6aa76508..9aba09fd 100644
--- a/Makefile
+++ b/Makefile
@@ -45,10 +45,12 @@ SONAME_SETTER=-Wl,-soname,
 # For cross compilation
 HOSTCC?=$(CC)
 HOSTAR?=$(AR)
-CFLAGS?=-O2
+#CFLAGS?=-O2
+CFLAGS?=-O0
 LDFLAGS?=-rdynamic

-COMMON_CFLAGS:=-std=c99 -Wall -Wextra -Isrc/include -Isrc/conf -fvisibility=hidden -fPIC
+#COMMON_CFLAGS:=-std=c99 -Wall -Wextra -Isrc/include -Isrc/conf -fvisibility=hidden -fPIC
+COMMON_CFLAGS:=-g3 -std=c99 -Wall -Wextra -Isrc/include -Isrc/conf -fvisibility=hidden -fPIC
 BOOT_CFLAGS:=-DJANET_BOOTSTRAP -DJANET_BUILD=$(JANET_BUILD) -O0 -g $(COMMON_CFLAGS)
 BUILD_CFLAGS:=$(CFLAGS) $(COMMON_CFLAGS)

I've had success with various flags [1] but the above is what I settled on.


[1] The link is meant to get one to the "Scratch" section of that page, but it isn't working for me. Please search for "Scratch" on the pointed at page.

sogaiu commented 1 year ago

In a janet project that I have a native part in, I've done the following sort of thing:

(declare-native
  :name "_tree-sitter"
  :cflags   [;default-cflags
             "-Itree-sitter/lib/include"
             "-Itree-sitter/lib/src"
             # XXX: for debugging with gdb
             "-O0" "-g3"
            ]
  :source ["janet-tree-sitter/tree_sitter.c"
           "tree-sitter/lib/src/lib.c"
           # XXX
           "tree-sitter-clojure/src/parser.c"])

Just the bit about "for debugging with gdb".

dbohdan commented 1 year ago

I have encountered the same problem, but only on OpenBSD, not the other two platforms I have tried janet-sh on, Ubuntu and NetBSD. I used Janet 1.27.0-440af9fd and janet-sh 221bcc86.

Ubuntu 22.04

> janet
Janet 1.27.0-440af9fd linux/x64/gcc - '(doc)' for help
repl:1:> (import sh)
@{_ @{:value <cycle 0>} sh/$ @{:private true} sh/$* @{:private true} sh/$< @{:private true} sh/$<* @{:private true} sh/$<_ @{:private true} sh/$<_* @{:private true} sh/$? @{:private true} sh/$?* @{:private true} sh/glob @{:private true} sh/run @{:private true} sh/run* @{:private true} :macro-lints @[]}
repl:2:> (sh/$ ls)
bootstrap.janet
CHANGELOG.md
configs
content
jpm
jpm.1
LICENSE
project.janet
README.md
test
testinstall
nil
repl:3:>

NetBSD 9.3

> janet
Janet 1.27.0-440af9fd netbsd/x64/gcc - '(doc)' for help
repl:1:> (import sh)
@{_ @{:value <cycle 0>} sh/$ @{:private true} sh/$* @{:private true} sh/$< @{:private true} sh/$<* @{:private true} sh/$<_ @{:private true} sh/$<_* @{:private true} sh/$? @{:private true} sh/$?* @{:private true} sh/glob @{:private true} sh/run @{:private true} sh/run* @{:private true} :macro-lints @[]}
repl:2:> (sh/$ ls)
CHANGELOG.md
LICENSE
README.md
bootstrap.janet
configs
content
jpm
jpm.1
project.janet
test
testinstall
nil
repl:3:>

OpenBSD 7.3

> janet
Janet 1.27.0-20230324 openbsd/x64/clang - '(doc)' for help
repl:1:> (import sh)
@{_ @{:value <cycle 0>} sh/$ @{:private true} sh/$* @{:private true} sh/$< @{:private true} sh/$<* @{:private true} sh/$<_ @{:private true} sh/$<_* @{:private true} sh/$? @{:private true} sh/$?* @{:private true} sh/glob @{:private true} sh/run @{:private true} sh/run* @{:private true} :macro-lints @[]}
repl:2:> (sh/$ ls)
error: command(s) (@[ls]) failed, exit code(s) @[127]
  in $* [/usr/local/lib/janet/sh.janet] on line 255, column 5
  in _thunk [repl] (tailcall) on line 2, column 1
repl:3:>
repl:9:> (os/getenv "PATH")
"/home/dbohdan/.local/bin:/home/dbohdan/bin:/home/dbohdan/.cargo/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin:/usr/local/bin:/usr/local/sbin"

Installing with --cc=gcc does not make a difference.

jminh commented 9 months ago

The cause of this issue is the underlying library janet-posix-spawn does not work. The detail is described in https://github.com/andrewchambers/janet-posix-spawn/issues/4 and a solution is also propsoed in that issue.