]> sourceware.org Git - systemtap.git/commitdiff
Added a new mode: language server
authorRyan Goldberg <rgoldber@redhat.com>
Mon, 19 Dec 2022 22:29:48 +0000 (17:29 -0500)
committerRyan Goldberg <rgoldber@redhat.com>
Fri, 3 Feb 2023 16:08:56 +0000 (11:08 -0500)
This mode will turn the stap process into a
language server, which will use the official
language-server-protocol. It can be started
with the new --language-server flag

Makefile.am
cmdline.cxx
cmdline.h
configure.ac
main.cxx
man/stap.1.in
session.cxx
session.h

index ff59b95bb91c8c7048143466098d835399093a93..d3f3fb4ae50aa9491854bd9f140f4cc9bff135a3 100644 (file)
@@ -63,6 +63,11 @@ stap_SOURCES += interactive.cxx
 stap_LDADD += @READLINE_LIBS@
 endif
 
+if HAVE_JSON_C
+stap_SOURCES += language-server/stap-language-server.cxx language-server/stap-code-completion.cxx language-server/jsonrpc.cxx
+stap_LDADD += $(jsonc_LIBS)
+endif
+
 if HAVE_BPF_DECLS
 stap_SOURCES += bpf-base.cxx bpf-bitset.cxx bpf-translate.cxx bpf-opt.cxx
 endif
index 911e62e0feb41f9c7942def8c0d32be11f6e097d..8bee6f3ab26b73591da3790ae31edaaa532e8c9b 100644 (file)
@@ -64,5 +64,6 @@ struct option stap_long_options[] = {
   { "interactive",                 no_argument,       NULL, LONG_OPT_INTERACTIVE},
   { "example",                     no_argument,       NULL, LONG_OPT_RUN_EXAMPLE},
   { "no-global-var-display",       no_argument,       NULL, LONG_OPT_NO_GLOBAL_VAR_DISPLAY},
+  { "language-server",             no_argument,       NULL, LONG_OPT_LANGUAGE_SERVER},
   { NULL, 0, NULL, 0 }
 };
index 0ee3232d43283a3666802bdbec76c8862e515b48..c97c538a968146b4d2b65c7c140e265093ebafb3 100644 (file)
--- a/cmdline.h
+++ b/cmdline.h
@@ -68,6 +68,7 @@ enum {
   LONG_OPT_INTERACTIVE,
   LONG_OPT_RUN_EXAMPLE,
   LONG_OPT_NO_GLOBAL_VAR_DISPLAY,
+  LONG_OPT_LANGUAGE_SERVER,
 };
 
 // NB: when adding new options, consider very carefully whether they
index bd3a23868ee2136fcc842427592ab37922affcff..32e82ce554572d37e815c4e40e760b76a464c276 100644 (file)
@@ -793,8 +793,12 @@ PKG_CHECK_MODULES([ncurses], [ncurses], [have_ncurses=yes], [have_ncurses=no])
 if test "${have_jsonc}" = "yes" -a "${have_ncurses}" = yes; then
   AC_DEFINE([HAVE_MONITOR_LIBS],[1],[Define to 1 if json-c and ncurses libraries are installed])
 fi
+if test "${have_jsonc}" = "yes"; then
+  AC_DEFINE([HAVE_JSON_C],[1],[Define to 1 if the json-c library is installed])
+fi
 fi
 AM_CONDITIONAL([HAVE_MONITOR_LIBS], [test "${have_jsonc}" = "yes" -a "${have_ncurses}" = "yes" -a "$enable_monitor" != "no"])
+AM_CONDITIONAL([HAVE_JSON_C], [test "${have_jsonc}" = "yes"])
 
 AC_CACHE_CHECK([for assembler .section "?" flags support], stap_cv_sectionq, [
 old_CFLAGS="$CFLAGS"
index 53f57599c8e4198ecdb71e683cb5a5ed296af8c9..ad77fad7129295f69bc22fa262df74531904e8a1 100644 (file)
--- a/main.cxx
+++ b/main.cxx
@@ -30,6 +30,9 @@
 #ifdef HAVE_LIBREADLINE
 #include "interactive.h"
 #endif
+
+#include "language-server/stap-language-server.h"
+
 #include "bpf.h"
 
 #if ENABLE_NLS
@@ -1479,6 +1482,17 @@ main (int argc, char * const argv [])
     if (rc != 0)
       return rc;
 
+    #ifdef HAVE_JSON_C
+    if(s.language_server_mode){
+      // The language server commuinicates with the client via stdio, so the systemtap verbosity should be 0
+      // Instead the LS verbosity should be set
+      s.language_server = new language_server(&s, s.verbose);
+      s.verbose = 0;
+      for(int i = 0; i < 5; i++)
+        s.perpass_verbose[i] = 0;
+    }
+    #endif
+
     // Create the temp dir.
     s.create_tmp_dir();
 
@@ -1529,6 +1543,14 @@ main (int argc, char * const argv [])
     for (unsigned i = 0; i < targets.size(); ++i)
       sessions.insert(targets[i]->get_session());
 
+    if(s.language_server_mode){
+      #ifdef HAVE_JSON_C
+        int r = s.language_server->run();
+        delete s.language_server;
+        return r;
+      #endif
+    }
+
     // FIXME: For now, only attempt local interactive use.
     if (s.interactive_mode && fake_remote)
       {
index 61041b5423d2382bd02f8fad7382339f5ab2374b..4e1f0a537807f5b7896c1277a3e2b3895bd50c4c 100644 (file)
@@ -872,6 +872,11 @@ manual page.
 This option is used to disable the automatic logging of unused global
 variables at the end of a stap session.
 
+.TP
+.B \-\-language\-server
+Language server mode. Start a language server which will communicate via
+stdio. The language server will respect stap verbosity.
+
 .SH ARGUMENTS
 
 Any additional arguments on the command line are passed to the script
index 9b2dc188f40a88af8d84b9f12ddcbcff50114c15..138542b01254eed2b9920586563f6674c8598e45 100644 (file)
@@ -191,6 +191,8 @@ systemtap_session::systemtap_session ():
   timeout = 0;
   use_bpf_raw_tracepoint = false;
   symbol_resolver = 0;
+  language_server = 0;
+  language_server_mode = false;
 
   // PR12443: put compiled-in / -I paths in front, to be preferred during 
   // tapset duplicate-file elimination
@@ -381,6 +383,8 @@ systemtap_session::systemtap_session (const systemtap_session& other,
   no_global_var_display = other.no_global_var_display;
   pass_1a_complete = other.pass_1a_complete;
   timeout = other.timeout;
+  language_server_mode = other.language_server_mode;
+  language_server = other.language_server;
   // don't bother copy typequery_memo
 
   include_path = other.include_path;
@@ -549,6 +553,9 @@ systemtap_session::version ()
 #endif
 #ifdef HAVE_MONITOR_LIBS
        << " MONITOR_LIBS"
+#endif
+#ifdef HAVE_JSON_C
+       << " JSON_C"
 #endif
        << endl;
 }
@@ -729,6 +736,10 @@ systemtap_session::usage (int exitcode)
 #if HAVE_MONITOR_LIBS
     "   --monitor=INTERVAL\n"
     "              enables runtime interactive monitoring\n"
+#endif
+#ifdef HAVE_JSON_C
+     "   --language-server\n"
+     "              starts a systemtap language server\n"
 #endif
     , compatible.c_str()) << endl
   ;
@@ -1679,6 +1690,10 @@ systemtap_session::parse_cmdline (int argc, char * const argv [])
          no_global_var_display = true;
          break;
 
+  case LONG_OPT_LANGUAGE_SERVER:
+    language_server_mode = true;
+    break;
+
        case '?':
          // Invalid/unrecognized option given or argument required, but
          // not given. In both cases getopt_long() will have printed the
@@ -1789,10 +1804,10 @@ systemtap_session::check_options (int argc, char * const argv [])
         args.push_back (string (argv[i]));
     }
 
-  // We don't need a script with --list-servers, --trust-servers, or any dump mode
+  // We don't need a script with --list-servers, --trust-servers, or any dump mode, or a lang-server
   bool need_script = server_status_strings.empty () &&
                      server_trust_spec.empty () &&
-                     !dump_mode && !interactive_mode;
+                     !dump_mode && !interactive_mode && !language_server_mode;
 
   if (benchmark_sdt_loops > 0 || benchmark_sdt_threads > 0)
     {
@@ -1835,13 +1850,18 @@ systemtap_session::check_options (int argc, char * const argv [])
       cerr << _("Cannot specify -i with -l/-L/--dump-* switches.") << endl;
       usage(1);
     }
+  if (dump_mode && language_server_mode)
+    {
+      cerr << _("Cannot specify --language-server with -l/-L/--dump-* switches.") << endl;
+      usage(1);
+    }
   if (dump_mode && monitor)
     {
       cerr << _("Cannot specify --monitor with -l/-L/--dump-* switches.") << endl;
       usage(1);
     }
   // FIXME: we need to think through other options that shouldn't be
-  // used with '-i'.
+  // used with '-i' and '--language-server'.
 
   // ignore any -E bits in list modes; their presence could flip the
   // process result code even if list results are empty
@@ -1873,6 +1893,14 @@ systemtap_session::check_options (int argc, char * const argv [])
     }
 #endif
 
+#if ! HAVE_JSON_C
+  if (language_server_mode)
+    {
+      print_warning("Language server mode is not supported by this version of systemtap");
+      exit(1);
+    }
+#endif
+
   if (runtime_specified && ! specified_servers.empty ())
     {
       print_warning("Ignoring --use-server due to the use of -R");
index de9a47175b5b26eb7285eed42f5d8fd9ced49131..7e20b14c64a6d7605dd0c860069271586edd76d4 100644 (file)
--- a/session.h
+++ b/session.h
@@ -76,6 +76,7 @@ struct semantic_error;
 struct module_cache;
 struct update_visitor;
 struct compile_server_cache;
+class language_server;
 
 // XXX: a generalized form of this descriptor could be associated with
 // a vardecl instead of out here at the systemtap_session level.
@@ -483,6 +484,9 @@ public:
   // PR25841, for early probe-derivation-time symbol resolution
   symresolution_info* symbol_resolver; // may be NULL
   
+  bool language_server_mode;
+  class language_server* language_server;
+
   // NB: It is very important for all of the above (and below) fields
   // to be cleared in the systemtap_session ctor (session.cxx).
 
This page took 0.042143 seconds and 5 git commands to generate.