Closed kraptor closed 3 years ago
Maybe I'm doing something wrong :(
As a reference, I compiled with:
-d:debug --debugger:native --debuginfo --linedir:on
Current Nim version:
Nim Compiler Version 1.2.6 [Windows: amd64]
Compiled at 2020-07-29
Copyright (c) 2006-2020 by Andreas Rumpf
git hash: bf320ed172f74f60fd274338e82bdc9ce3520dd9
active boot switches: -d:release
Well, you neglected to copy your VERSION_META variable. So, I cannot compile it :-) Adding some dummy value for that I get similar results where no-arg invocation does not dump the help summary but tries to run start
. Looking into it more..
Oh, wait. Duh. You are doing that directly with your check of len
.
So, this relates to your other issue. https://github.com/c-blake/cligen/issues/135 where you want default activity with no subcommand. Your len == 0
check solution is an ok workaround for that (though it means CLusers will never see the brief summary table. Eh. Different priorities.).
I guess when I said "similar results" I should have been clear, "similar results to what you expected", not what you got. Sorry. I literally had just woken up. I am on Linux with Nim 1.3.5 githash 8c82144ba507244084836b38689e4925de982626 and cannot reproduce the failure.
Specifically, when run just as app with no params I see:
app.nim(13) app
app.nim(6) cmd_start
Error: unhandled exception: Error! [Exception]
(There's a 2-line shift in line numbers from me adding a const VERSION_META = "foo"
.)
So, maybe this has to do with a setting in your nim.cfg
/config.nims
? Or otherwise your build environment or specific nim version. It's really hard for me to help with a problem like this without being able to reproduce...I haven't seen it come up before.
I can also say that I tested on nim-1.2.0 and nim-0.20.2 on Linux getting the same, expected behavior, but I doubt that's very helpful. I don't have a 1.2.6 built/around or any Windows env.
It would be worthwhile to try some newer version of Nim..or possibly try a different computer that may have different configuration..Maybe it will work there and you can 'diff' the two configs. It may be some interaction between Nim and your backend compiler, too...Anyway, I'm just guessing blindly. Sorry. Sounds like a thorny problem, but very likely not cligen-specific. :(
I guess it may be theoretically possible that how you establish VERSION_META could play a role, though I kind of doubt it. So, if you want to be more specific about that then I may be able to help, but otherwise I cannot any more than I have. Given the essentially total lack of cligen
involvement up to that point in your code (just the import, really), you may be able to just remove all the cligen
stuff, reproduce, and submit a bug report to Nim core who is also more familiar with Windows build issues.
BTW, I see you edited in the VERSION_META and as I expected that makes no difference to my output which is what you expected but are not getting. If you change the import to just import os
and comment out the else: dispatchMulti
I suspect you would get the same misbehavior { EDIT: on your system :-) }.
Wop, too much information, let me process it... I'll answer asap.
Ouch... seems this is worst than I thought... Look:
Source:
import cligen
proc cmd_test =
raise newException(Exception, "Error!")
when isMainModule:
dispatchMulti(
[
"multi",
doc = "Test program"
],
[
cmd_test,
cmd_name = "start",
doc = "run the app",
]
)
nim c -d:debug --debugger:native --debuginfo --linedir:on main2.nim && main2 start
Results:
C:\Users\kraptor\.nimble\pkgs\cligen-1.2.0\cligen.nim(1007) main2 C:\Users\kraptor\.nimble\pkgs\cligen-1.2.0\cligen.nim(659) multiSubs C:\Users\kraptor\.nimble\pkgs\cligen-1.2.0\cligen.nim(741) multi C:\Users\kraptor\.nimble\pkgs\cligen-1.2.0\cligen.nim(659) dispatchstart D:\Projects\nim_tests\main2.nim(4) cmd_test Error: unhandled exception: Error! [Exception]
But when compiled with the CPP backend:
nim cpp -d:debug --debugger:native --debuginfo --linedir:on main2.nim && main2 start
Results:
Traceback (most recent call last) C:\Users\kraptor\.nimble\pkgs\cligen-1.2.0\cligen.nim(1007) main2 SIGABRT: Abnormal termination.
May this be a codegen issue on Nim's side????
EDIT: escaped paths properly.
I agree it looks like some kind of Nim codegen issue (or interaction of generated code with the backend compiler). As mentioned, I expect you can get the same misbehavior with a simpler program:
proc cmd_test =
raise newException(Exception, "Error!")
cmd_test()
or maybe you also have to import os
and check cmdLineParams().len
like before, but I don't think this is cligen-related.
Now, it may have been fixed in Nim since your version. So, before filing a bug over at Nim core, you should try it against the latest devel. I now the cpp backend and c backends often have different exception handling generation. So, that also tracks.
Uhmmm... compiling your simple test seems ok:
proc cmd_test =
raise newException(Exception, "Error!")
cmd_test()
Results with CPP:
D:\Projects\nim_tests>nim cpp -d:debug --debugger:native --debuginfo --linedir:on main.nim && main
Hint: used config file 'C:\Users\kraptor\scoop\apps\nim\current\config\nim.cfg' [Conf]
Hint: system [Processing]
Hint: widestrs [Processing]
Hint: io [Processing]
Hint: main [Processing]
CC: stdlib_io.nim
CC: stdlib_system.nim
CC: main.nim
Hint: [Link]
Hint: 14188 LOC; 3.319 sec; 16.125MiB peakmem; Debug build; proj: D:\Projects\nim_tests\main.nim; out: D:\Projects\nim_tests\main.exe [SuccessX]
D:\Projects\nim_tests\main.nim(3) main
D:\Projects\nim_tests\main.nim(2) cmd_test
Error: unhandled exception: Error! [Exception]
Same with C:
D:\Projects\nim_tests>nim c -d:debug --debugger:native --debuginfo --linedir:on main.nim && main
Hint: used config file 'C:\Users\kraptor\scoop\apps\nim\current\config\nim.cfg' [Conf]
Hint: system [Processing]
Hint: widestrs [Processing]
Hint: io [Processing]
Hint: main [Processing]
CC: stdlib_io.nim
CC: stdlib_system.nim
CC: main.nim
Hint: [Link]
Hint: 14188 LOC; 2.882 sec; 16.117MiB peakmem; Debug build; proj: D:\Projects\nim_tests\main.nim; out: D:\Projects\nim_tests\main.exe [SuccessX]
D:\Projects\nim_tests\main.nim(3) main
D:\Projects\nim_tests\main.nim(2) cmd_test
Error: unhandled exception: Error! [Exception]
Not sure I can use latest version of Nim right now to check, as I don't know how to do that (installed using scoop.sh and using always stable versions)
Note I'm using GCC on windows...
Well, they all seem ok in my build environments and I tried 3 versions of Nim. :) Just an import cligen
(with no macro call) may be another way to simplify the problem.
It was initially failing for you not via dispatchMulti
, but just an if
. So, it's really not about anything other than importing cligen
(possibly it declaring procs/etc. tweaks things enough to trigger the problem), and I don't do anything very unusual there, Nim-package-wise.
Ehm... forget about the if, it was an attempt to have only one example that triggers both behaviors on the same executable.
Do you mind to tell me your version of GCC?? I'm on 9.3 from feb...
https://play.nim-lang.org/#ix=2x3G
Seems in Linux it works properly, using both backends, with 1.2.6...
Literally none of my code was active with the if clparams.len==0
. So, to me that matters. :-) I was using gcc-10.2 and those versions of Nim I mentioned.
import cligen
proc cmd_test =
raise newException(Exception, "Error!")
when isMainModule:
dispatch(cmd_test)
This simple snippet causes a SIGABRT on my side, using cpp backend... but works ok using c backend... very strange, as the Linux example in playnim works
(Also, it would matter to anyone trying to create a "minimal" reproducible failure for a bug report/question to Nim core.)
Literally none of my code was active with the
if clparams.len==0
. So, to me that matters. :-) I was using gcc-10.2 and those versions of Nim I mentioned.
yeah, that branch in the if was not exhibiting the issue....
(Also, it would matter to anyone trying to create a "minimal" reproducible failure for a bug report/question to Nim core.)
This is what I'm trying to do. Asked on the channel, no answer yet
very strange, as the Linux example in playnim works
Yeah. "thorny problem", but I don't think one I can do anything about. :(
Yes, I know... trying to help as much as I can. I really appreciate your efforts.
I see. I misunderstood. Since it all works for me, I thought the if
one failed for you just like the cligen
one. Maybe you do need some limited extra amount of call stack complexity.
It's unrelated (with virtual certainty), but I was once doing an emit
with inline C (adding that wy hash for ints to stdlib) and I used return
instead of assigning to result
. This messed up all the exception/call stack machinery. But I don't do anything like that in cligen
. (Well, I do in cligen/strUt
but that is non-imported library code present only for examples/dups
.)
Well... I try no to use emits or too advanced things... that's why I tried to make the example as simple as possible. But there are so many variables playing here: compiler, arch, os, and underlying compiler... plus all their versions... Impossible to test them all.
I'm wondering if the issue has to do with the terminate handler (https://github.com/nim-lang/Nim/issues/12573) although this one is for MSVC, not GCC... who knows.
I generally use the Nim-devel versions and just a few old stable versions for testing. I think many people around the Nim community do. While it may seem more "stable" to use old versions, every version of Nim surely has many bugs. The bugs in the tip/head of devel are probably more well known to the devs. ;-) Since the dev team is so small, you may get better support that way. Nothing is really for certain, though. I'm just motivating my advice.
It does seem like some kind of exception escaping Nim's handling system and hitting the OS handling, but that's more or less just a re-description of your problem in other words.
When an exception occurs within a
dispatchMulti
, cligen ends with a SIGABRT instead of displaying the traceback.The following example can be run with or without params, to demonstrate different behavior depending if cligen is within the call to
cmd_start
or not.Example:
Expected result (executing without params) as
$ app
:Current result (executing with params) as
$ app start