[RFC,3/3,gdb/dap] Ignore OSError on stream.flush in JSON writer

Message ID 20240207090224.27521-4-tdevries@suse.de
State Dropped
Headers
Series Fix issues triggered by gdb.dap/eof.exp |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_gdb_build--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gdb_check--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 success Testing passed

Commit Message

Tom de Vries Feb. 7, 2024, 9:02 a.m. UTC
  Due to the previous two fixes, I can now run test-case gdb.dap/eof.exp without
coredumps happening.

However, I do run into:
...
FAIL: gdb.dap/eof.exp: exceptions in log file
...
due to:
...
JSON writer: caught exception: err=OSError(5, 'Input/output error'),
  type(err)=<class 'OSError'>
Traceback (most recent call last):
  File "python/gdb/dap/startup.py", line 72, in thread_wrapper
    target(*args)
  File "python/gdb/dap/io.py", line 80, in _json_writer
    stream.flush()
OSError: [Errno 5] Input/output error
...

I can image that the stream.flush would throw an OSError if it races with the
gdb main thread handling a SIGHUP and finalizing python in the process.

Handle this is in the simplest way I can think of: ignore the OSError, and
terminate the DAP thread.

Tested on aarch64-linux.
---
 gdb/python/lib/gdb/dap/io.py | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
  

Comments

Tom de Vries Feb. 7, 2024, 10:29 a.m. UTC | #1
On 2/7/24 10:02, Tom de Vries wrote:
> Due to the previous two fixes, I can now run test-case gdb.dap/eof.exp without
> coredumps happening.
> 
> However, I do run into:
> ...
> FAIL: gdb.dap/eof.exp: exceptions in log file
> ...
> due to:
> ...
> JSON writer: caught exception: err=OSError(5, 'Input/output error'),
>    type(err)=<class 'OSError'>
> Traceback (most recent call last):
>    File "python/gdb/dap/startup.py", line 72, in thread_wrapper
>      target(*args)
>    File "python/gdb/dap/io.py", line 80, in _json_writer
>      stream.flush()
> OSError: [Errno 5] Input/output error
> ...
> 
> I can image that the stream.flush would throw an OSError if it races with the
> gdb main thread handling a SIGHUP and finalizing python in the process.
> 
> Handle this is in the simplest way I can think of: ignore the OSError, and
> terminate the DAP thread.

I just found that the JSON reader thread does:
...
     except OSError:
         # Reading can also possibly throw an exception.  Treat this as 

         # EOF. 

         log_stack(LogLevel.FULL)
         return None
...

If we however threat this is in the JSON writer thread the same way, we 
get a FAIL from dap_check_log_file, because it checks for ^Traceback, 
which is generated by the log_stack.

Thanks,
- Tom
  

Patch

diff --git a/gdb/python/lib/gdb/dap/io.py b/gdb/python/lib/gdb/dap/io.py
index 4edd504c727..e5547bd1072 100644
--- a/gdb/python/lib/gdb/dap/io.py
+++ b/gdb/python/lib/gdb/dap/io.py
@@ -77,6 +77,9 @@  def start_json_writer(stream, queue):
             header_bytes = header.encode("ASCII")
             stream.write(header_bytes)
             stream.write(body_bytes)
-            stream.flush()
+            try:
+                stream.flush()
+            except OSError:
+                break
 
     start_thread("JSON writer", _json_writer)