public inbox for systemtap@sourceware.org
 help / color / mirror / Atom feed
* Code maintenance / verbosity: macros, enums, and casts
@ 2020-07-21  2:54 Craig Ringer
  2020-07-21  4:11 ` Arkady
  2020-07-23  5:16 ` Craig Ringer
  0 siblings, 2 replies; 3+ messages in thread
From: Craig Ringer @ 2020-07-21  2:54 UTC (permalink / raw)
  To: systemtap

Hi all

TL;DR: I'd like to add DWARF-based @enum("foo","my.so") and am interested
in whether that'd be potentially mergeable + advice on where in the stap
code I might want to start.

------

I'm looking for advice from people more experienced with writing and
maintaining real world systemtap tapsets and tools to manage tapset
verbosity and make my tapsets reasonably maintainable.

As I write most stap code I'm increasingly finding that I produce a lot of
boilerplate, especially for member access via a @cast or @var, for mapping
enums to their long values; for mapping scalar integer macros to their long
values; for mapping the values of various enums back to their symbolic
names; and for comparing with C "char" literals.

Constants are definitely the biggest one right now. In addition to their
verbosity, if they're maintained in tapsets instead of looked up from the
probed code there's a risk that the tapset's idea of a given enum or macro
definition may not match what the code is using.

I write a lot of tapset boilerplate like:

@define FOO_BAR %( 0 %)
@define FOO_BAZ %( 0x63 %) // 'c'
@define FOO_BAK %( 0x64 %) // 'd'

function foo_str:string(foo:long) {
    if (foo == @FOO_BAR) return "BAR"
    if (foo == @FOO_BAZ) return "BAZ"
    if (foo == @FOO_BAK) return "BAK"
}

Add @enum("FOO_BAR", "my.so")
====

If these are defined in the sources as an enum, it'd be great to look them
up at stap compile time with a new @enum construct.

I'm wondering how feasible this might be and where I should start looking
if I want to try implementing it.

Enums are guaranteed to be evaluated to a constant value and they're in the
ELF .debug_info section. So there's no need to for the executable to have
-g3 / -ggdb3 debuginfo, the default is fine. And there are no problems with
evaluating expressions, since there's a constant pre-evaluated by the
compiler and embedded in the debuginfo.

I can get enum info with

   eu-readelf --debug-dump=info mylib.so

though I'm still trying to understand the elfutils / libdw api well enough
to actually access it...


Why not @const?
====

I'm aware of "@const" but there are a number of reasons it doesn't help me:

* It needs guru mode, which is really not desirable on production systems
(or you need to preinstall a tapset that exposes the constants which then
defeats the point);

* It doesn't provide a way to specify the header(s) to include to find the
constant, you have to handle that externally via a tapset or an explicit
guru-mode #include .

* man stap says "headers are built with default GCC parameters"; this means
there's no guarantee the values stap sees match what the program was
compiled with;

* It requires full headers of the probed lib/program to be available at
probe compile time, *including* transitive dependency headers included by
the program/lib headers, which is not always desirable or possible;

* The headers must be safely include-able including any/all headers they
include in turn, any required preprocessor definitions, etc. Some headers
have specific order-of-inclusion rules, may define or redefine symbols that
should not be exposed, etc;

* "stap" doesn't appear provide a simple way to specify the include path to
search for such headers

What about macros?
====

Macros are harder.

They're only present if -g3 or -ggdb3 was used at build-time, which is
still not the norm even though the results are much more compact now than
they used to be. Most packages don't use dwz to compact their debuginfo
either.

Even if present in the .debug_macro ELF section, the macro definitions may
be arbitrary C expressions. They are not guaranteed to be literal integers
or strings. gdb knows how to evaluate expressions when attached to a
process, but I don't think it can do so statically. So using macro
definitions from debuginfo will only work in cases where the macro
definition is simple. It'd still be really handy.

There's

    eu-readelf --debug-dump=macro some.so

and there's libdw's dwarf_getmacros() etc so the foundations are there.

I'd definitely want to start with @enum first though.

Then only add a @dwarf_macro later, if feasible, and probably restricted to
simple numeric or string literals.

-- 
 Craig Ringer                   http://www.2ndQuadrant.com/
 2ndQuadrant - PostgreSQL Solutions for the Enterprise

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-07-23  5:16 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-21  2:54 Code maintenance / verbosity: macros, enums, and casts Craig Ringer
2020-07-21  4:11 ` Arkady
2020-07-23  5:16 ` Craig Ringer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).