Skip to content

Commit 11a046b

Browse files
committedJul 20, 2015
Add initial "interactive mode" support.
* interactive.cxx: New file. * interactive.h: Ditto. * session.h: Add 2 new variables to the systemtap_session class - 'interactive_mode' and 'pass_1a_complete'. Also add a function declaration for 'clear_script_data()'. * session.cxx (systemtap_session::systemtap_session): Initialize new variables. (systemtap_session::usage): Add '-i' description. (systemtap_session::parse_cmdline): Add interactive mode support. (systemtap_session::clear_script_data): New function. * main.cxx (main): Call 'interactive_mode' when the user specifies '-i'. * elaborate.cxx (semantic_pass): Add note about changes needed. * cmdline.h: Add '-i' option. * Makefile.am: Add interactive.cxx and readline/ncurses libraries. * Makefile.in: Regenerated.
1 parent 4dde890 commit 11a046b

9 files changed

+352
-41
lines changed
 

‎Makefile.am

+3-2
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,10 @@ stap_SOURCES = main.cxx session.cxx \
4949
setupdwfl.cxx remote.cxx privilege.cxx cmdline.cxx \
5050
tapset-dynprobe.cxx tapset-method.cxx translator-output.cxx
5151
stap_SOURCES += stapregex.cxx stapregex-tree.cxx stapregex-parse.cxx \
52-
stapregex-dfa.cxx
52+
stapregex-dfa.cxx interactive.cxx
5353
noinst_HEADERS = sdt_types.h
54-
stap_LDADD = @stap_LIBS@ @sqlite3_LIBS@ @LIBINTL@ -lpthread
54+
# FIXME: We'll need some configure changes to check for readline/ncurses.
55+
stap_LDADD = @stap_LIBS@ @sqlite3_LIBS@ @LIBINTL@ -lpthread -lreadline -lncurses
5556
stap_DEPENDENCIES =
5657

5758
if BUILD_VIRT

‎Makefile.in

+22-2
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ loc2c_test_LINK = $(CCLD) $(loc2c_test_CFLAGS) $(CFLAGS) \
212212
@BUILD_TRANSLATOR_TRUE@ stap-stapregex-tree.$(OBJEXT) \
213213
@BUILD_TRANSLATOR_TRUE@ stap-stapregex-parse.$(OBJEXT) \
214214
@BUILD_TRANSLATOR_TRUE@ stap-stapregex-dfa.$(OBJEXT) \
215+
@BUILD_TRANSLATOR_TRUE@ stap-interactive.$(OBJEXT) \
215216
@BUILD_TRANSLATOR_TRUE@ $(am__objects_1)
216217
stap_OBJECTS = $(am_stap_OBJECTS)
217218
stap_LINK = $(CXXLD) $(stap_CXXFLAGS) $(CXXFLAGS) $(stap_LDFLAGS) \
@@ -525,6 +526,7 @@ pdfdir = @pdfdir@
525526
prefix = @prefix@
526527
program_transform_name = @program_transform_name@
527528
psdir = @psdir@
529+
python = @python@
528530
sbindir = @sbindir@
529531
selinux_CFLAGS = @selinux_CFLAGS@
530532
selinux_LIBS = @selinux_LIBS@
@@ -575,10 +577,13 @@ oldinclude_HEADERS = includes/sys/sdt.h includes/sys/sdt-config.h
575577
@BUILD_TRANSLATOR_TRUE@ tapset-dynprobe.cxx tapset-method.cxx \
576578
@BUILD_TRANSLATOR_TRUE@ translator-output.cxx stapregex.cxx \
577579
@BUILD_TRANSLATOR_TRUE@ stapregex-tree.cxx stapregex-parse.cxx \
578-
@BUILD_TRANSLATOR_TRUE@ stapregex-dfa.cxx $(am__append_11)
580+
@BUILD_TRANSLATOR_TRUE@ stapregex-dfa.cxx interactive.cxx \
581+
@BUILD_TRANSLATOR_TRUE@ $(am__append_11)
579582
@BUILD_TRANSLATOR_TRUE@noinst_HEADERS = sdt_types.h
583+
# FIXME: We'll need some configure changes to check for readline/ncurses.
580584
@BUILD_TRANSLATOR_TRUE@stap_LDADD = @stap_LIBS@ @sqlite3_LIBS@ \
581-
@BUILD_TRANSLATOR_TRUE@ @LIBINTL@ -lpthread $(am__append_10) \
585+
@BUILD_TRANSLATOR_TRUE@ @LIBINTL@ -lpthread -lreadline \
586+
@BUILD_TRANSLATOR_TRUE@ -lncurses $(am__append_10) \
582587
@BUILD_TRANSLATOR_TRUE@ $(am__append_15)
583588
@BUILD_TRANSLATOR_TRUE@stap_DEPENDENCIES = $(am__append_21)
584589
@BUILD_TRANSLATOR_TRUE@@BUILD_VIRT_TRUE@stapvirt_SOURCES = stapvirt.c
@@ -945,6 +950,7 @@ distclean-compile:
945950
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-dwflpp.Po@am__quote@
946951
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-elaborate.Po@am__quote@
947952
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-hash.Po@am__quote@
953+
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-interactive.Po@am__quote@
948954
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-loc2c.Po@am__quote@
949955
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-main.Po@am__quote@
950956
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-mdfour.Po@am__quote@
@@ -1580,6 +1586,20 @@ stap-stapregex-dfa.obj: stapregex-dfa.cxx
15801586
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
15811587
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CXXFLAGS) $(CXXFLAGS) -c -o stap-stapregex-dfa.obj `if test -f 'stapregex-dfa.cxx'; then $(CYGPATH_W) 'stapregex-dfa.cxx'; else $(CYGPATH_W) '$(srcdir)/stapregex-dfa.cxx'; fi`
15821588

1589+
stap-interactive.o: interactive.cxx
1590+
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CXXFLAGS) $(CXXFLAGS) -MT stap-interactive.o -MD -MP -MF $(DEPDIR)/stap-interactive.Tpo -c -o stap-interactive.o `test -f 'interactive.cxx' || echo '$(srcdir)/'`interactive.cxx
1591+
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/stap-interactive.Tpo $(DEPDIR)/stap-interactive.Po
1592+
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='interactive.cxx' object='stap-interactive.o' libtool=no @AMDEPBACKSLASH@
1593+
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
1594+
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CXXFLAGS) $(CXXFLAGS) -c -o stap-interactive.o `test -f 'interactive.cxx' || echo '$(srcdir)/'`interactive.cxx
1595+
1596+
stap-interactive.obj: interactive.cxx
1597+
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CXXFLAGS) $(CXXFLAGS) -MT stap-interactive.obj -MD -MP -MF $(DEPDIR)/stap-interactive.Tpo -c -o stap-interactive.obj `if test -f 'interactive.cxx'; then $(CYGPATH_W) 'interactive.cxx'; else $(CYGPATH_W) '$(srcdir)/interactive.cxx'; fi`
1598+
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/stap-interactive.Tpo $(DEPDIR)/stap-interactive.Po
1599+
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='interactive.cxx' object='stap-interactive.obj' libtool=no @AMDEPBACKSLASH@
1600+
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
1601+
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CXXFLAGS) $(CXXFLAGS) -c -o stap-interactive.obj `if test -f 'interactive.cxx'; then $(CYGPATH_W) 'interactive.cxx'; else $(CYGPATH_W) '$(srcdir)/interactive.cxx'; fi`
1602+
15831603
stap-nsscommon.o: nsscommon.cxx
15841604
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CXXFLAGS) $(CXXFLAGS) -MT stap-nsscommon.o -MD -MP -MF $(DEPDIR)/stap-nsscommon.Tpo -c -o stap-nsscommon.o `test -f 'nsscommon.cxx' || echo '$(srcdir)/'`nsscommon.cxx
15851605
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/stap-nsscommon.Tpo $(DEPDIR)/stap-nsscommon.Po

‎cmdline.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ enum {
6565

6666
// NB: when adding new options, consider very carefully whether they
6767
// should be restricted from stap clients (after --client-options)!
68-
#define STAP_SHORT_OPTIONS "hVvtp:I:e:E:o:R:r:a:m:kgPc:x:D:bs:uqwl:d:L:FS:B:J:jWG:"
68+
#define STAP_SHORT_OPTIONS "hVvtp:I:e:E:o:R:r:a:m:kgPc:x:D:bs:uqiwl:d:L:FS:B:J:jWG:"
6969

7070
#define OWE5 "tter"
7171
#define OWE1 "uild-"

‎elaborate.cxx

+4
Original file line numberDiff line numberDiff line change
@@ -2015,6 +2015,10 @@ semantic_pass (systemtap_session& s)
20152015

20162016
try
20172017
{
2018+
// FIXME: interactive mode, register_library_aliases handles
2019+
// both aliases from library files *and* user scripts. It would
2020+
// be nice to have them in separate lists and register them
2021+
// separately.
20182022
s.register_library_aliases();
20192023
register_standard_tapsets(s);
20202024

‎interactive.cxx

+182
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
// systemtap interactive mode
2+
// Copyright (C) 2015 Red Hat Inc.
3+
//
4+
// This file is part of systemtap, and is free software. You can
5+
// redistribute it and/or modify it under the terms of the GNU General
6+
// Public License (GPL); either version 2, or (at your option) any
7+
// later version.
8+
9+
#include "config.h"
10+
#include "interactive.h"
11+
#include "session.h"
12+
#include "util.h"
13+
14+
#include "stap-probe.h"
15+
16+
#include <cstdlib>
17+
18+
using namespace std;
19+
20+
extern "C" {
21+
#include <unistd.h>
22+
#include <stdlib.h>
23+
#include <readline/readline.h>
24+
#include <readline/history.h>
25+
}
26+
27+
// FIXME: these declarations don't really belong here.
28+
extern int
29+
passes_0_4 (systemtap_session &s);
30+
extern int
31+
pass_5 (systemtap_session &s, vector<remote*> targets);
32+
33+
static void
34+
interactive_cmds ()
35+
{
36+
cout << endl
37+
<< "List of commands:\n\n"
38+
<< "!help -- Print this command list\n"
39+
<< "!set OPTION VALUE -- Set option value. Supported options are\n"
40+
<< " 'keep_tmpdir', 'last_pass' and 'verbose'.\n"
41+
<< "!show OPTION -- Show option value.\n"
42+
<< "!quit -- Exit systemtap\n";
43+
}
44+
45+
// FIXME: this isn't very elegant, and will quickly become longer and
46+
// longer with more supported options. However, for now...
47+
static void
48+
handle_setshow_cmd (systemtap_session &s, vector<string> &tokens)
49+
{
50+
bool set = (tokens[0] == "!set");
51+
52+
if ((set && tokens.size() != 3) || (!set && tokens.size() != 2))
53+
{
54+
cout << endl
55+
<< "Invalid command\n";
56+
interactive_cmds();
57+
return;
58+
}
59+
60+
if (tokens[1] == "keep_tmpdir")
61+
{
62+
if (set)
63+
s.keep_tmpdir = (tokens[2] != "0");
64+
else
65+
cout << "keep_tmpdir: " << s.keep_tmpdir << endl;
66+
}
67+
else if (tokens[1] == "last_pass")
68+
{
69+
if (set)
70+
{
71+
char *end;
72+
long val;
73+
74+
errno = 0;
75+
val = strtol (tokens[2].c_str(), &end, 10);
76+
if (errno != 0 || *end != '\0' || val < 1 || val > 5)
77+
cout << endl
78+
<< "Invalid option value (should be 1-5)\n";
79+
else
80+
s.last_pass = val;
81+
}
82+
else
83+
cout << "last_pass: " << s.last_pass << endl;
84+
}
85+
else if (tokens[1] == "verbose")
86+
{
87+
if (set)
88+
{
89+
char *end;
90+
long val;
91+
92+
errno = 0;
93+
val = strtol (tokens[2].c_str(), &end, 10);
94+
if (errno != 0 || *end != '\0' || val < 0)
95+
cout << endl
96+
<< "Invalid option value (should be greater than 0)\n";
97+
else
98+
{
99+
s.verbose = val;
100+
for (unsigned i=0; i<5; i++)
101+
s.perpass_verbose[i] = val;
102+
}
103+
}
104+
else
105+
cout << "verbose: " << s.verbose << endl;
106+
}
107+
else
108+
{
109+
cout << endl
110+
<< "Invalid option name\n";
111+
interactive_cmds();
112+
}
113+
return;
114+
}
115+
116+
// Interactive mode, passes 0 through 5 and back again.
117+
int
118+
interactive_mode (systemtap_session &s, vector<remote*> targets)
119+
{
120+
int rc;
121+
string delimiters = " \t";
122+
bool input_handled;
123+
124+
while (1)
125+
{
126+
char *line_tmp = readline("stap> ");
127+
if (line_tmp && *line_tmp)
128+
add_history(line_tmp);
129+
else
130+
continue;
131+
132+
string line = string(line_tmp);
133+
free(line_tmp);
134+
135+
vector<string> tokens;
136+
tokenize(line, tokens, delimiters);
137+
138+
input_handled = false;
139+
if (tokens.size())
140+
{
141+
if (tokens[0] == "!quit")
142+
{
143+
input_handled = true;
144+
break;
145+
}
146+
else if (tokens[0] == "!help")
147+
{
148+
input_handled = true;
149+
interactive_cmds();
150+
}
151+
else if (tokens[0] == "!set" || tokens[0] == "!show")
152+
{
153+
input_handled = true;
154+
handle_setshow_cmd(s, tokens);
155+
}
156+
}
157+
158+
// If it isn't a command, we assume it is a script to run.
159+
//
160+
// FIXME: Later this could be a line from a script that we have
161+
// to keep track of.
162+
if (!input_handled)
163+
{
164+
// Try creating a new systemtap session object so that we
165+
// don't get leftovers from the last script we compiled.
166+
systemtap_session* ss = s.clone(s.architecture, s.kernel_release);
167+
clog << "orig tmpdir: " << s.tmpdir
168+
<< ", new tmpdir: " << ss->tmpdir << endl;
169+
170+
ss->clear_script_data();
171+
ss->cmdline_script = line;
172+
ss->have_script = true;
173+
rc = passes_0_4(*ss);
174+
175+
// Run pass 5, if passes 0-4 worked.
176+
if (rc == 0 && ss->last_pass >= 5 && !pending_interrupts)
177+
rc = pass_5 (*ss, targets);
178+
ss->reset_tmp_dir();
179+
}
180+
}
181+
return 0;
182+
}

‎interactive.h

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Interactive mode header.
2+
// Copyright (C) 2015 Red Hat Inc.
3+
//
4+
// This file is part of systemtap, and is free software. You can
5+
// redistribute it and/or modify it under the terms of the GNU General
6+
// Public License (GPL); either version 2, or (at your option) any
7+
// later version.
8+
9+
#ifndef INTERACTIVE_H
10+
#define INTERACTIVE_H
11+
12+
#include <vector>
13+
14+
#include "session.h"
15+
#include "remote.h"
16+
17+
extern int interactive_mode (systemtap_session &s, std::vector<remote*> targets);
18+
19+
#endif

0 commit comments

Comments
 (0)