summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfche <fche>2008-02-28 21:34:46 +0000
committerfche <fche>2008-02-28 21:34:46 +0000
commit49abf162fa91397b0c65d41f5c9af31ace4e6290 (patch)
tree45fe654102d6db99e627fe04f7cbfd78e9db12e1
parent7e6c2d0bd81af35151167ca75fc1b7d20a9e9a7d (diff)
downloadsystemtap-steved-49abf162fa91397b0c65d41f5c9af31ace4e6290.tar.gz
systemtap-steved-49abf162fa91397b0c65d41f5c9af31ace4e6290.tar.xz
systemtap-steved-49abf162fa91397b0c65d41f5c9af31ace4e6290.zip
PR5045: clean up after interrupts
2008-02-28 Frank Ch. Eigler <fche@elastic.org> PR5045 * session.h (pending_interrupts): New global. * main.cxx (handle_interrupts): New fn to handle SIGINT* etc. * elaborate.cxx, translate.cxx, tapsets.cxx, main.cxx (*): Insert pending_interrupts escape hatches inside potentially timetaking loops. * buildrun.cxx: Don't deal with signals.
-rw-r--r--ChangeLog9
-rw-r--r--buildrun.cxx5
-rw-r--r--elaborate.cxx17
-rw-r--r--main.cxx47
-rw-r--r--session.h3
-rw-r--r--tapsets.cxx6
-rw-r--r--translate.cxx11
7 files changed, 82 insertions, 16 deletions
diff --git a/ChangeLog b/ChangeLog
index 8be45cfc..ecfe4269 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2008-02-28 Frank Ch. Eigler <fche@elastic.org>
+
+ PR5045
+ * session.h (pending_interrupts): New global.
+ * main.cxx (handle_interrupts): New fn to handle SIGINT* etc.
+ * elaborate.cxx, translate.cxx, tapsets.cxx, main.cxx (*): Insert
+ pending_interrupts escape hatches inside potentially timetaking loops.
+ * buildrun.cxx: Don't deal with signals.
+
2008-02-27 Frank Ch. Eigler <fche@elastic.org>
PR5697
diff --git a/buildrun.cxx b/buildrun.cxx
index 67836108..f3f29d49 100644
--- a/buildrun.cxx
+++ b/buildrun.cxx
@@ -16,7 +16,7 @@
#include <sstream>
extern "C" {
-#include "signal.h"
+#include <signal.h>
#include <sys/wait.h>
#include <pwd.h>
#include <sys/types.h>
@@ -269,9 +269,6 @@ run_pass (systemtap_session& s)
if (s.verbose>1) clog << "Running " << staprun_cmd << endl;
- signal (SIGHUP, SIG_IGN);
- signal (SIGINT, SIG_IGN);
rc = system (staprun_cmd.c_str ());
-
return rc;
}
diff --git a/elaborate.cxx b/elaborate.cxx
index 7f4ccf35..75714102 100644
--- a/elaborate.cxx
+++ b/elaborate.cxx
@@ -344,6 +344,8 @@ match_node::find_and_build (systemtap_session& s,
const match_key& subkey = i->first;
match_node* subnode = i->second;
+ if (pending_interrupts) break;
+
if (match.globmatch(subkey))
{
if (s.verbose > 2)
@@ -627,6 +629,8 @@ derive_probes (systemtap_session& s,
{
for (unsigned i = 0; i < p->locations.size(); ++i)
{
+ if (pending_interrupts) break;
+
probe_point *loc = p->locations[i];
try
@@ -1070,6 +1074,7 @@ semantic_pass_symbols (systemtap_session& s)
s.files.push_back (s.user_file);
for (unsigned i = 0; i < s.files.size(); i++)
{
+ if (pending_interrupts) break;
stapfile* dome = s.files[i];
// Pass 1: add globals and functions to systemtap-session master list,
@@ -1088,6 +1093,7 @@ semantic_pass_symbols (systemtap_session& s)
for (unsigned i=0; i<dome->functions.size(); i++)
{
+ if (pending_interrupts) break;
functiondecl* fd = dome->functions[i];
try
@@ -1107,6 +1113,7 @@ semantic_pass_symbols (systemtap_session& s)
for (unsigned i=0; i<dome->probes.size(); i++)
{
+ if (pending_interrupts) break;
probe* p = dome->probes [i];
vector<derived_probe*> dps;
@@ -1116,6 +1123,7 @@ semantic_pass_symbols (systemtap_session& s)
for (unsigned j=0; j<dps.size(); j++)
{
+ if (pending_interrupts) break;
derived_probe* dp = dps[j];
s.probes.push_back (dp);
dp->join_group (s);
@@ -2025,6 +2033,8 @@ semantic_pass_optimize1 (systemtap_session& s)
bool relaxed_p = false;
while (! relaxed_p)
{
+ if (pending_interrupts) break;
+
relaxed_p = true; // until proven otherwise
semantic_pass_opt1 (s, relaxed_p);
@@ -2052,6 +2062,7 @@ semantic_pass_optimize2 (systemtap_session& s)
bool relaxed_p = false;
while (! relaxed_p)
{
+ if (pending_interrupts) break;
relaxed_p = true; // until proven otherwise
semantic_pass_opt5 (s, relaxed_p);
@@ -2082,12 +2093,16 @@ semantic_pass_types (systemtap_session& s)
// XXX: maybe convert to exception-based error signalling
while (1)
{
+ if (pending_interrupts) break;
+
iterations ++;
ti.num_newly_resolved = 0;
ti.num_still_unresolved = 0;
for (unsigned j=0; j<s.functions.size(); j++)
{
+ if (pending_interrupts) break;
+
functiondecl* fn = s.functions[j];
ti.current_probe = 0;
ti.current_function = fn;
@@ -2103,6 +2118,8 @@ semantic_pass_types (systemtap_session& s)
for (unsigned j=0; j<s.probes.size(); j++)
{
+ if (pending_interrupts) break;
+
derived_probe* pn = s.probes[j];
ti.current_function = 0;
ti.current_probe = pn;
diff --git a/main.cxx b/main.cxx
index 668c14b8..449c1a2a 100644
--- a/main.cxx
+++ b/main.cxx
@@ -29,6 +29,7 @@
extern "C" {
#include <glob.h>
#include <unistd.h>
+#include <signal.h>
#include <sys/utsname.h>
#include <sys/times.h>
#include <sys/time.h>
@@ -185,6 +186,23 @@ printscript(systemtap_session& s, ostream& o)
}
}
+
+int pending_interrupts;
+
+extern "C"
+void handle_interrupt (int /* sig */)
+{
+ pending_interrupts ++;
+ if (pending_interrupts > 1) // XXX: should be configurable? time-based?
+ {
+ char msg[] = "Too many interrupts received, exiting.\n";
+ int rc = write (2, msg, sizeof(msg)-1);
+ if (rc) /* Do nothing; we don't care if our last gasp went out. */ ;
+ _exit (1);
+ }
+}
+
+
int
main (int argc, char * const argv [])
{
@@ -541,6 +559,13 @@ main (int argc, char * const argv [])
// directory.
s.translated_source = string(s.tmpdir) + "/" + s.module_name + ".c";
+ // Set up our handler to catch routine signals, to allow clean
+ // and reasonably timely exit.
+ signal (SIGHUP, handle_interrupt);
+ signal (SIGPIPE, handle_interrupt);
+ signal (SIGINT, handle_interrupt);
+ signal (SIGTERM, handle_interrupt);
+
struct tms tms_before;
times (& tms_before);
struct timeval tv_before;
@@ -616,8 +641,10 @@ main (int argc, char * const argv [])
for (unsigned j=0; j<globbuf.gl_pathc; j++)
{
- // privilege only for /usr/share/systemtap?
-
+ if (pending_interrupts)
+ break;
+
+ // XXX: privilege only for /usr/share/systemtap?
stapfile* f = parser::parse (s, globbuf.gl_pathv[j], true);
if (f == 0)
rc ++;
@@ -683,7 +710,7 @@ main (int argc, char * const argv [])
<< "Try again with more '-v' (verbose) options."
<< endl;
- if (rc || s.last_pass == 1) goto cleanup;
+ if (rc || s.last_pass == 1 || pending_interrupts) goto cleanup;
times (& tms_before);
gettimeofday (&tv_before, NULL);
@@ -733,14 +760,14 @@ main (int argc, char * const argv [])
{
// If our last pass isn't 5, we're done (since passes 3 and
// 4 just generate what we just pulled out of the cache).
- if (s.last_pass < 5) goto cleanup;
+ if (s.last_pass < 5 || pending_interrupts) goto cleanup;
// Short-circuit to pass 5.
goto pass_5;
}
}
- if (rc || s.last_pass == 2) goto cleanup;
+ if (rc || s.last_pass == 2 || pending_interrupts) goto cleanup;
// PASS 3: TRANSLATION
@@ -769,7 +796,7 @@ main (int argc, char * const argv [])
<< "Try again with more '-v' (verbose) options."
<< endl;
- if (rc || s.last_pass == 3) goto cleanup;
+ if (rc || s.last_pass == 3 || pending_interrupts) goto cleanup;
// PASS 4: COMPILATION
times (& tms_before);
@@ -799,7 +826,7 @@ main (int argc, char * const argv [])
add_to_cache(s);
// Copy module to the current directory.
- if (save_module)
+ if (save_module && !pending_interrupts)
{
string module_src_path = s.tmpdir + "/" + s.module_name + ".ko";
string module_dest_path = s.module_name + ".ko";
@@ -813,7 +840,7 @@ main (int argc, char * const argv [])
}
}
- if (rc || s.last_pass == 4) goto cleanup;
+ if (rc || s.last_pass == 4 || pending_interrupts) goto cleanup;
// PASS 5: RUN
@@ -841,7 +868,7 @@ pass_5:
cleanup:
// update the database information
- if (!rc && s.tapset_compile_coverage) {
+ if (!rc && s.tapset_compile_coverage && !pending_interrupts) {
#ifdef HAVE_LIBSQLITE3
update_coverage_db(s);
#else
@@ -867,5 +894,5 @@ pass_5:
}
}
- return rc ? EXIT_FAILURE : EXIT_SUCCESS;
+ return (rc||pending_interrupts) ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/session.h b/session.h
index e2d7cd4f..b06d9ecc 100644
--- a/session.h
+++ b/session.h
@@ -160,4 +160,7 @@ struct systemtap_session
};
+// global counter of SIGINT/SIGTERM's received
+extern int pending_interrupts;
+
#endif // SESSION_H
diff --git a/tapsets.cxx b/tapsets.cxx
index c5ed6ea1..52c14024 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -827,6 +827,7 @@ struct dwflpp
ptrdiff_t off = 0;
do
{
+ if (pending_interrupts) return;
off = dwfl_getmodules (dwfl, module_caching_callback,
& module_cache, off);
}
@@ -837,6 +838,7 @@ struct dwflpp
// Traverse the cache.
for (unsigned i = 0; i < module_cache.size(); i++)
{
+ if (pending_interrupts) return;
module_cache_entry& it = module_cache[i];
int rc = callback (it.mod, 0, it.name, it.addr, data);
if (rc != DWARF_CB_OK) break;
@@ -868,6 +870,7 @@ struct dwflpp
Dwarf_Off noff;
while (dwarf_nextcu (dw, off, &noff, &cuhl, NULL, NULL, NULL) == 0)
{
+ if (pending_interrupts) return;
Dwarf_Die die_mem;
Dwarf_Die *die;
die = dwarf_offdie (dw, off + cuhl, &die_mem);
@@ -878,6 +881,7 @@ struct dwflpp
for (unsigned i = 0; i < v->size(); i++)
{
+ if (pending_interrupts) return;
Dwarf_Die die = v->at(i);
int rc = (*callback)(& die, data);
if (rc != DWARF_CB_OK) break;
@@ -1057,6 +1061,7 @@ struct dwflpp
{
for (size_t i = 0; i < nsrcs; ++i)
{
+ if (pending_interrupts) return;
if (srcsp [i]) // skip over mismatched lines
callback (srcsp[i], data);
}
@@ -3012,6 +3017,7 @@ static int
query_cu (Dwarf_Die * cudie, void * arg)
{
dwarf_query * q = static_cast<dwarf_query *>(arg);
+ if (pending_interrupts) return DWARF_CB_ABORT;
try
{
diff --git a/translate.cxx b/translate.cxx
index fefb0c8f..855a8e93 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -4471,18 +4471,21 @@ translate_pass (systemtap_session& s)
s.op->newline(1);
for (unsigned i=0; i<s.globals.size(); i++)
{
+ if (pending_interrupts) return 1;
s.up->emit_global_init (s.globals[i]);
}
s.op->newline(-1) << "};";
for (unsigned i=0; i<s.functions.size(); i++)
{
+ if (pending_interrupts) return 1;
s.op->newline();
s.up->emit_functionsig (s.functions[i]);
}
for (unsigned i=0; i<s.functions.size(); i++)
{
+ if (pending_interrupts) return 1;
s.op->newline();
s.up->emit_function (s.functions[i]);
}
@@ -4492,12 +4495,16 @@ translate_pass (systemtap_session& s)
// emit_locks()/emit_unlocks().
for (unsigned i=0; i<s.probes.size(); i++)
{
- if (s.probes[i]->needs_global_locks())
+ if (pending_interrupts) return 1;
+ if (s.probes[i]->needs_global_locks())
s.probes[i]->body->visit (&cup.vcv_needs_global_locks);
}
for (unsigned i=0; i<s.probes.size(); i++)
- s.up->emit_probe (s.probes[i]);
+ {
+ if (pending_interrupts) return 1;
+ s.up->emit_probe (s.probes[i]);
+ }
s.op->newline();
s.up->emit_module_init ();