The unpac monorepo manager self-hosting as a monorepo using unpac
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request #14363 from kayceesrk/kc/domain_join_reraise

Domain.join preserves the backtrace.

authored by

David Allsopp and committed by
GitHub
44b89464 8d697505

+75 -11
+6
Changes
··· 88 88 89 89 ### Standard library: 90 90 91 + - #14363: Preserve the backtrace at exceptional domain termination. Domain.join 92 + on an exceptionally terminated domain re-raises the exception with the 93 + backtrace. 94 + (KC Sivaramakrishnan, report by Nathan Taylor, review by Gabriel Scherer, 95 + David Allsopp) 96 + 91 97 - #13372: New Format and Printf printf-like functions that accept a 92 98 heterogeneous list as arguments. 93 99 (Leonardo Santos, review by Florian Angeletti and Gabriel Scherer)
+2
runtime/caml/backtrace.h
··· 150 150 void caml_init_backtrace(void); 151 151 CAMLextern void caml_init_debug_info(void); 152 152 153 + value caml_get_exception_raw_backtrace(value unit); 154 + 153 155 #endif /* CAML_INTERNALS */ 154 156 155 157 #endif /* CAML_BACKTRACE_H */
+18 -8
runtime/domain.c
··· 1294 1294 static value make_finished(caml_result result) 1295 1295 { 1296 1296 CAMLparam0(); 1297 - CAMLlocal1(res); 1298 - res = caml_alloc_1( 1299 - (caml_result_is_exception(result) ? 1300 - 1 /* Error */ : 1301 - 0 /* Ok */), 1302 - result.data); 1303 - /* [Finished res] */ 1304 - res = caml_alloc_1(0, res); 1297 + CAMLlocal2(res, bt); 1298 + if (caml_result_is_exception(result)) { 1299 + res = result.data; /* Ensure that [result.data] is rooted before 1300 + subsequent allocations */ 1301 + /* res = exn */ 1302 + bt = caml_get_exception_raw_backtrace(Val_unit); 1303 + res = caml_alloc_2(0, res, bt); 1304 + /* res = (exn, bt) */ 1305 + res = caml_alloc_1(1 /* Error */, res); 1306 + /* res = Error (exn, bt) */ 1307 + res = caml_alloc_1(0 /* Finished */, res); 1308 + /* res = Finished(Error(exn, bt)) */ 1309 + } else { 1310 + res = caml_alloc_1(0 /* Ok */,result.data); 1311 + /* res = Ok v */ 1312 + res = caml_alloc_1(0, res); 1313 + /* res = Finished(Ok v) */ 1314 + } 1305 1315 CAMLreturn(res); 1306 1316 } 1307 1317
+2
stdlib/.depend
··· 216 216 stdlib__Domain.cmo : domain.ml \ 217 217 stdlib__Sys.cmi \ 218 218 stdlib.cmi \ 219 + stdlib__Printexc.cmi \ 219 220 stdlib__Obj.cmi \ 220 221 stdlib__Mutex.cmi \ 221 222 stdlib__List.cmi \ ··· 226 227 stdlib__Domain.cmx : domain.ml \ 227 228 stdlib__Sys.cmx \ 228 229 stdlib.cmx \ 230 + stdlib__Printexc.cmx \ 229 231 stdlib__Obj.cmx \ 230 232 stdlib__Mutex.cmx \ 231 233 stdlib__List.cmx \
+1 -1
stdlib/StdlibModules
··· 73 73 mutex \ 74 74 condition \ 75 75 semaphore \ 76 - domain \ 77 76 camlinternalFormat \ 78 77 printf \ 79 78 arg \ 80 79 printexc \ 80 + domain \ 81 81 fun \ 82 82 gc \ 83 83 in_channel \
+3 -2
stdlib/domain.ml
··· 25 25 26 26 type 'a state = 27 27 | Running 28 - | Finished of ('a, exn) result [@warning "-unused-constructor"] 28 + | Finished of ('a, exn * Printexc.raw_backtrace) result 29 + [@warning "-unused-constructor"] 29 30 30 31 type 'a term_sync = { 31 32 (* protected by [mut] *) ··· 299 300 in 300 301 match Mutex.protect term_sync.mut loop with 301 302 | Ok x -> x 302 - | Error ex -> raise ex 303 + | Error (ex, bt) -> Printexc.raise_with_backtrace ex bt 303 304 304 305 let count = Raw.get_domain_count 305 306 let recommended_domain_count = Raw.get_recommended_domain_count
+28
testsuite/tests/backtrace/backtrace_domain_join.ml
··· 1 + (* TEST_BELOW 2 + (* Blank lines added here to preserve locations. *) 3 + 4 + *) 5 + 6 + (* A test for backtraces on [Domain.join] *) 7 + 8 + let rec bar n = 9 + if n = 0 then failwith "bar raised" 10 + else foo (n-1) + 1 11 + 12 + and foo n = 13 + if n = 0 then failwith "foo raised" 14 + else bar (n-1) + 1 15 + 16 + let f () = foo 10 17 + 18 + let _ = 19 + match Domain.spawn f |> Domain.join with 20 + | v -> () 21 + | exception e -> 22 + let bt = Printexc.get_raw_backtrace () in 23 + Printexc.print_raw_backtrace stdout bt 24 + 25 + (* TEST 26 + flags = "-g"; 27 + ocamlrunparam += ",b=1"; 28 + *)
+15
testsuite/tests/backtrace/backtrace_domain_join.reference
··· 1 + Raised at Stdlib.failwith in file "stdlib.ml", line 29, characters 17-33 2 + Called from Backtrace_domain_join.bar in file "backtrace_domain_join.ml", line 10, characters 7-16 3 + Called from Backtrace_domain_join.foo in file "backtrace_domain_join.ml", line 14, characters 7-16 4 + Called from Backtrace_domain_join.bar in file "backtrace_domain_join.ml", line 10, characters 7-16 5 + Called from Backtrace_domain_join.foo in file "backtrace_domain_join.ml", line 14, characters 7-16 6 + Called from Backtrace_domain_join.bar in file "backtrace_domain_join.ml", line 10, characters 7-16 7 + Called from Backtrace_domain_join.foo in file "backtrace_domain_join.ml", line 14, characters 7-16 8 + Called from Backtrace_domain_join.bar in file "backtrace_domain_join.ml", line 10, characters 7-16 9 + Called from Backtrace_domain_join.foo in file "backtrace_domain_join.ml", line 14, characters 7-16 10 + Called from Backtrace_domain_join.bar in file "backtrace_domain_join.ml", line 10, characters 7-16 11 + Called from Backtrace_domain_join.foo in file "backtrace_domain_join.ml", line 14, characters 7-16 12 + Called from Stdlib__Domain.spawn.body in file "domain.ml", line 270, characters 16-20 13 + Re-raised at Stdlib__Domain.spawn.body in file "domain.ml", line 286, characters 8-17 14 + Re-raised at Stdlib__Domain.join in file "domain.ml", line 303, characters 22-57 15 + Called from Backtrace_domain_join in file "backtrace_domain_join.ml", line 19, characters 8-37