OCAMLRUNPARAM=b=2 => load debuginfo

Load the debug information during runtime startup if OCAMLRUNPARAM=b=2.
This guards against the specific case of running out of fds, since the
debug information can't then be loaded.
master
David Allsopp 2018-12-11 10:17:04 +01:00
parent 43b28fac00
commit 692bd73123
12 changed files with 40 additions and 10 deletions

View File

@ -65,7 +65,8 @@ OCaml 4.12.0
### Runtime system: ### Runtime system:
- #2195: Improve error message in bytecode stack trace printing - #2195: Improve error message in bytecode stack trace printing and load
debug information during bytecode startup if OCAMLRUNPARAM=b=2.
(David Allsopp, review by Gabriel Scherer and Xavier Leroy) (David Allsopp, review by Gabriel Scherer and Xavier Leroy)
- #9756: garbage collector colors change - #9756: garbage collector colors change

View File

@ -112,8 +112,13 @@ The following environment variables are also consulted:
\fi \fi
\begin{options} \begin{options}
\item[b] (backtrace) Trigger the printing of a stack backtrace \item[b] (backtrace) Trigger the printing of a stack backtrace
when an uncaught exception aborts the program. when an uncaught exception aborts the program. An optional argument can
This option takes no argument. be provided: "b=0" turns backtrace printing off; "b=1" is equivalent to
"b" and turns backtrace printing on; "b=2" turns backtrace printing on
and forces the runtime system to load debugging information at program
startup time instead of at backtrace printing time. "b=2" can be used if
the runtime is unable to load debugging information at backtrace
printing time, for example if there are no file descriptors available.
\item[p] (parser trace) Turn on debugging support for \item[p] (parser trace) Turn on debugging support for
"ocamlyacc"-generated parsers. When this option is on, "ocamlyacc"-generated parsers. When this option is on,
the pushdown automaton that executes the parsers prints a the pushdown automaton that executes the parsers prints a

View File

@ -123,6 +123,7 @@ CAMLexport void caml_print_exception_backtrace(void)
} }
} }
/* See also printexc.ml */
switch (caml_debug_info_status()) { switch (caml_debug_info_status()) {
case FILE_NOT_FOUND: case FILE_NOT_FOUND:
fprintf(stderr, fprintf(stderr,
@ -143,7 +144,7 @@ CAMLexport void caml_print_exception_backtrace(void)
fprintf(stderr, fprintf(stderr,
"(Cannot print locations:\n " "(Cannot print locations:\n "
"bytecode executable program file cannot be opened;\n " "bytecode executable program file cannot be opened;\n "
"-- too many open files)\n"); "-- too many open files. Try running with OCAMLRUNPARAM=b=2)\n");
break; break;
} }
} }

View File

@ -421,6 +421,13 @@ CAMLexport void caml_init_debug_info(void)
caml_add_debug_info(caml_start_code, Val_long(caml_code_size), Val_unit); caml_add_debug_info(caml_start_code, Val_long(caml_code_size), Val_unit);
} }
CAMLexport void caml_load_main_debug_info(void)
{
if (Caml_state->backtrace_active > 1) {
read_main_debug_info(caml_debug_info.contents[0]);
}
}
int caml_debug_info_available(void) int caml_debug_info_available(void)
{ {
return (caml_debug_info.size != 0); return (caml_debug_info.size != 0);

View File

@ -109,6 +109,7 @@ CAMLextern char_os * caml_cds_file;
* different prototype. */ * different prototype. */
extern void caml_stash_backtrace(value exn, value * sp, int reraise); extern void caml_stash_backtrace(value exn, value * sp, int reraise);
CAMLextern void caml_load_main_debug_info(void);
#endif #endif

View File

@ -111,7 +111,7 @@ void caml_parse_ocamlrunparam(void)
switch (*opt++){ switch (*opt++){
case 'a': scanmult (opt, &p); caml_set_allocation_policy ((intnat) p); case 'a': scanmult (opt, &p); caml_set_allocation_policy ((intnat) p);
break; break;
case 'b': scanmult (opt, &p); caml_record_backtrace(Val_bool (p)); case 'b': scanmult (opt, &p); caml_record_backtrace(Val_int (p));
break; break;
case 'c': scanmult (opt, &p); caml_cleanup_on_exit = (p != 0); break; case 'c': scanmult (opt, &p); caml_cleanup_on_exit = (p != 0); break;
case 'h': scanmult (opt, &caml_init_heap_wsz); break; case 'h': scanmult (opt, &caml_init_heap_wsz); break;

View File

@ -454,6 +454,8 @@ CAMLexport void caml_main(char_os **argv)
caml_oldify_mopup (); caml_oldify_mopup ();
/* Initialize system libraries */ /* Initialize system libraries */
caml_sys_init(exe_name, argv + pos); caml_sys_init(exe_name, argv + pos);
/* Load debugging info, if b>=2 */
caml_load_main_debug_info();
#ifdef _WIN32 #ifdef _WIN32
/* Start a thread to handle signals */ /* Start a thread to handle signals */
if (caml_secure_getenv(T("CAMLSIGPIPE"))) if (caml_secure_getenv(T("CAMLSIGPIPE")))
@ -545,6 +547,8 @@ CAMLexport value caml_startup_code_exn(
caml_section_table_size = section_table_size; caml_section_table_size = section_table_size;
/* Initialize system libraries */ /* Initialize system libraries */
caml_sys_init(exe_name, argv); caml_sys_init(exe_name, argv);
/* Load debugging info, if b>=2 */
caml_load_main_debug_info();
/* Execute the program */ /* Execute the program */
caml_debugger(PROGRAM_START, Val_unit); caml_debugger(PROGRAM_START, Val_unit);
return caml_interprete(caml_start_code, caml_code_size); return caml_interprete(caml_start_code, caml_code_size);

View File

@ -301,7 +301,7 @@ let errors = [| "";
(* NO_FDS *) (* NO_FDS *)
"(Cannot print locations:\n \ "(Cannot print locations:\n \
bytecode executable program file cannot be opened;\n \ bytecode executable program file cannot be opened;\n \
-- too many open files)" -- too many open files. Try running with OCAMLRUNPARAM=b=2)"
|] |]
let default_uncaught_exception_handler exn raw_backtrace = let default_uncaught_exception_handler exn raw_backtrace =

View File

@ -0,0 +1,4 @@
Fatal error: exception Stdlib.Exit
Raised by primitive operation at Stdlib.open_in_gen in file "stdlib.ml", line 399, characters 28-54
Called from Pr2195 in file "pr2195.ml", line 24, characters 6-19
Re-raised at Pr2195 in file "pr2195.ml", line 29, characters 4-41

View File

@ -3,4 +3,4 @@ Raised by primitive operation at unknown location
Called from unknown location Called from unknown location
(Cannot print locations: (Cannot print locations:
bytecode executable program file cannot be opened; bytecode executable program file cannot be opened;
-- too many open files) -- too many open files. Try running with OCAMLRUNPARAM=b=2)

View File

@ -2,7 +2,14 @@
flags += "-g" flags += "-g"
exit_status = "2" exit_status = "2"
* bytecode * bytecode
reference = "${test_source_directory}/pr2195.byte.reference" ocamlrunparam += ",b=0"
reference = "${test_source_directory}/pr2195-nolocs.byte.reference"
* bytecode
ocamlrunparam += ",b=1"
reference = "${test_source_directory}/pr2195-nolocs.byte.reference"
* bytecode
ocamlrunparam += ",b=2"
reference = "${test_source_directory}/pr2195-locs.byte.reference"
* native * native
reference = "${test_source_directory}/pr2195.opt.reference" reference = "${test_source_directory}/pr2195.opt.reference"
compare_programs = "false" compare_programs = "false"

View File

@ -1,5 +1,5 @@
Fatal error: exception Stdlib.Exit Fatal error: exception Stdlib.Exit
Raised by primitive operation at Stdlib.open_in_gen in file "stdlib.ml", line 399, characters 28-54 Raised by primitive operation at Stdlib.open_in_gen in file "stdlib.ml", line 399, characters 28-54
Called from Stdlib.open_in in file "stdlib.ml" (inlined), line 404, characters 2-45 Called from Stdlib.open_in in file "stdlib.ml" (inlined), line 404, characters 2-45
Called from Pr2195 in file "pr2195.ml", line 17, characters 6-19 Called from Pr2195 in file "pr2195.ml", line 24, characters 6-19
Re-raised at Pr2195 in file "pr2195.ml", line 22, characters 4-41 Re-raised at Pr2195 in file "pr2195.ml", line 29, characters 4-41