forked from Imagelibrary/binutils-gdb
[gdb/dap] Fix race between dap startup and dap log file
In dap_gdb_start we do:
...
append GDBFLAGS " -iex \"set debug dap-log-file $logfile\" -q -i=dap"
...
While the dap log file setting comes before the dap interpreter setting,
the order is the other way around:
- first, the dap interpreter is started
- second, the -iex commands are executed and the log file is initialized.
Consequently, there's a race between dap interpreter startup and dap log file
initialization.
This cannot be fixed by using -eiex instead. Before the interpreter is
started, the "set debug dap-log-file" command is not yet registered.
Fix this by postponing the start of the DAP server until GDB has processed all
command files.
Tested on aarch64-linux.
Approved-By: Tom Tromey <tom@tromey.com>
PR dap/31386
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31386
This commit is contained in:
@@ -69,5 +69,23 @@ def run():
|
||||
os.close(wfd)
|
||||
|
||||
# Note the inferior output is opened in text mode.
|
||||
global server
|
||||
server = Server(open(saved_in, "rb"), open(saved_out, "wb"), open(rfd, "r"))
|
||||
startup.start_dap(server.main_loop)
|
||||
|
||||
|
||||
# Whether the interactive session has started.
|
||||
session_started = False
|
||||
|
||||
|
||||
def pre_command_loop():
|
||||
"""DAP's pre_command_loop interpreter hook. This is called by the GDB DAP
|
||||
interpreter."""
|
||||
global session_started
|
||||
if not session_started:
|
||||
# The pre_command_loop interpreter hook can be called several times.
|
||||
# The first time it's called, it means we're starting an interactive
|
||||
# session.
|
||||
session_started = True
|
||||
startup.thread_log("starting DAP server")
|
||||
global server
|
||||
startup.start_dap(server.main_loop)
|
||||
|
||||
@@ -61,13 +61,18 @@ public:
|
||||
return m_ui_out.get ();
|
||||
}
|
||||
|
||||
void pre_command_loop () override;
|
||||
|
||||
private:
|
||||
|
||||
std::unique_ptr<ui_out> m_ui_out;
|
||||
};
|
||||
|
||||
void
|
||||
dap_interp::init (bool top_level)
|
||||
|
||||
/* Call function FN_NAME from module gdb.dap. */
|
||||
|
||||
static void
|
||||
call_dap_fn (const char *fn_name)
|
||||
{
|
||||
gdbpy_enter enter_py;
|
||||
|
||||
@@ -75,18 +80,30 @@ dap_interp::init (bool top_level)
|
||||
if (dap_module == nullptr)
|
||||
gdbpy_handle_exception ();
|
||||
|
||||
gdbpy_ref<> func (PyObject_GetAttrString (dap_module.get (), "run"));
|
||||
gdbpy_ref<> func (PyObject_GetAttrString (dap_module.get (), fn_name));
|
||||
if (func == nullptr)
|
||||
gdbpy_handle_exception ();
|
||||
|
||||
gdbpy_ref<> result_obj (PyObject_CallObject (func.get (), nullptr));
|
||||
if (result_obj == nullptr)
|
||||
gdbpy_handle_exception ();
|
||||
}
|
||||
|
||||
void
|
||||
dap_interp::init (bool top_level)
|
||||
{
|
||||
call_dap_fn ("run");
|
||||
|
||||
current_ui->input_fd = -1;
|
||||
current_ui->m_input_interactive_p = false;
|
||||
}
|
||||
|
||||
void
|
||||
dap_interp::pre_command_loop ()
|
||||
{
|
||||
call_dap_fn ("pre_command_loop");
|
||||
}
|
||||
|
||||
void _initialize_py_interp ();
|
||||
void
|
||||
_initialize_py_interp ()
|
||||
|
||||
Reference in New Issue
Block a user