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

Release bytecode only after backtrace has been recorded #10803

Merged
merged 8 commits into from
Jan 30, 2022

Conversation

renatoalencar
Copy link
Contributor

@renatoalencar renatoalencar commented Dec 1, 2021

When an exception happens bytecode has been released before the
backtrace is recorded and so all the debugging information related,
because of that the backtrace information for the script that has
just been compiled was not being found, which resulted on showing
'unknown location' instead of the actual location.

Enable debug flag for running a file on toplevel.

Resolves #9701

When an exception happens bytecode has been released before the
backtrace is recorded and so all the debugging information related,
because of that the backtrace information for the script that has
just been compiled was not being found, which resulted on showing
'unknown location' instead of the actual location.

Enable debug flag for running a file on toplevel
Copy link
Member

@gasche gasche left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that this is a correct bugfix to a regression we introduced in 4.12 -- see the discussion in #9701 (comment) .

@@ -87,13 +87,16 @@ let load_lambda ppf lam =
match
may_trace := true;
Fun.protect
~finally:(fun () -> may_trace := false;
if can_free then Meta.release_bytecode bytecode)
~finally:(fun () -> may_trace := false)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would be in favor of completely removing the Fun.protect call here, if only because it shows up in the user-visible backtrace.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, removed.

@renatoalencar renatoalencar marked this pull request as ready for review December 1, 2021 16:08
@renatoalencar
Copy link
Contributor Author

@gasche I would like to have a regression test for that. But couldn't figure that out from what is present on testsuite/tests/tool-toplevel/.

@gasche
Copy link
Member

gasche commented Dec 1, 2021

Re. testing: there is a flag ocaml_script_as_argument to test ocaml foo.ml, see testsuite/tests/tool-ocaml/directive_failure.ml (./ocamltest/ocamltest -e ..../mytest.ml shows how the test runs, -e logs on stderr instead of a file).

@renatoalencar
Copy link
Contributor Author

renatoalencar commented Dec 1, 2021

I was able to add the test, but not to make sure that's right. I couldn't make it fail when the reference file is different from the actual output of the script.

ocaml_exit_status = "2"
* setup-ocaml-build-env
** ocaml
*)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to add a check-ocaml-output step (see for example tests/typing-shadowing-of-pervasives-submodules/redefine_largefile_top.ml).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@renatoalencar
Copy link
Contributor Author

Looks like that test is failing because of the backslash Windows uses for paths, toplevel/byte/topeval.ml still the same though. I'm gonna try to understand why.

> Running pr9701.ml in bytecode toplevel (expected exit status: 2)
> Commandline: C:\projects\🐫реализация-mingw32\runtime\ocamlrun.exe C:\projects\🐫реализация-mingw32\ocaml.exe -noinit -no-version -noprompt -nostdlib -I C:\projects\🐫реализация-mingw32\stdlib -I C:\projects\🐫реализация-mingw32\toplevel pr9701.ml
>   Redirecting stdout to C:\projects\🐫реализация-mingw32\testsuite\_ocamltest\tests/tool-toplevel\pr9701\ocaml\ocaml.output 
>   Redirecting stderr to C:\projects\🐫реализация-mingw32\testsuite\_ocamltest\tests/tool-toplevel\pr9701\ocaml\ocaml.output 
> ### begin stdout ###
> Exception: Failure "test".
> Raised at Stdlib.failwith in file "stdlib.ml", line 29, characters 17-33
> Called from <unknown> in file ".\pr9701.ml", line 13, characters 9-16
> Called from Topeval.load_lambda in file "toplevel/byte/topeval.ml", line 89, characters 4-14
> ### end stdout ###
> Action 1/1 (ocaml) passed
> Running test check-ocaml-output with 1 actions
> 
> Running action 1/1 (check-ocaml-output)
> Comparing toplevel output C:\projects\🐫реализация-mingw32\testsuite\_ocamltest\tests/tool-toplevel\pr9701\ocaml\ocaml.output to reference C:\projects\🐫реализация-mingw32\testsuite\tests\tool-toplevel\pr9701.compilers.reference
> Action 1/1 (check-ocaml-output) failed (toplevel output C:\projects\🐫реализация-mingw32\testsuite\_ocamltest\tests/tool-toplevel\pr9701\ocaml\ocaml.output differs from reference C:\projects\🐫реализация-mingw32\testsuite\tests\tool-toplevel\pr9701.compilers.reference: 
> --- "C:\\projects\\\360\237\220\253\321\200\320\265\320\260\320\273\320\270\320\267\320\260\321\206\320\270\321\217-mingw32\\testsuite\\tests\\tool-toplevel\\pr9701.compilers.reference"	2021-12-01 20:22:49.778687600 +0000
> +++ "C:\\projects\\\360\237\220\253\321\200\320\265\320\260\320\273\320\270\320\267\320\260\321\206\320\270\321\217-mingw32\\testsuite\\_ocamltest\\tests/tool-toplevel\\pr9701\\ocaml\\ocaml.output"	2021-12-01 20:50:30.477731600 +0000
> @@ -1,4 +1,4 @@
>  Exception: Failure "test".
>  Raised at Stdlib.failwith in file "stdlib.ml", line 29, characters 17-33
> -Called from <unknown> in file "./pr9701.ml", line 13, characters 9-16
> +Called from <unknown> in file ".\pr9701.ml", line 13, characters 9-16
>  Called from Topeval.load_lambda in file "toplevel/byte/topeval.ml", line 89, characters 4-14
> 
> )

@Octachron
Copy link
Member

A simpler workaround might be to fix the filename by adding a line directive at the start of the script:

#1 "pr9701.ml"
Printexc.record_backtrace true;;

@gasche
Copy link
Member

gasche commented Dec 2, 2021

It's odd that Windows is using .\foo.ml, but toplevel/byte/topeval.ml. (cc @dra27)

But yes I would go for @Octachron's workaround, or just disable the test under Windows for now.

@renatoalencar
Copy link
Contributor Author

Gonna try @Octachron's workaround first, it seems to work locally.

@xavierleroy
Copy link
Contributor

What's the status on this PR? It looks like a bug fix, so it should be given some attention for 4.14.

@@ -109,6 +109,7 @@ let load_file = load_file false
(* Execute a script. If [name] is "", read the script from stdin. *)

let run_script ppf name args =
Clflags.debug := true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this related to the bug fix or an independent change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without this, the toplevel wouldn't collect debug information and show no line numbers after an exception.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still don't understand. Is this change visible to users? If so it should have been discussed as part of this PR and it should be described as such in the Changes file.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand this as a minor fix to an inconsistency in the toplevel code: Toploop.loop, called by interactive usage of the toplevel, sets Clflags.debug := true on entry, but (until this change) ocaml foo.ml would behave differently. With this change, both Toploop entry points from Topmain do the same thing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That will affect the output of shebang ocaml scripts, which is a known area for surprising bug reports (cf. the still-smouldering, if closed, stuff around #2155). That sounds worth an explicit entry in Changes, therefore?

@gasche
Copy link
Member

gasche commented Jan 30, 2022

Thanks for the ping! I guess we got distracted by other stuff. I fixed the Changes conflict and will merge in 4.14 if the CI comes back green.

@renatoalencar
Copy link
Contributor Author

What's the status on this PR? It looks like a bug fix, so it should be given some attention for 4.14.

It should be really to go. Although I think location for scripts could be really improved, this specific bug should be fixed.

@gasche gasche merged commit 6a7a7b3 into ocaml:trunk Jan 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

"unknown location" in backtraces in ocaml script
5 participants