[v4,2/4,gdb/cli] Allow source highlighting to be interrupted

Message ID 20231018171151.25427-3-tdevries@suse.de
State Superseded
Headers
Series Allow source highlighting to be interrupted |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_gdb_check--master-arm fail Patch failed to apply

Commit Message

Tom de Vries Oct. 18, 2023, 5:11 p.m. UTC
  Currently highlighting by the GNU source-highlight library cannot be
interrupted by either SIGINT or SIGTERM.

Fix this by installing a srchilite::HighlightEventListener that:
- checks whether SIGINT or SIGTERM was issued, and if so
- interrupts the command.

Interrupting the highlighting with SIGINT (using ^C) looks like this to the
user:
...
$ gdb -q a.out
Reading symbols from a.out...
(gdb) list
^CQuit
(gdb)
...
and with SIGTERM (using kill -SIGTERM $(pidof gdb)):
...
$ gdb -q a.out
Reading symbols from a.out...
(gdb) list
$
...

Tested on x86_64-linux.
---
 gdb/source-cache.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)
  

Patch

diff --git a/gdb/source-cache.c b/gdb/source-cache.c
index 7d8339a16df..f04a9d42e0d 100644
--- a/gdb/source-cache.c
+++ b/gdb/source-cache.c
@@ -37,6 +37,7 @@ 
 #include <sstream>
 #include <srchilite/sourcehighlight.h>
 #include <srchilite/langmap.h>
+#include <srchilite/highlighteventlistener.h>
 #endif
 
 #if GDB_SELF_TEST
@@ -193,6 +194,17 @@  get_language_name (enum language lang)
   return nullptr;
 }
 
+/* Class with notify function called during highlighting.  */
+
+class gdb_highlight_event_listener : public srchilite::HighlightEventListener
+{
+public:
+  void notify (const srchilite::HighlightEvent &event) override
+  {
+    QUIT;
+  }
+};
+
 #endif /* HAVE_SOURCE_HIGHLIGHT */
 
 /* Try to highlight CONTENTS from file FULLNAME in language LANG using
@@ -225,6 +237,9 @@  try_source_highlight (std::string &contents ATTRIBUTE_UNUSED,
 	{
 	  highlighter = new srchilite::SourceHighlight ("esc.outlang");
 	  highlighter->setStyleFile ("esc.style");
+
+	  static gdb_highlight_event_listener event_listener;
+	  highlighter->setHighlightEventListener (&event_listener);
 	}
 
       std::istringstream input (contents);
@@ -233,6 +248,16 @@  try_source_highlight (std::string &contents ATTRIBUTE_UNUSED,
       contents = std::move (output).str ();
       styled = true;
     }
+  catch (const gdb_exception_forced_quit &)
+    {
+      /* SIGTERM, rethrow.  */
+      throw;
+    }
+  catch (const gdb_exception_quit &)
+    {
+      /* SIGINT, rethrow.  */
+      throw;
+    }
   catch (...)
     {
       /* Source Highlight will throw an exception if
@@ -299,6 +324,51 @@  static void gnu_source_highlight_test ()
   /* Make sure there are no SIGINT or SIGTERM pending.  */
   sync_quit_force_run = false;
   check_quit_flag ();
+
+  /* Pretend user send SIGTERM.  */
+  set_force_quit_flag ();
+
+  bool saw_forced_quit = false;
+  res = false;
+  styled_prog = prog;
+  try
+    {
+      res = try_source_highlight (styled_prog, language_c, "test.c");
+    }
+  catch (const gdb_exception_forced_quit &ex)
+    {
+      saw_forced_quit = true;
+    }
+
+  SELF_CHECK (saw_forced_quit);
+  SELF_CHECK (!res);
+  SELF_CHECK (prog == styled_prog);
+
+  /* Make sure there are no SIGINT or SIGTERM pending.  */
+  sync_quit_force_run = false;
+  check_quit_flag ();
+
+  /* Pretend user send SIGINT.  */
+  set_quit_flag ();
+
+  bool saw_quit = false;
+  res = false;
+  styled_prog = prog;
+  try
+    {
+      res = try_source_highlight (styled_prog, language_c, "test.c");
+    }
+  catch (const gdb_exception_quit &ex)
+    {
+      saw_quit = true;
+    }
+  SELF_CHECK (saw_quit);
+  SELF_CHECK (!res);
+  SELF_CHECK (prog == styled_prog);
+
+  /* Make sure there are no SIGINT or SIGTERM pending.  */
+  sync_quit_force_run = false;
+  check_quit_flag ();
 }
 }
 #endif /* GDB_SELF_TEST */