[squid-dev] [PATCH] avoid clobbering errno in debugs()

Kinkie gkinkie at gmail.com
Sun Jul 12 05:45:52 UTC 2015


On Sun, Jul 12, 2015 at 2:34 AM, Amos Jeffries <squid3 at treenet.co.nz> wrote:

> On 12/07/2015 5:42 a.m., Kinkie wrote:
> > Hi all,
> >   this patch saves and restores errno around calls to strftime in
> > debugLogTime, preventing harmless errors in these calls from clobbering
> > errno, thus messing up xstrerror() calls within debugs().
> >
>
> 1) xerrno is a local variable in lots of places in the code. This patch
> introduces shadowing errors. Please call it debug_xerrno.
>

Ok, no problem.


> 2) The snprintf() call directly after restoring errno in the top chunk
> may alter the original errno in rare cases as well.
>

Are you sure? The snprintf manual page doesn't mention that.


> Which is a good example of why we simply can't rely on errno being
> correct for any length of time in C++. Things such as errno changes by
> operator<< implementations, print() methods, implicit calls to copy
> constructors/destructors, and exlicit function/method calls are also
> possible in ways we are unlikely to be predict.
>
>
> We are still going to have to do a global removal of xstrerror() anyway.
>

I do not object on the technical merit.
At the same time, there are too many to do it incrementally, and we already
failed to reach a consensus on flag-day commit for HERE removal. Sure,
maybe xstrerror()+HERE removal will reach a mass critical enough to support
the flag-day-commit camp, but I don't see that happening, and we already
have quite a but of rework due to HERE being left in changed code. We'd end
up for years with a half-done migration.


> IMO, we should move xstrerror() to Debugs.h and make it use the
> debug_xerrno local variable instead of errno.
>

Maybe we could change debugLogTime to return a std::string instead of a
const char *, and format it ourselves using a stringbuf instead of using
strftime. Or we could maybe do something like this:

int _squid_errno;
const char *xstrerror() {
  return xstrerr(_squid_errno);
}
#define debugs(SECTION, LEVEL, CONTENT) \
   do { \
        if ((Debug::level = (LEVEL)) <= Debug::Levels[SECTION]) { \
            Debug::sectionLevel = Debug::Levels[SECTION]; \
            _squid_errno = errno;
            std::ostream &_dbo=Debug::getDebugOut(); \
            if (Debug::level > DBG_IMPORTANT) \
                _dbo << SkipBuildPrefix(__FILE__)<<"("<<__LINE__<<")
"<<__FUNCTION__<<": "; \
            _dbo << CONTENT; \
            Debug::finishDebug(); \
        } \
   } while (/*CONSTCOND*/ 0)

This would make xstrerror only work within debugs(); maybe we could add a
guard against it by setting _squid_errno to some invalid value and checking
it in xstrerror. Yes, it's ugly.

But until we reach a consensus, I'd like authorization to move forward with
the revised patch I'm attaching. It's far from ideal, but it's a step.

-- 
    Francesco
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squid-cache.org/pipermail/squid-dev/attachments/20150712/43030d2b/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: debug-noclobber-errno-v2.patch
Type: text/x-patch
Size: 488 bytes
Desc: not available
URL: <http://lists.squid-cache.org/pipermail/squid-dev/attachments/20150712/43030d2b/attachment-0001.bin>


More information about the squid-dev mailing list