public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jonathan Wakely <jwakely@redhat.com>
To: "François Dumont" <frs.dumont@gmail.com>
Cc: "libstdc++@gcc.gnu.org" <libstdc++@gcc.gnu.org>,
	gcc-patches <gcc-patches@gcc.gnu.org>
Subject: Re: [_GLIBCXX_DEBUG] Enhance rendering of assert message
Date: Tue, 25 May 2021 22:10:17 +0100	[thread overview]
Message-ID: <YK1nud6OKBYRzDWW@redhat.com> (raw)
In-Reply-To: <6e9705ca-518b-b535-4f5a-fc748306ec9e@gmail.com>

On 25/05/21 23:01 +0200, François Dumont wrote:
>On 25/05/21 11:58 am, Jonathan Wakely wrote:
>>On 22/05/21 22:08 +0200, François Dumont via Libstdc++ wrote:
>>>Here is the part of the libbacktrace patch with the enhancement to 
>>>the rendering of assert message.
>>>
>>>It only contains one real fix, the rendering of address. In 2 
>>>places it was done with "0x%p", so resulting in something like: 
>>>0x0x012345678
>>>
>>>Otherwise it is just enhancements, mostly avoiding intermediate 
>>>buffering.
>>>
>>>I am adding the _Parameter::_Named type to help on the rendering. 
>>>I hesitated in doing the same for the _M_iterator type but 
>>>eventually managed it with a template function.
>>>
>>>    libstdc++: [_GLIBCXX_DEBUG] Enhance rendering of assert message
>>>
>>>    Avoid building an intermediate buffer to print to stderr, push 
>>>directly to stderr.
>>>
>>>    libstdc++-v3/ChangeLog:
>>>
>>>            * include/debug/formatter.h
>>>            (_Error_formatter::_Parameter::_Named): New.
>>>            (_Error_formatter::_Parameter::_Type): Inherit latter.
>>>            (_Error_formatter::_Parameter::_M_integer): Likewise.
>>>            (_Error_formatter::_Parameter::_M_string): Likewise.
>>>            * src/c++11/debug.cc: Include <cstring>.
>>>            (_Print_func_t): New.
>>>            (print_raw(PrintContext&, const char*, ptrdiff_t)): New.
>>>            (print_word): Use '%.*s' format in fprintf to render 
>>>only expected number of chars.
>>>            (pretty_print(PrintContext&, const char*, 
>>>_Print_func_t)): New.
>>>            (print_type): Rename in...
>>>            (print_type_info): ...this. Use pretty_print.
>>>            (print_address, print_integer): New.
>>>            (print_named_name, print_iterator_constness, 
>>>print_iterator_state): New.
>>>            (print_iterator_seq_type): New.
>>>            (print_named_field, print_type_field, 
>>>print_instance_field, print_iterator_field): New.
>>>            (print_field): Use latters.
>>>            (print_quoted_named_name, print_type_type, print_type, 
>>>print_instance): New.
>>>            (print_string(PrintContext&, const char*, const 
>>>_Parameter*, size_t)):
>>>            Change signature to...
>>>            (print_string(PrintContext&, const char*, ptrdiff_t, 
>>>const _Parameter*, size_t)):
>>>            ...this and adapt. Remove intermediate buffer to 
>>>render input string.
>>>            (print_string(PrintContext&, const char*, ptrdiff_t)): New.
>>>
>>>Ok to commit ?
>>>
>>>François
>>>
>>
>>>+  void
>>>+  pretty_print(PrintContext& ctx, const char* str, _Print_func_t 
>>>print_func)
>>>+  {
>>>+    const char cxx1998[] = "__cxx1998::";
>>>+    const char uglification[] = "__";
>>>+    for (;;)
>>>+      {
>>>+    auto idx = strstr(str, uglification);
>>
>>This is confusing. strstr returns a pointer, not an index into the
>>string.
>>
>>>+    if (idx)
>>>+      {
>>>+        size_t offset =
>>>+          (idx == strstr(str, cxx1998)
>>>+           ? sizeof(cxx1998) : sizeof(uglification)) - 1;
>>
>>This is a bit inefficient. Consider "int __foo(__cxx1998::bar)". The
>>first strstr returns a pointer to "__foo" and then the second one
>>searches the entire string from the beginning looking for
>>"__cxx1998::", and checks if it is the same position as "__foo".
>>
>>The second strstr doesn't need to search from the beginning, and it
>>doesn't need to look all the way to the end. It should be memcmp.
>>
>>      if (auto pos = strstr(str, uglification))
>>        {
>>          if (pos != str)
>>            print_func(ctx, str, pos - str);
>>
>>          if (memcmp(pos, cxx1998, sizeof(cxx1998)-1) == 0)
>>            str = pos + (sizeof(cxx1998) - 1);
>>          else
>>            str = pos + (sizeof(uglification) - 1);
>>                      while (*str && isspace((unsigned char)*str))
>>            ++str;
>>
>>          if (!*str)
>>            break;
>>        }
>>      else
>>
>>It doesn't even need to search from the position found by the first
>>strstr, because we already know it starts with "__", so:
>>
>>  for (;;)
>>    {
>>      if (auto pos = strstr(str, "__"))
>>        {
>>          if (pos != str)
>>            print_func(ctx, str, pos - str);
>>
>>          pos += 2; // advance past "__"
>>
>>          if (memcmp(pos, "cxx1998::", 9) == 0)
>>            str = pos + 9; // advance past "cxx1998::"
>>                      while (*str && isspace((unsigned char)*str))
>>            ++str;
>>
>>          if (!*str)
>>            break;
>>        }
>>      else
>>
>>But either is OK. Just not doing a second strstr through the entire
>>string again to look for "__cxx1998::".
>>
>>
>>
>>>+
>>>+        if (idx != str)
>>>+          print_func(ctx, str, idx - str);
>>>+
>>>+        str = idx + offset;
>>>+
>>>+        while (*str && isspace((unsigned char)*str))
>>>+          ++str;
>>
>>Is this really needed?
>>
>>Why would there be whitespace following "__" or "__cxx1998::" and why
>>would we want to skip it?
>
>Yes, I cannot remember why I added it in the first place. So removed 
>in this new proposal with your other changes.
>
>>
>>I know it doesn't follow our usual naming scheme, but a symbol like
>>"__foo__ bar()" would get printed as "foobar()" wouldn't it?
>>
>Yes, it would.
>>The rest of the patch looks fine, I'm just unsure about pretty_print.
>>Maybe I've misunderstood the possible strings it gets used with?
>>
>pretty_print is used for demangle type names, variable names and 
>function names given by the __PRETTY_FUNCTION__ macro.
>
>So in theory yes, __foo__bar would be replaced by foobar but I 
>considered that we will never face this situation for the moment.
>
>When considering backtraces we might have to review this.
>
>Ok to commit ?

OK for trunk, thanks.



      reply	other threads:[~2021-05-25 21:10 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-22 20:08 François Dumont
2021-05-25  9:58 ` Jonathan Wakely
2021-05-25 21:01   ` François Dumont
2021-05-25 21:10     ` Jonathan Wakely [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YK1nud6OKBYRzDWW@redhat.com \
    --to=jwakely@redhat.com \
    --cc=frs.dumont@gmail.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=libstdc++@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).