[Libreoffice] Assertions and Logging

Michael Stahl mstahl at redhat.com
Tue Nov 22 03:46:52 PST 2011


On 18/11/11 15:25, Stephan Bergmann wrote:
> The downside of that mixture is that the useful debugging technique of 
> aborting upon detection of a violated invariant is not available.---If 
> you make OSL_ASSERT (and OSL_ENSURE, OSL_FAIL, etc.) abort, it will 
> abort far too often for mundane warnings for it to be useful.

indeed, the current state of tens of thousands of assertions firing on a
subsequentcheck run is pretty awful, this needs to be sorted out to have
the really bad assertions actually demand developer attention by calling
abort.

[...]

> 3  Furthermore, there is sometimes demand for additional, debug-only 
> code.  In general, that would be safety-check additions that are 
> considered too expensive to be included in production builds (e.g., code 
> that iterates over a data structure to check invariants, or additional, 
> redundant fields within data structures).  Enabling such additional code 
> potentially affects compatibility.
> 
> Such additional code is currently controlled via OSL_DEBUG_LEVEL et al. 
>   OSL_DEBUG_LEVEL==1 is generally used for additions that do not affect 
> compatibility (as it is enabled by both --enable-debug and 
> --enable-dbgutil).  OSL_DEBUG_LEVEL==2, DBG_UTIL (defined upon 
> --enable-dbguitl) and privately invented defines in certain parts of the 
> code (to be set manually by knowledgeable developers) are used for 
> additions that affect compatibility or that are considered too specific 
> for general inclusion.  Either because they are too expensive even for 
> every --enable-dbgutil build, or because they produce excessive log 
> information (for which case the below new log functionality offers a 
> better solution).

one requirement i would have on conditional compilation is that, whether
--disable-dbgutil or --enable-dbgutil, objects built with debug=t
(resulting in OSL_DEBUG_LEVEL being set to non-zero) should always be
binary compatible with objects built without debug=t.

this makes e.g. tracking down bugs introduced by mis-optimisation much
easier; i think we are in agreement on this point.

> This can probably be reduced to three cases:
> 
> #if OSL_DEBUG_LEVEL != 0  for additional code that does not cause 
> incompatibilities (if there is still demand for such code; the new log 
> functionality will remove the need for such code in many cases).  This 
> effectively reduces OSL_DEBUG_LEVEL to a binary switch (so the make 
> dbglevel=x feature can be removed; and OSL_DEBUG_LEVEL could potentially 
> be renamed---but that would probably not be worth it).
> 
> #if defined DBG_UTIL  for additional code that causes incompatibilities.

i think i've seen members of SwDoc being added with:
 #if OSL_DEBUG_LEVEL > 1
 #if OSL_DEBUG_LEVEL > 0
this kind of thing always struck me as wrong: it should be DBG_UTIL,
will try to clean that up a bit...

> #if defined MY_SPECIAL_DEBUG  (replaced with actual defines, varying 
> across the different code modules) for those special cases where always 
> enabling the additional code is deemed to expensive in general. 
> (However, for those special cases where the additional code produces 
> excess log information, see below.)

in these cases it is expected that the macro only affects a single
module, and the author knows what he/she is doing, so no guarantees on
binary compatibility required.

>>     Whether these macros generate any log output is controlled in a two-stage
>>     process.
>>
>>     First, at compile time the macro SAL_LOG_LEVEL controls whether these macros
>>     expand to actual code, or to no-ops.  SAL_LOG_LEVEL must expand to an
>>     integral value 0, 1, or 2.
>>
>>     If SAL_LOG_LEVEL is 0, neither the INFO nor the WARN macros produce code.
>>     If SAL_LOG_LEVEL is 1, only the WARN macros produce code.  If SAL_LOG_LEVEL
>>     is 2, both the INFO and the WARN macros produce code.

hmmm... i wonder if it makes sense to not distinguish between warnings
and info at compile-time (given that it is only active on debug builds
anyway), so it is not required to recompile a module to get full debug
output...

>>     Second, at runtime the environment variable SAL_LOG further limits which
>>     macro calls actually generate log output.  The environment varialbe SAL_LOG
>>     must either be unset or must match the regular expression

>>     If the environment variable is unset, "+WARN" is used instead (which results
>>     in all warnings being output but no infos).  If the given value does not
>>     match the regular expression, "+INFO+WARN" is used instead (which in turn
>>     results in everything being output).

... with the runtime default being to output only warnings, as above.

>>     A given macro call's level (INFO or WARN) and area is matched against the
>>     given switches as follows:  Only those switches for which the level matches
>>     the given level and for which the area is a prefix (including both empty and
>>     full prefixes) of the given area are considered.  Log output is generated if
>>     and only if among the longest such switches (if any), there is at least one
>>     that has a sense of "+".  (That is, if both +WARN.foo and -WARN.foo are
>>     present, +WARN.foo wins.)
>>
>>     For example, if SAL_LOG is "+INFO-INFO.foo+INFO.foo.bar", then calls like
>>     SAL_INFO("foo.bar", ...), SAL_INFO("foo.bar.baz", ...), or
>>     SAL_INFO("other", ...) generate output, while calls like
>>     SAL_INFO("foo", ...) or SAL_INFO("foo.barzzz", ...) do not.

(de-)activating by module is very useful, as everybody who has been
overwhelmed by the full debug output from e.g. sal would probably agree...

in summary, sounds like a good plan :)



More information about the LibreOffice mailing list