[PATCH] Refactor debug routines.
Ondřej Bílka
neleai@seznam.cz
Sun Jan 12 13:52:00 GMT 2014
On Mon, Dec 23, 2013 at 03:03:30AM -0500, Mike Frysinger wrote:
> On Tuesday 03 December 2013 20:39:53 OndÅej BÃlka wrote:
> > On Sat, Nov 30, 2013 at 02:24:12AM -0500, Mike Frysinger wrote:
> > >
> > > that strlen means you can scan the entire source string twice. seems
> > > like this overall change might win in some cases, but lose in others.
> > >
> > > i think it's safe to assume that the xxx_chk variants are becoming more
> > > common (i think all the major distros use it by default now) which means
> > > we need to be concerned with their performance.
> > >
> > > that means if an arch wants this to perform, then they should implement
> > > it which includes the destlen check.
> >
> > As this is at most twice slower than nonchecking variant its relatively
> > reasonable. Worse problem was x64 assembly code which was based on old
> > implementation and now is around five times slower than this code.
> >
> > A one-pass implementation could be done if we add a stpcat/stpncat
> > functions that returns end of string, these are usefull on their own as it
> > make easier avoid quadratic loops by concenating strings / letting gcc use
> > that optimization.
> >
> > dest[0] = '\0';
> > char *end = stpncat (dest, src, destlen);
> > if (end - dest == destlen)
> > __chk_fail ();
>
> every once in a while i run into situations where i wish there were more stp
> variants of existing funcs. maybe worth proposing as GNU extensions ?
>
I could send that in 2.20.
> > > > {
> > > > - char *s1 = dest;
> > > > - const char *s2 = src;
> > > > - char c;
> > > > -
> > > > - /* Find the end of the string. */
> > > > - do
> > > > - {
> > > > - if (__builtin_expect (destlen-- == 0, 0))
> > > > - __chk_fail ();
> > > > - c = *s1++;
> > > > - }
> > > > - while (c != '\0');
> > > > ...
> > > > + size_t destlen = strlen (dest);
> > >
> > > the dest strlen scan makes sense as we have to do that anyways (find the
> > > terminating NUL). however, you'll notice that this new version lost a
> > > check the old one had -- what if dest string lacks a NUL within its
> > > bounds ? yes, you would catch it below in your single check, but it
> > > might be too late by that point -- you might have scanned off into
> > > invalid memory and simply crashed. i think you should use strnlen
> > > (dest, totalen) instead and check the return value explicitly.
> >
> > I did that for performance reasons as segfault is similarly easy to
> > debug. A strnlen would only mostly work, bound here is not tight, if you
> > have
> >
> > if (c)
> > x = malloc (100);
> > else
> > x = malloc (1000);
> >
> > then 1000 will be used as bound.
>
> one of the nice things about fortify is that it provides nice abort messages
> rather than just a segfault. the former are generally taken pretty seriously
> while the latter are sometimes shrugged off as random flakes.
>
> if the performance degradation is significant, i could live with your variant.
I wrote that on assumption that these are equivalent where it would be a
performance degradation with no reason. With that information even more
expensive checks become feasible.
More information about the Libc-alpha
mailing list