diff --git a/.gitignore b/.gitignore index 4883f90..e3af9b7 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/systemtap-5.2.tar.gz +SOURCES/systemtap-5.3.tar.gz diff --git a/.systemtap.metadata b/.systemtap.metadata index 28aef4f..df20e27 100644 --- a/.systemtap.metadata +++ b/.systemtap.metadata @@ -1 +1 @@ -c4a891e0732378f7ff6131e59aa6e173282a6adb SOURCES/systemtap-5.2.tar.gz +5a3cbaf151ef6d8621ba24fefc1c2304a041d377 SOURCES/systemtap-5.3.tar.gz diff --git a/SOURCES/PR32302.patch b/SOURCES/PR32302.patch deleted file mode 100644 index 372014c..0000000 --- a/SOURCES/PR32302.patch +++ /dev/null @@ -1,223 +0,0 @@ -commit 8b87bd584dcadb3713eaf6d0c9b540b4f54124bf -gpg: Signature made Mon 11 Nov 2024 11:48:03 AM EST -gpg: using RSA key D8F2E95271BA794E222FBEE0DB83606EC7DAAB26 -gpg: Can't check signature: No public key -Author: Martin Cermak -Date: Mon Nov 11 17:41:53 2024 +0100 - - PR32302: Emit forward decls within tracepoint_derived_probe_group() too - - Forward decls added in commit 069def0ae9184 need to actually be - emitted in 2 locations, roughtly corresponding to where - tracepoint_extra_decls() is used. - - It would be ideal to put them directly to tracepoint_extra_decls() - but that gives significantly less recognized tracepoints. - - The plan is toreview this again though and try to merge the - tracepoint_forward_decls() body into tracepoint_extra_decls() - if possible. - -diff --git a/tapsets.cxx b/tapsets.cxx -index b4ad7e14e..06540cafc 100644 ---- a/tapsets.cxx -+++ b/tapsets.cxx -@@ -11729,6 +11729,89 @@ static bool header_exists(systemtap_session& s, const string& header) - return false; - } - -+static vector tracepoint_forward_decls () -+{ -+ vector retval; -+ // Kernel 6.12 -+ retval.push_back("enum cachefiles_content;"); -+ retval.push_back("enum extent_type;"); -+ retval.push_back("struct bch_fs;"); -+ retval.push_back("struct bch_move_stats;"); -+ retval.push_back("struct bpos;"); -+ retval.push_back("struct btree_bkey_cached_common;"); -+ retval.push_back("struct btree_insert_entry;"); -+ retval.push_back("struct btree_path;"); -+ retval.push_back("struct btree_trans;"); -+ retval.push_back("struct cachefiles_msg;"); -+ retval.push_back("struct cachefiles_open;"); -+ retval.push_back("struct cachefiles_read;"); -+ retval.push_back("struct cachefiles_volume;"); -+ retval.push_back("struct clk_rate_request;"); -+ retval.push_back("struct compact_control;"); -+ retval.push_back("struct fsi_device;"); -+ retval.push_back("struct fsi_msg;"); -+ retval.push_back("struct fsi_slave;"); -+ retval.push_back("struct fuse_req;"); -+ retval.push_back("struct get_locks_fail;"); -+ retval.push_back("struct gss_cred;"); -+ retval.push_back("struct handshake_req;"); -+ retval.push_back("struct i2c_client;"); -+ retval.push_back("struct ib_mad_agent_private;"); -+ retval.push_back("struct ib_mad_qp_info;"); -+ retval.push_back("struct ib_mad_send_wr_private;"); -+ retval.push_back("struct ib_smp;"); -+ retval.push_back("struct iomap;"); -+ retval.push_back("struct iomap_iter;"); -+ retval.push_back("struct mctp_sk_key;"); -+ retval.push_back("struct mptcp_ext;"); -+ retval.push_back("struct mptcp_subflow_context;"); -+ retval.push_back("struct nbd_request;"); -+ retval.push_back("struct netfs_io_request;"); -+ retval.push_back("struct netfs_io_stream;"); -+ retval.push_back("struct netfs_io_subrequest;"); -+ retval.push_back("struct nfs42_clone_args;"); -+ retval.push_back("struct nfs42_copy_args;"); -+ retval.push_back("struct nfs42_copy_notify_args;"); -+ retval.push_back("struct nfs42_copy_notify_res;"); -+ retval.push_back("struct nfs42_copy_res;"); -+ retval.push_back("struct nfs42_falloc_args;"); -+ retval.push_back("struct nfs42_offload_status_args;"); -+ retval.push_back("struct nfs42_seek_args;"); -+ retval.push_back("struct nfs42_seek_res;"); -+ retval.push_back("struct nfs_direct_req;"); -+ retval.push_back("struct nfs_page;"); -+ retval.push_back("struct opa_smp;"); -+ retval.push_back("struct p9_fid;"); -+ retval.push_back("struct pwc_device;"); -+ retval.push_back("struct request;"); -+ retval.push_back("struct rpc_auth;"); -+ retval.push_back("struct rpc_gss_wire_cred;"); -+ retval.push_back("struct rpcrdma_ep;"); -+ retval.push_back("struct rpcrdma_mr;"); -+ retval.push_back("struct rpcrdma_notification;"); -+ retval.push_back("struct rpcrdma_rep;"); -+ retval.push_back("struct rpcrdma_req;"); -+ retval.push_back("struct rpcrdma_xprt;"); -+ retval.push_back("struct rpc_rqst;"); -+ retval.push_back("struct rpc_task;"); -+ retval.push_back("struct selinux_audit_data;"); -+ retval.push_back("struct spi_device;"); -+ retval.push_back("struct svc_rdma_chunk;"); -+ retval.push_back("struct svc_rdma_recv_ctxt;"); -+ retval.push_back("struct svc_rdma_segment;"); -+ retval.push_back("struct svc_rdma_send_ctxt;"); -+ retval.push_back("struct svc_rqst;"); -+ retval.push_back("struct svcxprt_rdma;"); -+ retval.push_back("struct tmigr_cpu;"); -+ retval.push_back("struct tmigr_group;"); -+ retval.push_back("struct virtio_gpu_ctrl_hdr;"); -+ retval.push_back("struct virtqueue;"); -+ retval.push_back("struct somenonexistentstruct_123;"); -+ retval.push_back("union ifs_sbaf;"); -+ retval.push_back("union ifs_sbaf_status;"); -+ retval.push_back("union tmigr_state;"); -+ return retval; -+} - - static vector tracepoint_extra_decls (systemtap_session& s, - const string& header, -@@ -12187,6 +12270,8 @@ tracepoint_derived_probe_group::emit_module_decls (systemtap_session& s) - s.op->newline(); - - -+ -+ - // We create a MODULE_aux_N.c file for each tracepoint header, to allow them - // to be separately compiled. That's because kernel tracepoint headers sometimes - // conflict. PR13155. -@@ -12207,6 +12292,11 @@ tracepoint_derived_probe_group::emit_module_decls (systemtap_session& s) - tpop = s.op_create_auxiliary(); - per_header_aux[header] = tpop; - -+ // add needed forward decls/#includes -+ static vector forward_decls = tracepoint_forward_decls(); -+ for (unsigned z=0; znewline()<< forward_decls[z] << "\n"; -+ - // PR9993: Add extra headers to work around undeclared types in individual - // include/trace/foo.h files - const vector& extra_decls = tracepoint_extra_decls (s, header, -@@ -12773,83 +12863,10 @@ tracepoint_builder::get_tracequery_modules(systemtap_session& s, - osrc << "#ifdef CONFIG_TRACEPOINTS" << endl; - osrc << "#include " << endl; - -- osrc << "enum cachefiles_content;" << endl; -- osrc << "enum extent_type;" << endl; -- osrc << "struct bch_fs;" << endl; -- osrc << "struct bch_move_stats;" << endl; -- osrc << "struct bpos;" << endl; -- osrc << "struct btree_bkey_cached_common;" << endl; -- osrc << "struct btree_insert_entry;" << endl; -- osrc << "struct btree_path;" << endl; -- osrc << "struct btree_trans;" << endl; -- osrc << "struct cachefiles_msg;" << endl; -- osrc << "struct cachefiles_open;" << endl; -- osrc << "struct cachefiles_read;" << endl; -- osrc << "struct cachefiles_volume;" << endl; -- osrc << "struct clk_rate_request;" << endl; -- osrc << "struct compact_control;" << endl; -- osrc << "struct fsi_device;" << endl; -- osrc << "struct fsi_msg;" << endl; -- osrc << "struct fsi_slave;" << endl; -- osrc << "struct fuse_req;" << endl; -- osrc << "struct get_locks_fail;" << endl; -- osrc << "struct gss_cred;" << endl; -- osrc << "struct handshake_req;" << endl; -- osrc << "struct i2c_client;" << endl; -- osrc << "struct ib_mad_agent_private;" << endl; -- osrc << "struct ib_mad_qp_info;" << endl; -- osrc << "struct ib_mad_send_wr_private;" << endl; -- osrc << "struct ib_smp;" << endl; -- osrc << "struct iomap;" << endl; -- osrc << "struct iomap_iter;" << endl; -- osrc << "struct mctp_sk_key;" << endl; -- osrc << "struct mptcp_ext;" << endl; -- osrc << "struct mptcp_subflow_context;" << endl; -- osrc << "struct nbd_request;" << endl; -- osrc << "struct netfs_io_request;" << endl; -- osrc << "struct netfs_io_stream;" << endl; -- osrc << "struct netfs_io_subrequest;" << endl; -- osrc << "struct nfs42_clone_args;" << endl; -- osrc << "struct nfs42_copy_args;" << endl; -- osrc << "struct nfs42_copy_notify_args;" << endl; -- osrc << "struct nfs42_copy_notify_res;" << endl; -- osrc << "struct nfs42_copy_res;" << endl; -- osrc << "struct nfs42_falloc_args;" << endl; -- osrc << "struct nfs42_offload_status_args;" << endl; -- osrc << "struct nfs42_seek_args;" << endl; -- osrc << "struct nfs42_seek_res;" << endl; -- osrc << "struct nfs_direct_req;" << endl; -- osrc << "struct nfs_page;" << endl; -- osrc << "struct opa_smp;" << endl; -- osrc << "struct p9_fid;" << endl; -- osrc << "struct pwc_device;" << endl; -- osrc << "struct request;" << endl; -- osrc << "struct rpc_auth;" << endl; -- osrc << "struct rpc_gss_wire_cred;" << endl; -- osrc << "struct rpcrdma_ep;" << endl; -- osrc << "struct rpcrdma_mr;" << endl; -- osrc << "struct rpcrdma_notification;" << endl; -- osrc << "struct rpcrdma_rep;" << endl; -- osrc << "struct rpcrdma_req;" << endl; -- osrc << "struct rpcrdma_xprt;" << endl; -- osrc << "struct rpc_rqst;" << endl; -- osrc << "struct rpc_task;" << endl; -- osrc << "struct selinux_audit_data;" << endl; -- osrc << "struct spi_device;" << endl; -- osrc << "struct svc_rdma_chunk;" << endl; -- osrc << "struct svc_rdma_recv_ctxt;" << endl; -- osrc << "struct svc_rdma_segment;" << endl; -- osrc << "struct svc_rdma_send_ctxt;" << endl; -- osrc << "struct svc_rqst;" << endl; -- osrc << "struct svcxprt_rdma;" << endl; -- osrc << "struct tmigr_cpu;" << endl; -- osrc << "struct tmigr_group;" << endl; -- osrc << "struct virtio_gpu_ctrl_hdr;" << endl; -- osrc << "struct virtqueue;" << endl; -- osrc << "struct somenonexistentstruct_123;" << endl; -- osrc << "union ifs_sbaf;" << endl; -- osrc << "union ifs_sbaf_status;" << endl; -- osrc << "union tmigr_state;" << endl; -+ // add needed forward decls/#includes -+ static vector forward_decls = tracepoint_forward_decls(); -+ for (unsigned z=0; z +Date: Mon May 19 16:51:42 2025 -0400 + + PR32964 part 1: improve diagnostics of @defined resolution + + The @defined construct is special in that it is attempted to be + resolved to literal 1/0 fairly early during semantic analysis pass-2, + so that it can guard $context variable references. But this early + processing is not that systematic: not all script level constructs + properly nest with it. Those cases that don't happen to match end + up resolved to 0 as a fallback in late during pass-2, due to PR18079. + + This patch adds verbosity diagnostics for some of these cases, and a + warning message for the fallback resolution path. This triggers + for the test case associated with this bugzilla report. + +diff --git a/dwflpp.cxx b/dwflpp.cxx +index 1105272f2..62ae15837 100644 +--- a/dwflpp.cxx ++++ b/dwflpp.cxx +@@ -4427,8 +4427,9 @@ dwflpp::literal_stmt_for_pointer (location_context &ctx, + Dwarf_Die *die_mem) + { + if (sess.verbose>2) +- clog << _F("literal_stmt_for_pointer: finding value for %s (%s)\n", +- dwarf_type_name(start_typedie).c_str(), (dwarf_diename(cu) ?: "")); ++ clog << _("literal_stmt_for_pointer: finding value for ") << *e->tok ++ << _F(" type %s (%s)\n", ++ dwarf_type_name(start_typedie).c_str(), (dwarf_diename(cu) ?: "")); + + assert(ctx.pointer != NULL); + location *tail = ctx.translate_argument (ctx.pointer); +diff --git a/elaborate.cxx b/elaborate.cxx +index 865fe6555..023b4c08f 100644 +--- a/elaborate.cxx ++++ b/elaborate.cxx +@@ -1894,7 +1894,7 @@ semantic_pass_symbols (systemtap_session& s) + assert_no_interrupts(); + stapfile* dome = s.files[i]; + +- // Pass 1: add globals and functions to systemtap-session primart list, ++ // Pass 1: add globals and functions to systemtap-session primary list, + // so the find_* functions find them + // + // NB: tapset global/function definitions may duplicate or conflict +@@ -2796,6 +2796,8 @@ symresolution_info::visit_symbol (symbol* e) + vardecl* d = find_var (e->name, 0, e->tok); + if (d) + { ++ if (session.verbose > 4) ++ clog << "resolved variable " << *e->tok << " to " << *d->tok << endl; + e->referent = d; + e->name = d->name; + } +@@ -2814,6 +2816,8 @@ symresolution_info::visit_symbol (symbol* e) + // must be probe-condition expression + throw SEMANTIC_ERROR (_("probe condition must not reference undeclared global"), e->tok); + e->referent = v; ++ if (session.verbose > 4) ++ clog << "resolved variable " << *e->tok << " to new local" << endl; + } + } + +@@ -5112,6 +5116,7 @@ const_folder::visit_defined_op (defined_op* e) + // Don't be greedy... we'll only collapse one at a time so type + // resolution can have another go at it. + relaxed_p = false; ++ session.print_warning (_F("Collapsing unresolved @define to %ld", value), e->tok); + literal_number* n = new literal_number (value); + n->tok = e->tok; + n->visit (this); +diff --git a/tapsets.cxx b/tapsets.cxx +index d25c85043..01fec29e3 100644 +--- a/tapsets.cxx ++++ b/tapsets.cxx +@@ -3118,9 +3118,22 @@ var_expanding_visitor::visit_defined_op (defined_op* e) + + target_symbol* tsym = dynamic_cast (e->operand); + if (tsym && tsym->saved_conversion_error) // failing +- resolved = false; ++ { ++ if (sess.verbose>3) ++ { ++ for (const semantic_error *c = tsym->saved_conversion_error; ++ c != 0; ++ c = c->get_chain()) { ++ clog << _("variable location problem [man error::dwarf]: ") << c->what() << endl; ++ } ++ } ++ resolved = false; ++ } + else if (e->operand == old_operand) // unresolved but not marked failing + { ++ if (sess.verbose>3) ++ clog << _("@defined unresolved due to un-rewritten operand ") << *e << endl; ++ + // There are some visitors that won't touch certain target_symbols, + // e.g. dwarf_var_expanding_visitor won't resolve @cast. We should + // leave it for now so some other visitor can have a chance. +@@ -3132,6 +3145,8 @@ var_expanding_visitor::visit_defined_op (defined_op* e) + resolved = true; + } catch (const semantic_error& e) { + // some uncooperative value like @perf("NO_SUCH_VALUE") ++ if (sess.verbose > 3) ++ clog << sess.build_error_msg (e); + resolved = false; + } + defined_ops.pop (); + +commit b36c59692966c6207bf6f69b2f6f91079f7b89ab +Author: Frank Ch. Eigler +Date: Mon May 19 22:30:29 2025 -0400 + + PR32964 part 2: document new @defined() warning + + ... in [man stapprobes], though [man stap] is where autocast variable + processing is documented in the "TYPECASTING" section. + +diff --git a/elaborate.cxx b/elaborate.cxx +index 023b4c08f..c09e3ddca 100644 +--- a/elaborate.cxx ++++ b/elaborate.cxx +@@ -5116,7 +5116,7 @@ const_folder::visit_defined_op (defined_op* e) + // Don't be greedy... we'll only collapse one at a time so type + // resolution can have another go at it. + relaxed_p = false; +- session.print_warning (_F("Collapsing unresolved @define to %ld", value), e->tok); ++ session.print_warning (_F("Collapsing unresolved @define to %ld [stapprobes]", value), e->tok); + literal_number* n = new literal_number (value); + n->tok = e->tok; + n->visit (this); +diff --git a/man/stapprobes.3stap b/man/stapprobes.3stap +index 1f980567b..d395e3578 100644 +--- a/man/stapprobes.3stap ++++ b/man/stapprobes.3stap +@@ -700,6 +700,11 @@ for use in conditionals such as + .SAMPLE + @defined($foo\->bar) ? $foo\->bar : 0 + .ESAMPLE ++Use full $context variables or @cast() expressions in @define parameters ++for unambiguous processing. The TYPECAST script-level variable ++facility is incompletely supported. Simplify the parameters by reducing ++nesting or indirection, if encountering "Collapsing unresolved @define to ..." ++warnings. + .TP + @probewrite($VAR) + see the PROBES section of \fIstap\fR(1). + +commit e4786671a999d47003ea62525ed829c1784c03ea +Author: Frank Ch. Eigler +Date: Thu May 22 17:14:53 2025 -0400 + + PR32964 part 3: include autocast processing in initial_typeres_pass + + This type resolution pass is done early, but previously purposefully + ommitted opportunistic autocast expansion. With it done there, once + (in the usual relaxation loop), more autocast-based @defined / + @choose_defined constructs will be processed in the way a user + may expect. + +diff --git a/elaborate.cxx b/elaborate.cxx +index c09e3ddca..b03f0aced 100644 +--- a/elaborate.cxx ++++ b/elaborate.cxx +@@ -2602,7 +2602,7 @@ semantic_pass (systemtap_session& s) + if (rc == 0) rc = semantic_pass_symbols (s); + if (rc == 0) monitor_mode_write (s); + if (rc == 0) rc = semantic_pass_conditions (s); +- if (rc == 0) rc = semantic_pass_optimize1 (s); ++ if (rc == 0) rc = semantic_pass_optimize1 (s); // includes const_fold and last ditch @defined() processing + if (rc == 0) rc = semantic_pass_types (s); + if (rc == 0) rc = gen_dfa_table(s); + if (rc == 0) add_global_var_display (s); +@@ -6045,7 +6045,7 @@ struct initial_typeresolution_info : public typeresolution_info + static int initial_typeres_pass(systemtap_session& s) + { + // minimal type resolution based off of semantic_pass_types(), without +- // checking for complete type resolutions or autocast expanding ++ // checking for complete type resolutions, PR32964 but including autocast expanding + initial_typeresolution_info ti(s); + + ti.assert_resolvability = false; +@@ -6067,6 +6067,30 @@ static int initial_typeres_pass(systemtap_session& s) + ti.current_function = fd; + ti.t = pe_unknown; + fd->body->visit (& ti); ++ ++ // Check and run the autocast expanding visitor. ++ if (ti.num_available_autocasts > 0) ++ { ++ autocast_expanding_visitor aev (s, ti); ++ aev.replace (fd->body); ++ ++ // PR18079, rerun the const-folder / dead-block-remover ++ // if autocast evaluation enabled a @defined() ++ if (! aev.relaxed()) ++ { ++ bool relaxed_p = true; ++ const_folder cf (s, relaxed_p); ++ cf.replace (fd->body); ++ if (! s.unoptimized) ++ { ++ dead_control_remover dc (s, relaxed_p); ++ fd->body->visit (&dc); ++ } ++ (void) relaxed_p; // we judge success later by num_still_unresolved, not this flag ++ } ++ ++ ti.num_available_autocasts = 0; ++ } + } + + for (unsigned j=0; jbody->visit (& ti); + ++ // Check and run the autocast expanding visitor. ++ if (ti.num_available_autocasts > 0) ++ { ++ autocast_expanding_visitor aev (s, ti); ++ var_expand_const_fold_loop (s, pn->body, aev); ++ // PR18079, rerun the const-folder / dead-block-remover ++ // if autocast evaluation enabled a @defined() ++ if (! s.unoptimized) ++ { ++ bool relaxed_p; ++ dead_control_remover dc (s, relaxed_p); ++ pn->body->visit (&dc); ++ (void) relaxed_p; // we judge success later by num_still_unresolved, not this flag ++ } ++ ++ ti.num_available_autocasts = 0; ++ } ++ + probe_point* pp = pn->sole_location(); + if (pp->condition) + { +@@ -6147,30 +6189,8 @@ semantic_pass_types (systemtap_session& s) + // ti.unresolved (fd->tok); + for (unsigned i=0; i < fd->locals.size(); ++i) + ti.check_local (fd->locals[i]); +- +- // Check and run the autocast expanding visitor. +- if (ti.num_available_autocasts > 0) +- { +- autocast_expanding_visitor aev (s, ti); +- aev.replace (fd->body); +- +- // PR18079, rerun the const-folder / dead-block-remover +- // if autocast evaluation enabled a @defined() +- if (! aev.relaxed()) +- { +- bool relaxed_p = true; +- const_folder cf (s, relaxed_p); +- cf.replace (fd->body); +- if (! s.unoptimized) +- { +- dead_control_remover dc (s, relaxed_p); +- fd->body->visit (&dc); +- } +- (void) relaxed_p; // we judge success later by num_still_unresolved, not this flag +- } + +- ti.num_available_autocasts = 0; +- } ++ // PR32964: autocast resolution is now done early in initial_typeres_pass + } + catch (const semantic_error& e) + { +@@ -6191,24 +6211,8 @@ semantic_pass_types (systemtap_session& s) + pn->body->visit (& ti); + for (unsigned i=0; i < pn->locals.size(); ++i) + ti.check_local (pn->locals[i]); +- +- // Check and run the autocast expanding visitor. +- if (ti.num_available_autocasts > 0) +- { +- autocast_expanding_visitor aev (s, ti); +- var_expand_const_fold_loop (s, pn->body, aev); +- // PR18079, rerun the const-folder / dead-block-remover +- // if autocast evaluation enabled a @defined() +- if (! s.unoptimized) +- { +- bool relaxed_p; +- dead_control_remover dc (s, relaxed_p); +- pn->body->visit (&dc); +- (void) relaxed_p; // we judge success later by num_still_unresolved, not this flag +- } + +- ti.num_available_autocasts = 0; +- } ++ // PR32964: autocast resolution is now done early in initial_typeres_pass + + probe_point* pp = pn->sole_location(); + if (pp->condition) + +commit 3122ff592bdfcf553afa6683724e90c359f3c5c9 +Author: Frank Ch. Eigler +Date: Fri May 30 17:50:10 2025 -0400 + + PR32964 part 4: let autocast pass propagate vardecl/symbol type_details + + The initial_typeres_pass now communicates relaxed status, + and its autocast_expanding_visitor now passes vardecl type_details + to the symbols. This way, the existing const_folder etc. visitors + can deduce enough type info for @defined(an_autocast_var->foo->bar) + constructs, and early enough, that @defined() works as intended. + + New testsuite/semok/definedautocast.stp tests a simple case. + +diff --git a/elaborate.cxx b/elaborate.cxx +index b03f0aced..7a1609f1b 100644 +--- a/elaborate.cxx ++++ b/elaborate.cxx +@@ -5163,7 +5163,7 @@ const_folder::visit_target_symbol (target_symbol* e) + } + } + +-static int initial_typeres_pass(systemtap_session& s); ++static int initial_typeres_pass(systemtap_session& s, bool& relaxed_p); + static int semantic_pass_const_fold (systemtap_session& s, bool& relaxed_p) + { + // attempt an initial type resolution pass to see if there are any type +@@ -5171,7 +5171,7 @@ static int semantic_pass_const_fold (systemtap_session& s, bool& relaxed_p) + // with a const. + + // return if the initial type resolution pass reported errors (type mismatches) +- int rc = initial_typeres_pass(s); ++ int rc = initial_typeres_pass(s, relaxed_p); + if (rc) + { + relaxed_p = true; +@@ -5994,6 +5994,25 @@ struct autocast_expanding_visitor: public var_expanding_visitor + } + } + ++ void visit_symbol (symbol* e) // propagate referent exp_type ++ { ++ // PR32964: mimic typeresolution_info::resolve_details, for case ++ // where the symbol (autocast_op operand) is within a @defined(). ++ ++ if (e->referent && e->referent->type_details && !e->type_details) ++ { ++ const exp_type_ptr &src = e->referent->type_details; ++ exp_type_ptr &dest = e->type_details; ++ dest = src; ++ ti.num_newly_resolved++; ++ relaxed_p = false; ++ if (sess.verbose > 4) ++ clog << "resolved early type details " << *dest << " to " << *e->tok << endl; ++ } ++ var_expanding_visitor::visit_symbol (e); ++ } ++ ++ + void visit_autocast_op (autocast_op* e) + { + const bool lvalue = is_active_lvalue (e); +@@ -6004,7 +6023,7 @@ struct autocast_expanding_visitor: public var_expanding_visitor + if (fc) + { + ti.num_newly_resolved++; +- ++ relaxed_p = false; + resolve_functioncall (fc); + // NB: at this stage, the functioncall object has one + // argument too few if we're in lvalue context. It will +@@ -6042,7 +6061,7 @@ struct initial_typeresolution_info : public typeresolution_info + void visit_cast_op (cast_op*) {} + }; + +-static int initial_typeres_pass(systemtap_session& s) ++static int initial_typeres_pass(systemtap_session& s, bool& relaxed_p) + { + // minimal type resolution based off of semantic_pass_types(), without + // checking for complete type resolutions, PR32964 but including autocast expanding +@@ -6069,7 +6088,7 @@ static int initial_typeres_pass(systemtap_session& s) + fd->body->visit (& ti); + + // Check and run the autocast expanding visitor. +- if (ti.num_available_autocasts > 0) ++ if (true || ti.num_available_autocasts > 0) + { + autocast_expanding_visitor aev (s, ti); + aev.replace (fd->body); +@@ -6078,7 +6097,7 @@ static int initial_typeres_pass(systemtap_session& s) + // if autocast evaluation enabled a @defined() + if (! aev.relaxed()) + { +- bool relaxed_p = true; ++ // bool relaxed_p = true; + const_folder cf (s, relaxed_p); + cf.replace (fd->body); + if (! s.unoptimized) +@@ -6086,7 +6105,7 @@ static int initial_typeres_pass(systemtap_session& s) + dead_control_remover dc (s, relaxed_p); + fd->body->visit (&dc); + } +- (void) relaxed_p; // we judge success later by num_still_unresolved, not this flag ++ // (void) relaxed_p; // we judge success later by num_still_unresolved, not this flag + } + + ti.num_available_autocasts = 0; +@@ -6104,7 +6123,7 @@ static int initial_typeres_pass(systemtap_session& s) + pn->body->visit (& ti); + + // Check and run the autocast expanding visitor. +- if (ti.num_available_autocasts > 0) ++ if (true || ti.num_available_autocasts > 0) + { + autocast_expanding_visitor aev (s, ti); + var_expand_const_fold_loop (s, pn->body, aev); +@@ -6112,10 +6131,10 @@ static int initial_typeres_pass(systemtap_session& s) + // if autocast evaluation enabled a @defined() + if (! s.unoptimized) + { +- bool relaxed_p; ++ // bool relaxed_p; + dead_control_remover dc (s, relaxed_p); + pn->body->visit (&dc); +- (void) relaxed_p; // we judge success later by num_still_unresolved, not this flag ++ // (void) relaxed_p; // we judge success later by num_still_unresolved, not this flag + } + + ti.num_available_autocasts = 0; +diff --git a/testsuite/semok/definedautocast.stp b/testsuite/semok/definedautocast.stp +new file mode 100755 +index 000000000..b28be6118 +--- /dev/null ++++ b/testsuite/semok/definedautocast.stp +@@ -0,0 +1,6 @@ ++#! stap -Wp2 ++ ++probe kernel.function("do_exit") { ++ x = & @cast(0, "struct block_device") ++ println(@defined(x->__bd_flags->counter)) ++} + +commit 778ba67e356dc1820acc8ecdaa2c4b608c2eb184 +Author: Frank Ch. Eigler +Date: Fri May 30 22:10:36 2025 -0400 + + PR32964 part 5: tweak type inference propagation + + Because some type inference is now performed earlier than before, + coupled with early const-folding (so dead code elimination), tests + like semko/binexpr_infer_type.stp started passing with immediately + prior code. That's because constructs like (foo*0) got quietly + replaced by 0, even if foo was typed pe_string. This patch + compensates for this change in behaviour by: + + - typeresolution_info::resolve_2types now propagates types + more aggressively & recursively in its three-way inference, + so that the unknown x string x long case is detected in one + incoming invocation of the function, instead of being + deferred to some unknown later relaxation-iteration round. + + - typeresolution_info::mismatch reporting errors, independent + of "assert_resolvability". That flag was most likely meant + for detection & rejection of pe_unknown types at the end of + all the optimization stuff, not for ignoring outright known + conflicts. + +diff --git a/elaborate.cxx b/elaborate.cxx +index 7a1609f1b..d93a83eca 100644 +--- a/elaborate.cxx ++++ b/elaborate.cxx +@@ -6683,21 +6683,21 @@ void resolve_2types (Referrer* referrer, Referent* referent, + // propagate from upstream + re_type = t; + r->resolved (re_tok, re_type); +- // catch re_type/te_type mismatch later ++ resolve_2types (referrer, referent, r, t, accept_unknown); + } + else if (re_type == pe_unknown && te_type != pe_unknown) + { + // propagate from referent + re_type = te_type; + r->resolved (re_tok, re_type); +- // catch re_type/t mismatch later ++ resolve_2types (referrer, referent, r, t, accept_unknown); + } + else if (re_type != pe_unknown && te_type == pe_unknown) + { + // propagate to referent + te_type = re_type; + r->resolved (re_tok, re_type, referent); +- // catch re_type/t mismatch later ++ resolve_2types (referrer, referent, r, t, accept_unknown); + } + else if (! accept_unknown) + r->unresolved (re_tok); +@@ -7636,14 +7636,14 @@ typeresolution_info::mismatch (const binary_expression* e) + { + num_still_unresolved ++; + +- if (assert_resolvability && mismatch_complexity <= 1) ++ if (mismatch_complexity <= 1) + { + stringstream msg; + msg << _F("type mismatch: left and right sides don't agree (%s vs %s)", + lex_cast(e->left->type).c_str(), lex_cast(e->right->type).c_str()); + session.print_error (SEMANTIC_ERROR (msg.str(), e->tok)); + } +- else if (!assert_resolvability) ++ else + mismatch_complexity = max(1, mismatch_complexity); + } + +@@ -7656,7 +7656,7 @@ typeresolution_info::mismatch (const token* tok, exp_type t1, exp_type t2) + { + num_still_unresolved ++; + +- if (assert_resolvability && mismatch_complexity <= 2) ++ if (mismatch_complexity <= 2) + { + stringstream msg; + msg << _F("type mismatch: expected %s", lex_cast(t1).c_str()); +@@ -7664,7 +7664,7 @@ typeresolution_info::mismatch (const token* tok, exp_type t1, exp_type t2) + msg << _F(" but found %s", lex_cast(t2).c_str()); + session.print_error (SEMANTIC_ERROR (msg.str(), tok)); + } +- else if (!assert_resolvability) ++ else + mismatch_complexity = max(2, mismatch_complexity); + } + +@@ -7679,7 +7679,7 @@ typeresolution_info::mismatch (const token *tok, exp_type type, + { + num_still_unresolved ++; + +- if (assert_resolvability && mismatch_complexity <= 3) ++ if (mismatch_complexity <= 3) + { + assert(decl != NULL); + +@@ -7737,7 +7737,7 @@ typeresolution_info::mismatch (const token *tok, exp_type type, + err.set_chain(chain); + session.print_error (err); + } +- else if (!assert_resolvability) ++ else + mismatch_complexity = max(3, mismatch_complexity); + } + + +commit fd4322e38d1e6504341b67329e112ccc1af387b6 +Author: Frank Ch. Eigler +Date: Sat May 31 09:15:33 2025 -0400 + + PR32964 part 6: NEWS & old testcase + + It turns out there was one old testcase that relied on type + non-checking upon elided variables. This test has been removed, and + the change mentioned in NEWS. Unfortunately, this is is hard to make + conditional on --compatible=XXXX, so hypothetical old (arguably buggy) + scripts may get hit. + +diff --git a/NEWS b/NEWS +index 01b74a671..f1d78e8fa 100644 +--- a/NEWS ++++ b/NEWS +@@ -1,3 +1,11 @@ ++* What's new in version 5.4 ++ ++- Type checking and autocast processing have been made more thorough, ++ so elided variables are checked more and @defined() tests may be ++ more complicated. Preexisting scripts that rely on elision for ++ bypassing type violations may now get caught. No --compatible ++ option exists to suppress this new behaviour. ++ + * What's new in version 5.3, 2025-05-02 + + - Updated to support drastic linux 6.13 kbuild changes, numerous +diff --git a/testsuite/semok/pr30570.stp b/testsuite/semok/pr30570.stp +index b711b214c..dda7d027c 100755 +--- a/testsuite/semok/pr30570.stp ++++ b/testsuite/semok/pr30570.stp +@@ -24,13 +24,16 @@ probe oneshot { + } + + # error var and the try block are elided which means +-# it's not an issue to use e4 as a long here +-global e4 = 10 +-probe oneshot { +- try { } +- catch (e4) +- { } +-} ++# it's not an issue to use e4 as a long here ... ++# except after PR32964, type checking is done more ++# systematically on even elided variables, so this ++# would be an error! ++# global e4 = 10 ++# probe oneshot { ++# try { } ++# catch (e4) ++# { } ++# } + + # e5 can be a global string + global e5 = "foo" diff --git a/SOURCES/systemtap-dev_tapset.patch b/SOURCES/systemtap-dev_tapset.patch new file mode 100644 index 0000000..975a8b3 --- /dev/null +++ b/SOURCES/systemtap-dev_tapset.patch @@ -0,0 +1,59 @@ +commit ea6ec6da37f1d3ec9ab1c3b5808287676c9d3742 +Author: William Cohen +Date: Mon Jun 2 11:15:44 2025 -0400 + + RHEL-90805: Fix dev.stp tapset to work with RHEL 9.7 kernel + + RHEL 9.7 kernels have backported block dev support from Linux 6.14. + The test in the dev.stp tapset checked the kernel version to determine + where to get information and that test did not work in the case of + code backported to the older RHEL 9 Linux 5.14 kernel. The dev.stp + code has been reworked to search for the particular member field + holding the information instead. + +diff --git a/tapset/linux/dev.stp b/tapset/linux/dev.stp +index f6b90c5d3..56b8e63c4 100644 +--- a/tapset/linux/dev.stp ++++ b/tapset/linux/dev.stp +@@ -64,17 +64,19 @@ function disk_name:string(hd:long, partno:long) + return sprintf("%s%d", disk_name, partno) + } + +-%( kernel_v >= "6.10" %? + %{ ++#include + #include + %} + + function bdev_partno(bdev:long) + %{ /* pure */ /* unprivileged */ ++#ifdef BD_PARTNO + STAP_RETURN(bdev_partno((const struct block_device *) STAP_ARG_bdev)); ++#else ++ STAP_RETURN(0); ++#endif + %} +-%: +-%) + + function bdevname:string(bdev:long) + { +@@ -84,15 +86,13 @@ function bdevname:string(bdev:long) + + hd = bdev->bd_disk + +-%( kernel_v >= "6.10" %? +- partno = bdev_partno(bdev) +-%: +- if (@defined(@cast(bdev, "block_device", "kernel")->bd_partno)) ++ if (@defined(&bdev->__bd_flags)) ++ partno = bdev_partno(bdev) ++ else if (@defined(bdev->bd_partno)) + partno = bdev->bd_partno + else if (bdev->bd_part) + partno = bdev->bd_part->partno + else + partno = MINOR(bdev->bd_dev) - hd->first_minor; +-%) + return disk_name(hd, partno) + } diff --git a/SPECS/systemtap.spec b/SPECS/systemtap.spec index 230357a..1d586df 100644 --- a/SPECS/systemtap.spec +++ b/SPECS/systemtap.spec @@ -13,8 +13,8 @@ %endif %{!?with_rpm: %global with_rpm 1} %{!?elfutils_version: %global elfutils_version 0.179} -%{!?with_boost: %global with_boost 0} -%ifarch %{ix86} x86_64 ppc ppc64 ppc64le aarch64 +%{!?with_boost: %global with_boost 1} +%ifarch x86_64 ppc ppc64 ppc64le aarch64 %{!?with_dyninst: %global with_dyninst 0%{?fedora} >= 18 || 0%{?rhel} >= 7} %else %{!?with_dyninst: %global with_dyninst 0} @@ -45,6 +45,10 @@ %{!?with_httpd: %global with_httpd 0} %{!?with_specific_python: %global with_specific_python 0%{?fedora} >= 31} %{!?with_sysusers: %global with_sysusers 0%{?fedora} >= 32 || 0%{?rhel} >= 9} +# NB: can't turn this on by default on any distro version whose builder system +# may run kernels different than the distro version itself. +%{!?with_check: %global with_check 0} + # Virt is supported on these arches, even on el7, but it's not in core EL7 %if 0%{?rhel} && 0%{?rhel} <= 7 @@ -120,8 +124,8 @@ m stapdev stapdev Name: systemtap # PRERELEASE -Version: 5.2 -Release: 2%{?release_override}%{?dist} +Version: 5.3 +Release: 3%{?release_override}%{?dist} # for version, see also configure.ac @@ -133,7 +137,7 @@ Release: 2%{?release_override}%{?dist} # systemtap-runtime /usr/bin/staprun, /usr/bin/stapsh, /usr/bin/stapdyn # systemtap-client /usr/bin/stap, samples, docs, tapset(bonus), req:-runtime # systemtap-initscript /etc/init.d/systemtap, dracut module, req:systemtap -# systemtap-sdt-devel /usr/include/sys/sdt.h AND /usr/bin/dtrace +# systemtap-sdt-devel /usr/include/sys/sdt.h # systemtap-sdt-dtrace /usr/bin/dtrace # systemtap-testsuite /usr/share/systemtap/testsuite*, req:systemtap, req:sdt-devel # systemtap-runtime-java libHelperSDT.so, HelperSDT.jar, stapbm, req:-runtime @@ -158,7 +162,9 @@ Summary: Programmable system-wide instrumentation system License: GPL-2.0-or-later URL: https://sourceware.org/systemtap/ Source: ftp://sourceware.org/pub/systemtap/releases/systemtap-%{version}.tar.gz -Patch0: PR32302.patch + +Patch1: systemtap-defined.patch +Patch2: systemtap-dev_tapset.patch # Build* BuildRequires: make @@ -186,9 +192,7 @@ BuildRequires: pkgconfig(ncurses) BuildRequires: systemd %endif # Needed for libstd++ < 4.0, without -%if %{with_boost} BuildRequires: boost-devel -%endif %if %{with_crash} BuildRequires: crash-devel zlib-devel %endif @@ -242,8 +246,14 @@ BuildRequires: libmicrohttpd-devel BuildRequires: libuuid-devel %endif %if %{with_sysusers} -BuildRequires: systemd-rpm-macros +BuildRequires: systemd-rpm-macros %endif +%if %{with_check} +BuildRequires: kernel-devel +# and some of the same Requires: as below +BuildRequires: dejagnu gcc make +%endif + # Install requirements @@ -382,12 +392,13 @@ boot-time probing if supported. Summary: Static probe support header files License: GPL-2.0-or-later AND CC0-1.0 URL: https://sourceware.org/systemtap/ +# for RHEL buildability compatibility, pull in sdt-dtrace at all times +Requires: systemtap-sdt-dtrace = %{version}-%{release} %description sdt-devel This package includes the header file used for static instrumentation compiled into userspace programs. - %package sdt-dtrace Summary: Static probe support dtrace tool License: GPL-2.0-or-later AND CC0-1.0 @@ -595,8 +606,7 @@ or within a container. # ------------------------------------------------------------------------ %prep -%setup -q -%patch -P0 -p1 +%autosetup -p1 %build @@ -849,9 +859,18 @@ done %py3_shebang_fix %{buildroot}%{python3_sitearch} %{buildroot}%{_bindir}/* %endif +%check +%if %{with_check} +make check RUNTESTFLAGS=environment_sanity.exp +%endif + + %pre runtime %if %{with_sysusers} +%if (0%{?fedora} && 0%{?fedora} < 42) || (0%{?rhel} && 0%{?rhel} < 11) echo '%_systemtap_runtime_preinstall' | systemd-sysusers --replace=%{_sysusersdir}/systemtap-runtime.conf - +exit 0 +%endif %else getent group stapusr >/dev/null || groupadd -f -g 156 -r stapusr getent group stapsys >/dev/null || groupadd -f -g 157 -r stapsys @@ -859,23 +878,29 @@ getent group stapdev >/dev/null || groupadd -f -g 158 -r stapdev getent passwd stapunpriv >/dev/null || \ useradd -c "Systemtap Unprivileged User" -u 159 -g stapunpriv -d %{_localstatedir}/lib/stapunpriv -r -s /sbin/nologin stapunpriv 2>/dev/null || \ useradd -c "Systemtap Unprivileged User" -g stapunpriv -d %{_localstatedir}/lib/stapunpriv -r -s /sbin/nologin stapunpriv -%endif exit 0 +%endif %pre server %if %{with_sysusers} +%if (0%{?fedora} && 0%{?fedora} < 42) || (0%{?rhel} && 0%{?rhel} < 11) echo '%_systemtap_server_preinstall' | systemd-sysusers --replace=%{_sysusersdir}/systemtap-server.conf - +exit 0 +%endif %else getent group stap-server >/dev/null || groupadd -f -g 155 -r stap-server getent passwd stap-server >/dev/null || \ useradd -c "Systemtap Compile Server" -u 155 -g stap-server -d %{_localstatedir}/lib/stap-server -r -s /sbin/nologin stap-server 2>/dev/null || \ useradd -c "Systemtap Compile Server" -g stap-server -d %{_localstatedir}/lib/stap-server -r -s /sbin/nologin stap-server -%endif exit 0 +%endif %pre testsuite %if %{with_sysusers} +%if (0%{?fedora} && 0%{?fedora} < 42) || (0%{?rhel} && 0%{?rhel} < 11) echo '%_systemtap_testsuite_preinstall' | systemd-sysusers --replace=%{_sysusersdir}/systemtap-testsuite.conf - +exit 0 +%endif %else getent passwd stapusr >/dev/null || \ useradd -c "Systemtap 'stapusr' User" -g stapusr -r -s /sbin/nologin stapusr @@ -883,8 +908,8 @@ getent passwd stapsys >/dev/null || \ useradd -c "Systemtap 'stapsys' User" -g stapsys -G stapusr -r -s /sbin/nologin stapsys getent passwd stapdev >/dev/null || \ useradd -c "Systemtap 'stapdev' User" -g stapdev -G stapusr -r -s /sbin/nologin stapdev -%endif exit 0 +%endif %post server @@ -1246,8 +1271,6 @@ exit 0 %doc README AUTHORS NEWS %{!?_licensedir:%global license %%doc} %license COPYING -%{_bindir}/dtrace -%{_mandir}/man1/dtrace.1* %files sdt-dtrace @@ -1330,6 +1353,16 @@ exit 0 # PRERELEASE %changelog +* Thu Jun 5 2025 William Cohen - 5.3-3 +- RHEL-90805: Update dev.stp tapset to handle RHEL-9.7 kernels. + +* Mon May 12 2025 Martin Cermak - 5.3-2 +- RHEL-RHEL-89809: stap-server log owned by root + +* Fri May 02 2025 Frank Ch. Eigler - 5.3-1 +- Upstream release, see wiki page below for detailed notes. + https://sourceware.org/systemtap/wiki/SystemTapReleases + * Fri Nov 15 2024 Frank Ch. Eigler - 5.2-2 - RHEL-67586: supply /usr/bin/dtrace in sdt-devel subrpm too