Direct-linking changes lose line-number on invoke()

Description

(ns foo) ;; 1 ;; 2 ;; 3 ;; 4 ;; 5 ;; 6 ;; 7 (defn callstack [] ;; 8 [1 2 3] ;; 9 (throw (Exception. "whoopsie!"))) ;; 10

Stack Trace comparison. Only the first two lines of each trace are relevant, the rest is all REPL fluff.

;;; 1.7.0 {:cause "whoopsie!", :via [{:type java.lang.Exception, :message "whoopsie!", :at [foo$callstack invoke "foo.clj" 8]}], :trace [[foo$callstack invoke "foo.clj" 8] [user$eval7675 invoke "form-init3342294504880003721.clj" 1] [clojure.lang.Compiler eval "Compiler.java" 6782] [clojure.lang.Compiler eval "Compiler.java" 6745] ... ;;; 1.8 RC2 {:cause "whoopsie!", :via [{:type java.lang.Exception, :message "whoopsie!", :at [foo$callstack invokeStatic "foo.clj" 8]}], :trace [[foo$callstack invokeStatic "foo.clj" 8] [foo$callstack invoke "foo.clj" -1] ;; Unexpected: -1 [user$eval4 invokeStatic "NO_SOURCE_FILE" 28] [user$eval4 invoke "NO_SOURCE_FILE" -1] ;; Unexpected: -1 [clojure.lang.Compiler eval "Compiler.java" 6913] [clojure.lang.Compiler eval "Compiler.java" 6876] ... ;;; 1.8 RC2 with patch {:cause "whoopsie!", :via [{:type java.lang.Exception, :message "whoopsie!", :at [foo$callstack invokeStatic "foo.clj" 8]}], :trace [[foo$callstack invokeStatic "foo.clj" 8] [foo$callstack invoke "foo.clj" 8] ;; Fixed [user$eval4 invokeStatic "NO_SOURCE_FILE" 3] [user$eval4 invoke "NO_SOURCE_FILE" 3] ;; Fixed [clojure.lang.Compiler eval "Compiler.java" 6917] [clojure.lang.Compiler eval "Compiler.java" 6880] ...

Cause: Non-direct linking now calls from invoke() through to invokeStatic(). In invoke(), Compiler does not visitLineNumber() before invoke() calls invokeStatic(), meaning that stack traces end up with -1 instead of a useful line number.

Patch: CLJ-1854-more-context.patch

Screened by: Alex Miller

Environment

Clojure 1.8RC2, leiningen 2.5.1

Attachments

2
  • 24 Nov 2015, 07:54 PM
  • 24 Nov 2015, 06:53 PM

Activity

Show:

Gary Trakhman November 24, 2015 at 11:20 PM

Comparison of line numbers between 1.7 and 1.8 with patch here applied, clojure.test/do-report was modified to print stacktraces. It's weird that the numbers are different between parallel invoke/invokeStatic pairs.

diff --git a/src/clj/clojure/test.clj b/src/clj/clojure/test.clj index 55e00f7..318ef20 100644 --- a/src/clj/clojure/test.clj +++ b/src/clj/clojure/test.clj @@ -349,7 +349,10 @@ (report (case (:type m) - :fail (merge (file-and-line (new java.lang.Throwable) 1) m) + :fail (merge (file-and-line (doto (new java.lang.Throwable) + (.printStackTrace)) + 1) + m) :error (merge (file-and-line (:actual m) 0) m) m)))

1.7

gary@gary-dell:~/.m2/repository/org/clojure/clojure/1.7.0$ java -jar clojure-1.7.0.jar -r Clojure 1.7.0 user=> (use 'clojure.test) nil user=> (deftest a [] (is false)) #'user/a user=> (run-tests) Testing user java.lang.Throwable at clojure.test$do_report.invoke(test.clj:352) at user$fn__3.invoke(NO_SOURCE_FILE:3) at clojure.test$test_var$fn__7671.invoke(test.clj:707) at clojure.test$test_var.invoke(test.clj:707) at clojure.test$test_vars$fn__7693$fn__7698.invoke(test.clj:725) at clojure.test$default_fixture.invoke(test.clj:677) at clojure.test$test_vars$fn__7693.invoke(test.clj:725) at clojure.test$default_fixture.invoke(test.clj:677) at clojure.test$test_vars.invoke(test.clj:721) at clojure.test$test_all_vars.invoke(test.clj:731) at clojure.test$test_ns.invoke(test.clj:750) at clojure.core$map$fn__4553.invoke(core.clj:2624) at clojure.lang.LazySeq.sval(LazySeq.java:40) at clojure.lang.LazySeq.seq(LazySeq.java:49) at clojure.lang.Cons.next(Cons.java:39) at clojure.lang.RT.boundedLength(RT.java:1735) at clojure.lang.RestFn.applyTo(RestFn.java:130) at clojure.core$apply.invoke(core.clj:632) at clojure.test$run_tests.doInvoke(test.clj:765) at clojure.lang.RestFn.invoke(RestFn.java:408) at clojure.test$run_tests.invoke(test.clj:763) at user$eval7.invoke(NO_SOURCE_FILE:4) at clojure.lang.Compiler.eval(Compiler.java:6782) at clojure.lang.Compiler.eval(Compiler.java:6745) at clojure.core$eval.invoke(core.clj:3081) at clojure.main$repl$read_eval_print__7099$fn__7102.invoke(main.clj:240) at clojure.main$repl$read_eval_print__7099.invoke(main.clj:240) at clojure.main$repl$fn__7108.invoke(main.clj:258) at clojure.main$repl.doInvoke(main.clj:258) at clojure.lang.RestFn.invoke(RestFn.java:421) at clojure.main$repl_opt.invoke(main.clj:324) at clojure.main$main.doInvoke(main.clj:421) at clojure.lang.RestFn.invoke(RestFn.java:408) at clojure.lang.Var.invoke(Var.java:379) at clojure.lang.AFn.applyToHelper(AFn.java:154) at clojure.lang.Var.applyTo(Var.java:700) at clojure.main.main(main.java:37) FAIL in (a) (NO_SOURCE_FILE:3) expected: false actual: false Ran 1 tests containing 1 assertions. 1 failures, 0 errors. {:test 1, :pass 0, :fail 1, :error 0, :type :summary}

1.8 with patch here applied

gary@gary-dell:~/.m2/repository/org/clojure/clojure/1.8.0-master-SNAPSHOT$ java -jar clojure-1.8.0-master-SNAPSHOT.jar -r Clojure 1.8.0-master-SNAPSHOT user=> (use 'clojure.test) nil user=> (deftest a [] (is false)) #'user/a user=> (run-tests) Testing user java.lang.Throwable at clojure.test$do_report.invokeStatic(test.clj:355) at clojure.test$do_report.invoke(test.clj:342) at user$fn__3.invokeStatic(NO_SOURCE_FILE:3) at user$fn__3.invoke(NO_SOURCE_FILE:2) at clojure.test$test_var$fn__7973.invoke(test.clj:706) at clojure.test$test_var.invokeStatic(test.clj:706) at clojure.test$test_var.invoke(test.clj:697) at clojure.test$test_vars$fn__7995$fn__8000.invoke(test.clj:724) at clojure.test$default_fixture.invokeStatic(test.clj:676) at clojure.test$default_fixture.invoke(test.clj:672) at clojure.test$test_vars$fn__7995.invoke(test.clj:724) at clojure.test$default_fixture.invokeStatic(test.clj:676) at clojure.test$default_fixture.invoke(test.clj:672) at clojure.test$test_vars.invokeStatic(test.clj:720) at clojure.test$test_all_vars.invokeStatic(test.clj:726) at clojure.test$test_ns.invokeStatic(test.clj:747) at clojure.test$test_ns.invoke(test.clj:732) at clojure.core$map$fn__4781.invoke(core.clj:2648) at clojure.lang.LazySeq.sval(LazySeq.java:40) at clojure.lang.LazySeq.seq(LazySeq.java:49) at clojure.lang.Cons.next(Cons.java:39) at clojure.lang.RT.boundedLength(RT.java:1749) at clojure.lang.RestFn.applyTo(RestFn.java:130) at clojure.core$apply.invokeStatic(core.clj:647) at clojure.test$run_tests.invokeStatic(test.clj:757) at clojure.test$run_tests.doInvoke(test.clj:757) at clojure.lang.RestFn.invoke(RestFn.java:408) at clojure.test$run_tests.invokeStatic(test.clj:762) at clojure.test$run_tests.invoke(test.clj:757) at user$eval7.invokeStatic(NO_SOURCE_FILE:4) at user$eval7.invoke(NO_SOURCE_FILE:4) at clojure.lang.Compiler.eval(Compiler.java:6915) at clojure.lang.Compiler.eval(Compiler.java:6878) at clojure.core$eval.invokeStatic(core.clj:3107) at clojure.core$eval.invoke(core.clj:3103) at clojure.main$repl$read_eval_print__7402$fn__7405.invoke(main.clj:240) at clojure.main$repl$read_eval_print__7402.invoke(main.clj:240) at clojure.main$repl$fn__7411.invoke(main.clj:258) at clojure.main$repl.invokeStatic(main.clj:258) at clojure.main$repl_opt.invokeStatic(main.clj:322) at clojure.main$repl_opt.invoke(main.clj:318) at clojure.main$main.invokeStatic(main.clj:421) at clojure.main$main.doInvoke(main.clj:384) at clojure.lang.RestFn.invoke(RestFn.java:408) at clojure.lang.Var.invoke(Var.java:379) at clojure.lang.AFn.applyToHelper(AFn.java:154) at clojure.lang.Var.applyTo(Var.java:700) at clojure.main.main(main.java:37) FAIL in (a) (test.clj:342) expected: false actual: false Ran 1 tests containing 1 assertions. 1 failures, 0 errors. {:test 1, :pass 0, :fail 1, :error 0, :type :summary} user=>

Gary Trakhman November 24, 2015 at 10:03 PM

I will make a separate ticket for the potential clojure.test change.

Alex Miller November 24, 2015 at 9:56 PM

I think that issue should be a separate ticket if so.

Gary Trakhman November 24, 2015 at 9:47 PM

The current CLJ-1854-more-context.patch just gives me the same line number for all test cases, in my case it's test.clj:342 instead of -1 from before. I think perhaps clojure.test might need an adjustment as well, in particular the hardcoded '1' magic number here: https://github.com/clojure/clojure/blob/master/src/clj/clojure/test.clj#L351

test.clj:342 is do-report: https://github.com/clojure/clojure/blob/master/src/clj/clojure/test.clj#L342

Ghadi Shayban November 24, 2015 at 9:44 PM

Example has recursion through walk and is not minimal. Editing the ticket for reproducibility.

Completed

Details

Assignee

Reporter

Approval

Ok

Patch

Code

Priority

Affects versions

Fix versions

Created November 24, 2015 at 5:48 PM
Updated December 1, 2015 at 5:47 PM
Resolved December 1, 2015 at 5:47 PM