lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] Suppressing exception stack dumps


From: Greg Chicares
Subject: Re: [lmi] Suppressing exception stack dumps
Date: Thu, 18 Mar 2021 00:45:22 +0000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.4.0

On 3/17/21 8:05 PM, Vadim Zeitlin wrote:
> On Wed, 17 Mar 2021 18:21:05 +0000 Greg Chicares <gchicares@sbcglobal.net> 
> wrote:
> 
>  I really think the solution to this is using a debugger. It's a brute
> force and less elegant option, but just a much more efficient one and
> you're never going to be able to replicate it in lmi itself (because
> breakpoints can be conditional and execute arbitrary gdb commands when hit,
> which makes them much more powerful than doing anything unconditionally).

But suppose I've done a series of operations in lmi's GUI, and an
exception is thrown. I might not remember everything I did, and
might not be able to reproduce the problem later when running under
a debugger. Then an automatic backtrace is invaluable.

Besides, I never really liked debuggers very much. It's not that
I'm unfamiliar with them: I've set conditional breakpoints, and
changed data and run arbitrary code when they're hit. I just never
enjoyed using them. If I want to know what values some variables
have at some point, I automatically type

  warning()
    << z << " z\n"
    << LMI_FLUSH
    ;

and then duplicate the "z" line, search for \<z\>, and
change-inner-word to whatever variables I want. Tastes will
differ, of course, but this is my preference.

> GC> Commit e0c15aab3 provides an on-off toggle, and toggles the backtrace
> GC> off in a handful of places where we know we don't want it.
> 
>  Thanks, I'm going to test it a.s.a.p. but it should indeed fix the
> immediate problem.

A tangential question occurs to me. In that commit, I had thought of
using a static member instead of a global variable to toggle the
"trace" output. Then I thought that I'd heard of a reason not to do
that, and found it with git-grep:

gpt_test.cpp:// These could be made static members of class gpt_test, but this 
way
gpt_test.cpp://   
https://www.securecoding.cert.org/confluence/display/cplusplus/MSC22-CPP.+Do+not+define+static+private+members

Intrigued, I tried following that link, but it's gone, and that
site doesn't seem to advise against the practice any more. Is this
a good guideline, for some reason I don't remember and cannot now
imagine? (I've found some of that site's recommendations dubious.)

Do you have any strong opinion about that global variable?
I tend to think that it's okay, and that it's better for it to
be separate from the "toggler" class, but I'm not really sure.

>  The fundamental question about whether this exception stack reporting
> should be enabled or disabled by default remains, however. IMO, as any
> debugging helper, it must be disabled because the users really don't care
> about this, but it may introduce some problems (more code to execute means
> not only some, not that small in this case, overhead, but more chances of
> something going wrong). Of course, right now no end users use a version
> where this functionality is available, but if this changes in the future
> (e.g. because we implement it for MSW too), I strongly believe this
> shouldn't be enabled in production builds by default.

Let me make a case for the opposite position, to which I lean.

We don't have multiple builds, one for development and another
for production. I know some people do that, but it strikes me as
dangerous, because an issue present in production might not be
observed in development. To me at least, it seems wiser to eat
the same food we're serving.

(We do create binaries with libstdc++ debugging enabled, but
only for some automated tests. And I find myself using
pc-linux-gnu binaries more and more, because they build faster,
and because some handy tools are useful only with pc-linux-gnu:
linux-perf, certainly, and also gdb, which, in my experience,
is not practical to use under 'wine'. But I do regularly run
the same code we distribute to users.)

Because lmi is distributed only as msw binaries that end users
run via 'shortcuts', we can write developer-only output to the
console, and end users don't see it, even though we're running
the same binaries. We've been doing that for quite some time
with warning() and alarum(), which generate messages that are
much easier to cut and paste from a console. Now we're doing
the same for '--pyx=show_7702i' and for backtraces.

Users don't see console output, so it can't confuse them.
Backtraces in particular do have non-negligible overhead, and
the code that generates them may have defects, true; but any
defect that occurs with any frequency will probably be found
and fixed quickly, and exception-reporting overhead isn't
incurred unless an exception is thrown (and unwound).

> GC> > +    if (std::strcmp(std::getenv("LMI_VERBOSE_EXCEPTIONS"), "1") == 0)
> GC> 
> GC> That would offer much flexibility. But nothing else in lmi's C++ code
> GC> reads the environment (except getopt(), as I was surprised to find).
> GC> For pc-linux-gnu, it doesn't make much difference, but for msw, getenv()
> GC> it has some drawbacks:
> 
>  Please feel free to ignore everything below, but I don't think any of
> these drawbacks is actually relevant.
[...big snip...]
>  From practical experience of using it in all my code
> (including wxWidgets, BTW, which means that lmi already uses it too) for
> 25+ years, I've never, ever had any shadow of a problem due to using it and
> I just don't understand how could it ever happen.

Okay, I was thinking of anathematizing it, and hence eradicating it
from 'getopt.cpp', but now I won't do that.

> GC> Except in situations where lmi catches an exception and does something
> GC> interesting (e.g., displaying an abridged what() string),
> 
>  I wonder if what you really want is not this, instead:
> 
> 1. Remember the stack when the exception is thrown (but _not_ print it out)
> 2. Show this stack if the exception is caught in one of the top-level catch
>    statements, i.e. not caught before by some handler actually knowing what
>    to do with it.
> 
> ?

That's an intriguing idea. Right now, I don't know if it'll
be worth the effort, but I'll keep it in mind if further
experience makes the present backtrace seem more inconvenient.

> GC> I usually want
> GC> to see a backtrace automatically. Restarting the program with a change
> GC> in its environment is less convenient--often, extremely less. And if I
> GC> don't want it, I just disregard it.
> 
>  IMHO this just means that you ought to set LMI_VERBOSE_EXCEPTIONS in your
> environment, but all this doesn't apply to lmi users at all (it also
> doesn't apply to me, but this is a much lesser problem, of course).

I'm wary of needing to customize too many switches. I rely on
plenty already--e.g., .rc files, and command-line switches in
makefiles--but adding and maintaining new ones does have a cost.

But I think practical experience should be our guide. I'd like
to know of any concrete circumstances where this backtrace is
inconvenient for you (now that I've suppressed it in unit tests).


reply via email to

[Prev in Thread] Current Thread [Next in Thread]