From 0e1d5b7eb39785cbafe0c0fb1c4e5e3d21576aab Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Fri, 14 Feb 2020 16:10:22 -0500 Subject: [PATCH] @var() diagnostics: generate more dwarf detail & context For TLS-related variables like @var("errno") in glibc, some useful diagnostic details were just dropped on the floor as semantic_error objects were caught but not printed. New code tries to arrange for these to be chained instead of lost. In exchange, more errors would propagate to session.print_error as chained to the target_symbol, so now the code also has to duplicate-eliminate the chained errors. The net result is that at verbosity 0 or 1, we appear to get only a few specific and valuable incremental messages, which point to the problematic dwarf. It would be nice to simplify this stuff, perhaps by storing context (script-source level data, dwarf pointers, dwarf contents, etc.) as RAII style global stack of "current details". --- NEWS | 4 ++++ dwflpp.cxx | 16 ++++++++++++++-- session.cxx | 6 +++--- tapsets.cxx | 6 ++++-- 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/NEWS b/NEWS index 567de3fff..92d82ae74 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,9 @@ * What's new in version 4.3, PRERELEASE +- More $variable resolution errors may be generated, especially for + @var("") constructs that target global variables. These are + duplicate-eliminated by default, but may be seen with verbosity>=2. + - The stapbpf backend now supports try-catch statements, an improved error tapset and error probes. diff --git a/dwflpp.cxx b/dwflpp.cxx index f8531430d..c3f1c1685 100644 --- a/dwflpp.cxx +++ b/dwflpp.cxx @@ -2788,9 +2788,10 @@ dwflpp::find_variable_and_frame_base (vector& scopes, vardie); if (declaring_scope < 0) { + // XXX: instead: add suggested locals and let a caller throw a single error set locals; get_locals(scopes, locals); - string sugs = levenshtein_suggest(local, locals); // probably not that many, so no limit + string sugs = levenshtein_suggest(local, locals, 5); if (pc) throw SEMANTIC_ERROR (_F("unable to find local '%s', [man error::dwarf] dieoffset %s in %s, near pc %s %s %s %s (%s)", local.c_str(), @@ -3245,7 +3246,18 @@ dwflpp::translate_location(location_context *ctx, ctx->pc = pc; ctx->dw = this; - return ctx->translate_location (expr, len, input); + try + { + return ctx->translate_location (expr, len, input); + } + catch (const semantic_error& er) + { + // copy lower level loc2stap exception; add a DIE# to it so user + // has a chance to find the problematic raw debuginfo + semantic_error err(er); + err.details.push_back(die_location_as_string(die)); + throw err; + } } diff --git a/session.cxx b/session.cxx index 3720f150e..e2dadf00d 100644 --- a/session.cxx +++ b/session.cxx @@ -2369,11 +2369,11 @@ systemtap_session::print_error (const semantic_error& se) } // duplicate elimination - if (verbose > 0 || seen_errors[se.errsrc_chain()] < 1) + if (verbose > 0 || seen_errors[se.errsrc_chain()]++ < 1) { - seen_errors[se.errsrc_chain()]++; for (const semantic_error *e = &se; e != NULL; e = e->get_chain()) - cerr << build_error_msg(*e); + if (verbose > 1 || seen_errors[e->errsrc]++ < 1) // dupe-eliminate chained errors too + cerr << build_error_msg(*e); } else suppressed_errors++; } diff --git a/tapsets.cxx b/tapsets.cxx index aab7c8367..61e479c85 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -5066,8 +5066,10 @@ dwarf_atvar_query::atvar_query_cu (Dwarf_Die * cudie, dwarf_atvar_query *q) } catch (const semantic_error& er) { - // Here we suppress the error because we often just have too many - // when scanning all the CUs. + if (q->sess.verbose > 3) + clog << "chaining to " << q->e.tok << endl + << q->sess.build_error_msg(er) << endl; + q->e.chain (er); return DWARF_CB_OK; } -- 2.43.5