Skip to content

Commit

Permalink
Support debugging multithreaded programs until they create their firs…
Browse files Browse the repository at this point in the history
…t threads

ocamldebug has never worked with multithreaded programs: multiple
threads mess up the communication protocol with the debugger, and the
fork()-based checkpointing mechanism breaks too.

Up to 4.11, the debugger would work fine until the first thread was
created.  Then, bizarre errors would be reported.

In 4.12 (commit e678885), a check was
added, causing any program linked with the threads library to report a
fatal error at start-up time when run under the debugger.

As reported in ocaml#10517, this check is too strong: some programs just
happen to be linked with the threads library, e.g. because they use
LWT, but may never start a thread.  There's no reason to refuse to
debug these programs.

This commit reverts the 4.12 change and adds a check in Thread.create
that aborts the program if it is run under the debugger.  This way,
programs linked with the threads library can still be debugged until
the point where they create new threads.
  • Loading branch information
xavierleroy committed Aug 31, 2021
1 parent b4a6d23 commit 9220811
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 1 deletion.
5 changes: 5 additions & 0 deletions otherlibs/systhreads/st_stubs.c
Expand Up @@ -19,6 +19,7 @@
#include "caml/backtrace.h"
#include "caml/callback.h"
#include "caml/custom.h"
#include "caml/debugger.h"
#include "caml/domain.h"
#include "caml/fail.h"
#include "caml/io.h"
Expand Down Expand Up @@ -558,6 +559,10 @@ CAMLprim value caml_thread_new(value clos) /* ML */
caml_thread_t th;
st_retcode err;

#ifndef NATIVE_CODE
if (caml_debugger_in_use)
caml_fatal_error("ocamldebug does not support multithreaded programs");
#endif
/* Create a thread info block */
th = caml_thread_new_info();
if (th == NULL) caml_raise_out_of_memory();
Expand Down
4 changes: 3 additions & 1 deletion runtime/debugger.c
Expand Up @@ -137,7 +137,9 @@ static void open_connection(void)
dbg_in = caml_open_descriptor_in(dbg_socket);
dbg_out = caml_open_descriptor_out(dbg_socket);
/* The code in this file does not bracket channel I/O operations with
Lock and Unlock, so fail if those are not no-ops. */
Lock and Unlock, but this is safe because the debugger only works
with single-threaded programs. The program being debugged
will abort when it creates a thread. */
if (caml_channel_mutex_lock != NULL ||
caml_channel_mutex_unlock != NULL ||
caml_channel_mutex_unlock_exn != NULL)
Expand Down

0 comments on commit 9220811

Please sign in to comment.