From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 32584 invoked by alias); 18 Aug 2006 19:29:59 -0000 Received: (qmail 32559 invoked by uid 22791); 18 Aug 2006 19:29:55 -0000 X-Spam-Status: No, hits=-1.7 required=5.0 tests=AWL,BAYES_50,SPF_HELO_PASS,SPF_PASS,TW_DW X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 18 Aug 2006 19:29:50 +0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.11.20060308/8.12.11) with ESMTP id k7IJTmFn014570 for ; Fri, 18 Aug 2006 15:29:48 -0400 Received: from pobox.hsv.redhat.com (pobox.hsv.redhat.com [172.16.16.12]) by int-mx1.corp.redhat.com (8.12.11.20060308/8.12.11) with ESMTP id k7IJTmn5005176; Fri, 18 Aug 2006 15:29:48 -0400 Received: from dhcp-2.hsv.redhat.com (dhcp-2.hsv.redhat.com [172.16.17.2]) by pobox.hsv.redhat.com (8.12.8/8.12.8) with ESMTP id k7IJTljs014200; Fri, 18 Aug 2006 15:29:47 -0400 Subject: Re: [Bug translator/2421] translator emitting duplicate probe handlers From: David Smith To: "Frank Ch. Eigler" Cc: Systemtap List In-Reply-To: References: <20060306140007.2421.fche@redhat.com> <20060810191939.6964.qmail@sourceware.org> Content-Type: multipart/mixed; boundary="=-ENlX0iXob+lkVW6zstbk" Date: Fri, 18 Aug 2006 19:29:00 -0000 Message-Id: <1155929243.6167.44.camel@dhcp-2.hsv.redhat.com> Mime-Version: 1.0 X-Mailer: Evolution 2.0.2 (2.0.2-27.rhel4.6) X-Virus-Checked: Checked by ClamAV on sourceware.org X-IsSubscribed: yes Mailing-List: contact systemtap-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Post: List-Help: , Sender: systemtap-owner@sourceware.org X-SW-Source: 2006-q3/txt/msg00354.txt.bz2 --=-ENlX0iXob+lkVW6zstbk Content-Type: text/plain Content-Transfer-Encoding: 7bit Content-length: 2924 On Thu, 2006-08-10 at 16:18 -0400, Frank Ch. Eigler wrote: > Hi - > > With this code now in, it will be time for the next step of > duplication elimination. I hope this will make it clear why I talked > dsmith out of the earlier amazing "48k" variant mentioned in > http://sourceware.org/ml/systemtap/2006-q3/msg00208.html. > > The next idea is to extend the translator guts to group all probes > using the same lower level kernel API (kprobes / kretprobes / perfmon > / any others) together. Importantly, this grouping would *not* be > based on any similarity amongst probe handler bodies, only the probe > points! The goal of this method is to give a new layer of translator > code the chance to emit a single combined registration, > unregistration, and callback function *for each group as a whole*. (I > have some C++ implementation ideas on this for the person who wants to > undertake the work.) > > Among other things, this sort of grouping is required for perfmon. > When/if the kprobes API allows mass registration/unregistration, this > will readily exploit it. (It is a shame that the modules_get_byname() > code was boo'd by essentially one ignorant critic, since by > sorting/grouping all kprobes in the translator, we could most > efficiently perform the necessary relocation / locking and still > retain full generality.) > > In any case, the result should be the elimination of even more > duplication compared to the "48k" variant. It should approximate the > conceptual minimum amount of code required for the probe<->kernel > glue. Finally, if it is still economical to do so, some effort may be > directed toward improving the code for ordinary > statements/expressions. Then we will be "done". Here's a patch that provides the first level of probe grouping support. This patch just contains structural changes to support probe grouping. None of the actual probe emitting logic has changed - that's the next step. Here's a basic description of what's going on here. There is a new base class called 'derived_probe_group'. It is designed to contain 1 type of derived probe: be_derived_probe, dwarf_derived_probe, etc. One derived class of derived_probe_group is 'derived_probe_group_collection'. This is the object that contains all the other probe groups. As each probe gets created, it calls register_probe(), which eventually makes it back to the systemtap_session.probes member variable, which is now an instance of a derived_probe_group_container. The new probe gets added to the appropriate derived_probe_group based on its type. My next step will be to start modifying the probe emit logic to combine 1 registration/de-registration/callback function per group. This patch is bigger than I would like, so any good ideas on how to improve it would be appreciated. -- David Smith dsmith@redhat.com Red Hat, Inc. http://www.redhat.com 256.217.0141 (direct) 256.837.0057 (fax) --=-ENlX0iXob+lkVW6zstbk Content-Disposition: attachment; filename=probe_group.patch Content-Type: text/x-patch; name=probe_group.patch; charset=utf-8 Content-Transfer-Encoding: 7bit Content-length: 22412 Index: buildrun.cxx =================================================================== RCS file: /cvs/systemtap/src/buildrun.cxx,v retrieving revision 1.24 diff -u -p -r1.24 buildrun.cxx --- buildrun.cxx 30 Jun 2006 18:24:43 -0000 1.24 +++ buildrun.cxx 18 Aug 2006 19:18:45 -0000 @@ -8,6 +8,7 @@ #include "config.h" #include "buildrun.h" +#include "session.h" #include #include Index: elaborate.cxx =================================================================== RCS file: /cvs/systemtap/src/elaborate.cxx,v retrieving revision 1.64 diff -u -p -r1.64 elaborate.cxx --- elaborate.cxx 14 Aug 2006 21:09:21 -0000 1.64 +++ elaborate.cxx 18 Aug 2006 19:18:45 -0000 @@ -10,6 +10,7 @@ #include "elaborate.h" #include "parse.h" #include "tapsets.h" +#include "session.h" extern "C" { #include @@ -70,6 +71,58 @@ derived_probe::derived_probe (probe *p, // ------------------------------------------------------------------------ +// Members of derived_probe_group + +void +derived_probe_group::register_probe(be_derived_probe* p) +{ + throw semantic_error ("unexpected registration of a be_derived_probe"); +} + + +void +derived_probe_group::register_probe(dwarf_derived_probe* p) +{ + throw semantic_error ("unexpected registration of a dwarf_derived_probe"); +} + + +void +derived_probe_group::register_probe(hrtimer_derived_probe* p) +{ + throw semantic_error ("unexpected registration of a hrtimer_derived_probe"); +} + + +void +derived_probe_group::register_probe(mark_derived_probe* p) +{ + throw semantic_error ("unexpected registration of a mark_derived_probe"); +} + + +void +derived_probe_group::register_probe(never_derived_probe* p) +{ + throw semantic_error ("unexpected registration of a never_derived_probe"); +} + + +void +derived_probe_group::register_probe(profile_derived_probe* p) +{ + throw semantic_error ("unexpected registration of a profile_derived_probe"); +} + + +void +derived_probe_group::register_probe(timer_derived_probe* p) +{ + throw semantic_error ("unexpected registration of a timer_derived_probe"); +} + + +// ------------------------------------------------------------------------ // Members of derived_probe_builder bool @@ -330,6 +383,8 @@ struct alias_derived_probe: public deriv { alias_derived_probe (probe* base): derived_probe (base) {} + void register_probe (systemtap_session& s) { } + // alias probes should be ultimately expanded to other derived_probe // types, and not themselves emitted. void emit_registrations (translator_output* o) { throw semantic_error ("inappropriate", this->tok); } @@ -882,7 +937,7 @@ semantic_pass_symbols (systemtap_session for (unsigned j=0; jregister_probe (s); try { Index: elaborate.h =================================================================== RCS file: /cvs/systemtap/src/elaborate.h,v retrieving revision 1.31 diff -u -p -r1.31 elaborate.h --- elaborate.h 2 Jun 2006 23:13:38 -0000 1.31 +++ elaborate.h 18 Aug 2006 19:18:45 -0000 @@ -9,7 +9,6 @@ #ifndef ELABORATE_H #define ELABORATE_H -#include "session.h" #include "staptree.h" #include "parse.h" #include @@ -116,6 +115,8 @@ struct derived_probe: public probe virtual ~derived_probe () {} + virtual void register_probe (systemtap_session& s) = 0; + virtual void emit_registrations (translator_output* o) = 0; // (from within module_init): // rc = ..... register_or_whatever (ENTRYFN); @@ -148,6 +149,33 @@ public: // ------------------------------------------------------------------------ +struct be_derived_probe; +struct dwarf_derived_probe; +struct hrtimer_derived_probe; +struct mark_derived_probe; +struct never_derived_probe; +struct profile_derived_probe; +struct timer_derived_probe; +struct unparser; + +struct derived_probe_group +{ + virtual ~derived_probe_group () {} + + virtual void register_probe(be_derived_probe* p); + virtual void register_probe(dwarf_derived_probe* p); + virtual void register_probe(hrtimer_derived_probe* p); + virtual void register_probe(mark_derived_probe* p); + virtual void register_probe(never_derived_probe* p); + virtual void register_probe(profile_derived_probe* p); + virtual void register_probe(timer_derived_probe* p); + virtual size_t size () = 0; + + virtual void emit_probes (translator_output* op, unparser* up) = 0; +}; + +// ------------------------------------------------------------------------ + struct derived_probe_builder { virtual void build(systemtap_session & sess, @@ -218,4 +246,37 @@ void derive_probes (systemtap_session& s symbol * get_symbol_within_expression (expression *e); +struct unparser; + +struct derived_probe_group_container: public derived_probe_group +{ +private: + std::vector probes; + derived_probe_group* be_probe_group; + derived_probe_group* dwarf_probe_group; + derived_probe_group* hrtimer_probe_group; + derived_probe_group* mark_probe_group; + derived_probe_group* never_probe_group; + derived_probe_group* profile_probe_group; + derived_probe_group* timer_probe_group; + +public: + derived_probe_group_container (); + ~derived_probe_group_container (); + + void register_probe (be_derived_probe* p); + void register_probe (dwarf_derived_probe* p); + void register_probe (hrtimer_derived_probe* p); + void register_probe (mark_derived_probe* p); + void register_probe (never_derived_probe* p); + void register_probe (profile_derived_probe* p); + void register_probe (timer_derived_probe* p); + size_t size () { return (probes.size ()); } + + derived_probe* operator[] (size_t n) { return (probes[n]); } + + void emit_probes (translator_output* op, unparser* up); +}; + + #endif // ELABORATE_H Index: main.cxx =================================================================== RCS file: /cvs/systemtap/src/main.cxx,v retrieving revision 1.49 diff -u -p -r1.49 main.cxx --- main.cxx 17 Jul 2006 08:25:00 -0000 1.49 +++ main.cxx 18 Aug 2006 19:18:46 -0000 @@ -14,6 +14,7 @@ #include "elaborate.h" #include "translate.h" #include "buildrun.h" +#include "session.h" #include #include Index: parse.h =================================================================== RCS file: /cvs/systemtap/src/parse.h,v retrieving revision 1.22 diff -u -p -r1.22 parse.h --- parse.h 13 Jul 2006 20:41:00 -0000 1.22 +++ parse.h 18 Aug 2006 19:18:46 -0000 @@ -59,6 +59,8 @@ struct parse_error: public std::runtime_ }; +struct systemtap_session; + class lexer { public: @@ -77,6 +79,29 @@ private: }; +struct stapfile; +struct probe; +struct probe_alias; +struct vardecl; +struct functiondecl; +struct embeddedcode; +struct probe_point; +struct literal; +struct block; +struct for_loop; +struct statement; +struct if_statement; +struct foreach_loop; +struct expr_statement; +struct return_statement; +struct delete_statement; +struct break_statement; +struct next_statement; +struct continue_statement; +struct indexable; +struct expression; +struct hist_op; + class parser { public: Index: session.h =================================================================== RCS file: /cvs/systemtap/src/session.h,v retrieving revision 1.7 diff -u -p -r1.7 session.h --- session.h 9 May 2006 09:33:19 -0000 1.7 +++ session.h 18 Aug 2006 19:18:46 -0000 @@ -9,6 +9,7 @@ #ifndef SESSION_H #define SESSION_H +#include "elaborate.h" #include #include #include @@ -21,7 +22,7 @@ struct match_node; struct stapfile; struct vardecl; struct functiondecl; -struct derived_probe; +struct derived_probe_group_container; struct embeddedcode; struct translator_output; struct unparser; @@ -94,7 +95,7 @@ struct systemtap_session std::vector files; std::vector globals; std::vector functions; - std::vector probes; + derived_probe_group_container probes; std::vector embeds; std::map stat_decls; // XXX: vector<*> instead please? Index: staptree.h =================================================================== RCS file: /cvs/systemtap/src/staptree.h,v retrieving revision 1.42 diff -u -p -r1.42 staptree.h --- staptree.h 9 Jun 2006 09:20:03 -0000 1.42 +++ staptree.h 18 Aug 2006 19:18:46 -0000 @@ -9,7 +9,6 @@ #ifndef STAPTREE_H #define STAPTREE_H -#include "session.h" #include #include #include Index: tapsets.cxx =================================================================== RCS file: /cvs/systemtap/src/tapsets.cxx,v retrieving revision 1.138 diff -u -p -r1.138 tapsets.cxx --- tapsets.cxx 1 Aug 2006 02:20:47 -0000 1.138 +++ tapsets.cxx 18 Aug 2006 19:18:46 -0000 @@ -12,6 +12,7 @@ #include "elaborate.h" #include "tapsets.h" #include "translate.h" +#include "session.h" #include #include @@ -198,12 +199,27 @@ struct be_derived_probe: public derived_ be_derived_probe (probe* p, probe_point* l, bool b): derived_probe (p, l), begin (b) {} + void register_probe (systemtap_session& s); + void emit_registrations (translator_output* o); void emit_deregistrations (translator_output* o); void emit_probe_entries (translator_output* o); }; +struct be_derived_probe_group: public derived_probe_group +{ +private: + vector probes; + +public: + virtual void register_probe(be_derived_probe* p) { probes.push_back (p); } + virtual size_t size () { return probes.size (); } + + virtual void emit_probes (translator_output* op, unparser* up); +}; + + struct be_builder: public derived_probe_builder { bool begin; @@ -220,6 +236,13 @@ struct be_builder: public derived_probe_ void +be_derived_probe::register_probe(systemtap_session& s) +{ + s.probes.register_probe(this); +} + + +void be_derived_probe::emit_registrations (translator_output* o) { if (begin) @@ -270,6 +293,17 @@ be_derived_probe::emit_probe_entries (tr } +void +be_derived_probe_group::emit_probes (translator_output* op, unparser* up) +{ + for (unsigned i=0; i < probes.size(); i++) + { + op->newline (); + up->emit_probe (probes[i]); + } +} + + // ------------------------------------------------------------------------ // never probes are never run // ------------------------------------------------------------------------ @@ -279,12 +313,34 @@ struct never_derived_probe: public deriv never_derived_probe (probe* p): derived_probe (p) {} never_derived_probe (probe* p, probe_point* l): derived_probe (p, l) {} + void register_probe (systemtap_session& s); + void emit_registrations (translator_output* o); void emit_deregistrations (translator_output* o); void emit_probe_entries (translator_output* o); }; +struct never_derived_probe_group: public derived_probe_group +{ +private: + vector probes; + +public: + virtual void register_probe(never_derived_probe* p) { probes.push_back (p); } + virtual size_t size () { return probes.size (); } + + virtual void emit_probes (translator_output* op, unparser* up); +}; + + +void +never_derived_probe::register_probe(systemtap_session& s) +{ + s.probes.register_probe(this); +} + + struct never_builder: public derived_probe_builder { never_builder() {} @@ -317,6 +373,15 @@ never_derived_probe::emit_probe_entries } +void +never_derived_probe_group::emit_probes (translator_output* op, unparser* up) +{ + for (unsigned i=0; i < probes.size(); i++) + { + op->newline (); + up->emit_probe (probes[i]); + } +} // ------------------------------------------------------------------------ // Dwarf derived probes. @@ -1717,6 +1782,8 @@ struct dwarf_derived_probe : public deri vector probe_points; bool has_return; + void register_probe (systemtap_session& s); + void add_probe_point(string const & funcname, char const * filename, int line, @@ -1741,6 +1808,20 @@ struct dwarf_derived_probe : public deri virtual void emit_probe_entries (translator_output * o); }; + +struct dwarf_derived_probe_group: public derived_probe_group +{ +private: + vector probes; + +public: + virtual void register_probe(dwarf_derived_probe* p) { probes.push_back (p); } + virtual size_t size () { return probes.size (); } + + virtual void emit_probes (translator_output* op, unparser* up); +}; + + // Helper struct to thread through the dwfl callbacks. struct dwarf_query @@ -2938,6 +3019,13 @@ dwarf_var_expanding_copy_visitor::visit_ void +dwarf_derived_probe::register_probe(systemtap_session& s) +{ + s.probes.register_probe(this); +} + + +void dwarf_derived_probe::add_probe_point(string const & funcname, char const * filename, int line, @@ -3374,6 +3462,17 @@ dwarf_derived_probe::emit_probe_entries void +dwarf_derived_probe_group::emit_probes (translator_output* op, unparser* up) +{ + for (unsigned i=0; i < probes.size(); i++) + { + op->newline (); + up->emit_probe (probes[i]); + } +} + + +void dwarf_builder::build(systemtap_session & sess, probe * base, probe_point * location, @@ -3463,6 +3562,8 @@ struct timer_derived_probe: public deriv timer_derived_probe (probe* p, probe_point* l, int64_t i, int64_t r, bool ms=false); + virtual void register_probe (systemtap_session& s); + virtual void emit_registrations (translator_output * o); virtual void emit_deregistrations (translator_output * o); virtual void emit_probe_entries (translator_output * o); @@ -3485,6 +3586,13 @@ timer_derived_probe::timer_derived_probe void +timer_derived_probe::register_probe(systemtap_session& s) +{ + s.probes.register_probe(this); +} + + +void timer_derived_probe::emit_registrations (translator_output* o) { o->newline() << "init_timer (& timer_" << name << ");"; @@ -3539,6 +3647,30 @@ timer_derived_probe::emit_probe_entries } +struct timer_derived_probe_group: public derived_probe_group +{ +private: + vector probes; + +public: + virtual void register_probe(timer_derived_probe* p) { probes.push_back (p); } + virtual size_t size () { return probes.size (); } + + virtual void emit_probes (translator_output* op, unparser* up); +}; + + +void +timer_derived_probe_group::emit_probes (translator_output* op, unparser* up) +{ + for (unsigned i=0; i < probes.size(); i++) + { + op->newline (); + up->emit_probe (probes[i]); + } +} + + struct timer_builder: public derived_probe_builder { bool time_is_msecs; @@ -3580,6 +3712,8 @@ struct profile_derived_probe: public der profile_derived_probe (systemtap_session &s, probe* p, probe_point* l); + void register_probe (systemtap_session& s); + virtual void emit_registrations (translator_output * o); virtual void emit_deregistrations (translator_output * o); virtual void emit_probe_entries (translator_output * o); @@ -3603,6 +3737,13 @@ profile_derived_probe::profile_derived_p void +profile_derived_probe::register_probe(systemtap_session& s) +{ + s.probes.register_probe(this); +} + + +void profile_derived_probe::emit_registrations (translator_output* o) { if (using_rpn) @@ -3659,6 +3800,31 @@ profile_derived_probe::emit_probe_entrie } +struct profile_derived_probe_group: public derived_probe_group +{ +private: + vector probes; + +public: + virtual void register_probe(profile_derived_probe* p) { + probes.push_back (p); } + virtual size_t size () { return probes.size (); } + + virtual void emit_probes (translator_output* op, unparser* up); +}; + + +void +profile_derived_probe_group::emit_probes (translator_output* op, unparser* up) +{ + for (unsigned i=0; i < probes.size(); i++) + { + op->newline (); + up->emit_probe (probes[i]); + } +} + + struct profile_builder: public derived_probe_builder { profile_builder() {} @@ -3691,6 +3857,8 @@ struct mark_derived_probe: public derive string module; string probe_sig_expanded; + void register_probe (systemtap_session& s); + void emit_registrations (translator_output * o); void emit_deregistrations (translator_output * o); void emit_probe_entries (translator_output * o); @@ -3808,6 +3976,13 @@ mark_derived_probe::mark_derived_probe ( void +mark_derived_probe::register_probe(systemtap_session& s) +{ + s.probes.register_probe(this); +} + + +void mark_derived_probe::emit_probe_context_vars (translator_output* o) { // Save incoming arguments @@ -3903,6 +4078,29 @@ mark_derived_probe::emit_deregistrations } +struct mark_derived_probe_group: public derived_probe_group +{ +private: + vector probes; + +public: + virtual void register_probe(mark_derived_probe* p) { probes.push_back (p); } + virtual size_t size () { return probes.size (); } + + virtual void emit_probes (translator_output* op, unparser* up); +}; + + +void +mark_derived_probe_group::emit_probes (translator_output* op, unparser* up) +{ + for (unsigned i=0; i < probes.size(); i++) + { + op->newline (); + up->emit_probe (probes[i]); + } +} + struct symboltable_extract { @@ -4113,6 +4311,8 @@ struct hrtimer_derived_probe: public der // so we don't have to loop over them in the other functions } + void register_probe (systemtap_session& s); + virtual void emit_interval (translator_output * o); virtual void emit_registrations (translator_output * o); @@ -4122,6 +4322,13 @@ struct hrtimer_derived_probe: public der void +hrtimer_derived_probe::register_probe(systemtap_session& s) +{ + s.probes.register_probe(this); +} + + +void hrtimer_derived_probe::emit_interval (translator_output* o) { o->line() << "({"; @@ -4193,6 +4400,30 @@ hrtimer_derived_probe::emit_probe_entrie } +struct hrtimer_derived_probe_group: public derived_probe_group +{ +private: + vector probes; + +public: + virtual void register_probe(hrtimer_derived_probe* p) { probes.push_back (p); } + virtual size_t size () { return probes.size (); } + + virtual void emit_probes (translator_output* op, unparser* up); +}; + + +void +hrtimer_derived_probe_group::emit_probes (translator_output* op, unparser* up) +{ + for (unsigned i=0; i < probes.size(); i++) + { + op->newline (); + up->emit_probe (probes[i]); + } +} + + struct hrtimer_builder: public derived_probe_builder { hrtimer_builder() {} @@ -4347,3 +4578,114 @@ register_standard_tapsets(systemtap_sess s.pattern_root->bind("kernel")->bind_str("mark")->bind(new mark_builder()); s.pattern_root->bind_str("module")->bind_str("mark")->bind(new mark_builder()); } + + +derived_probe_group_container::derived_probe_group_container (): + be_probe_group(new be_derived_probe_group), + dwarf_probe_group(new dwarf_derived_probe_group), + hrtimer_probe_group(new hrtimer_derived_probe_group), + mark_probe_group(new mark_derived_probe_group), + never_probe_group(new never_derived_probe_group), + profile_probe_group(new profile_derived_probe_group), + timer_probe_group(new timer_derived_probe_group) +{ +} + + +derived_probe_group_container::~derived_probe_group_container () +{ + delete be_probe_group; + delete dwarf_probe_group; + delete hrtimer_probe_group; + delete mark_probe_group; + delete never_probe_group; + delete profile_probe_group; + delete timer_probe_group; +} + + +void +derived_probe_group_container::register_probe(be_derived_probe* p) +{ + probes.push_back (p); + be_probe_group->register_probe(p); +} + + +void +derived_probe_group_container::register_probe(dwarf_derived_probe* p) +{ + probes.push_back (p); + dwarf_probe_group->register_probe(p); +} + + +void +derived_probe_group_container::register_probe(hrtimer_derived_probe* p) +{ + probes.push_back (p); + hrtimer_probe_group->register_probe(p); +} + + +void +derived_probe_group_container::register_probe(mark_derived_probe* p) +{ + probes.push_back (p); + mark_probe_group->register_probe(p); +} + + +void +derived_probe_group_container::register_probe(never_derived_probe* p) +{ + probes.push_back (p); + never_probe_group->register_probe(p); +} + + +void +derived_probe_group_container::register_probe(profile_derived_probe* p) +{ + probes.push_back (p); + profile_probe_group->register_probe(p); +} + + +void +derived_probe_group_container::register_probe(timer_derived_probe* p) +{ + probes.push_back (p); + timer_probe_group->register_probe(p); +} + + +void +derived_probe_group_container::emit_probes (translator_output* op, + unparser* up) +{ + // Sanity check. + size_t groups_size = be_probe_group->size () + + dwarf_probe_group->size () + + hrtimer_probe_group->size () + + mark_probe_group->size () + + never_probe_group->size () + + profile_probe_group->size () + + timer_probe_group->size (); + if (probes.size () != groups_size) + { + cerr << "There are " << probes.size () << " total probes, and " + << groups_size << " grouped probes\n"; + + throw runtime_error("internal probe mismatch"); + } + + // Let each probe group emit its probes. + be_probe_group->emit_probes (op, up); + dwarf_probe_group->emit_probes (op, up); + hrtimer_probe_group->emit_probes (op, up); + mark_probe_group->emit_probes (op, up); + never_probe_group->emit_probes (op, up); + profile_probe_group->emit_probes (op, up); + timer_probe_group->emit_probes (op, up); +} Index: translate.cxx =================================================================== RCS file: /cvs/systemtap/src/translate.cxx,v retrieving revision 1.128 diff -u -p -r1.128 translate.cxx --- translate.cxx 10 Aug 2006 19:19:06 -0000 1.128 +++ translate.cxx 18 Aug 2006 19:18:46 -0000 @@ -11,6 +11,7 @@ #include "staptree.h" #include "elaborate.h" #include "translate.h" +#include "session.h" #include #include #include @@ -3926,11 +3927,7 @@ translate_pass (systemtap_session& s) s.up->emit_function (s.functions[i]); } - for (unsigned i=0; inewline(); - s.up->emit_probe (s.probes[i]); - } + s.probes.emit_probes (s.op, s.up); s.op->newline(); s.up->emit_module_init (); --=-ENlX0iXob+lkVW6zstbk--