Message ID | a1afcbea-4657-d356-a3ec-519188298bb3@gmail.com |
---|---|
State | New |
Headers | show |
Series | Add _GLIBCXX_DEBUG backtrace generation | expand |
Gentle reminder. On 13/07/22 19:26, François Dumont wrote: > libstdc++: [_GLIBCXX_DEBUG] Add backtrace generation on demand > > Add _GLIBCXX_DEBUG_BACKTRACE macro to activate backtrace generation > on _GLIBCXX_DEBUG assertions. Prerequisite is to have configure the > lib with: > > --enable-libstdcxx-backtrace=yes > > libstdc++-v3/ChangeLog: > > * include/debug/formatter.h > [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_state): Declare. > [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_create_state): Declare. > [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full_callback): Define. > [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_error_callback): Define. > [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full_func): Define. > [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full): Declare. > [_GLIBCXX_HAVE_STACKTRACE](_Error_formatter::_M_backtrace_state): New. > [_GLIBCXX_HAVE_STACKTRACE](_Error_formatter::_M_backtrace_full): New. > * src/c++11/debug.cc (pretty_print): Rename into... > (print_function): ...that. > [_GLIBCXX_HAVE_STACKTRACE](print_backtrace): New. > (_Error_formatter::_M_error()): Adapt. > * src/libbacktrace/Makefile.am: Add backtrace.c. > * src/libbacktrace/Makefile.in: Regenerate. > * src/libbacktrace/backtrace-rename.h (backtrace_full): New. > * testsuite/23_containers/vector/debug/assign4_neg.cc: Add backtrace > generation. > * doc/xml/manual/debug_mode.xml: Document _GLIBCXX_DEBUG_BACKTRACE. > * doc/xml/manual/using.xml: Likewise. > > Tested under Linux x86_64 normal and _GLIBCXX_DEBUG modes. > > Ok to commit ? > > François
On Wed, 13 Jul 2022 at 18:28, François Dumont via Libstdc++ <libstdc++@gcc.gnu.org> wrote: > > libstdc++: [_GLIBCXX_DEBUG] Add backtrace generation on demand > > Add _GLIBCXX_DEBUG_BACKTRACE macro to activate backtrace generation > on _GLIBCXX_DEBUG assertions. Prerequisite is to have configure the lib > with: > > --enable-libstdcxx-backtrace=yes > > libstdc++-v3/ChangeLog: > > * include/debug/formatter.h > [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_state): Declare. > [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_create_state): Declare. > [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full_callback): Define. > [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_error_callback): Define. > [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full_func): Define. > [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full): Declare. > [_GLIBCXX_HAVE_STACKTRACE](_Error_formatter::_M_backtrace_state): New. > [_GLIBCXX_HAVE_STACKTRACE](_Error_formatter::_M_backtrace_full): New. > * src/c++11/debug.cc (pretty_print): Rename into... > (print_function): ...that. This does more than just rename it, what are the other changes for? > [_GLIBCXX_HAVE_STACKTRACE](print_backtrace): New. > (_Error_formatter::_M_error()): Adapt. > * src/libbacktrace/Makefile.am: Add backtrace.c. > * src/libbacktrace/Makefile.in: Regenerate. > * src/libbacktrace/backtrace-rename.h (backtrace_full): New. > * testsuite/23_containers/vector/debug/assign4_neg.cc: Add backtrace > generation. > * doc/xml/manual/debug_mode.xml: Document _GLIBCXX_DEBUG_BACKTRACE. > * doc/xml/manual/using.xml: Likewise. > > Tested under Linux x86_64 normal and _GLIBCXX_DEBUG modes. > > Ok to commit ? >--- a/libstdc++-v3/testsuite/23_containers/vector/debug/assign4_neg.cc >+++ b/libstdc++-v3/testsuite/23_containers/vector/debug/assign4_neg.cc >@@ -16,6 +16,7 @@ > // <http://www.gnu.org/licenses/>. > // > // { dg-do run { xfail *-*-* } } >+// { dg-options "-D_GLIBCXX_DEBUG_BACKTRACE -lstdc++_libbacktrace" } > > #include <debug/vector> > #include <debug/checks.h> This will fail to link if the static lib isn't available.
On 08/08/22 15:29, Jonathan Wakely wrote: > On Wed, 13 Jul 2022 at 18:28, François Dumont via Libstdc++ > <libstdc++@gcc.gnu.org> wrote: >> libstdc++: [_GLIBCXX_DEBUG] Add backtrace generation on demand >> >> Add _GLIBCXX_DEBUG_BACKTRACE macro to activate backtrace generation >> on _GLIBCXX_DEBUG assertions. Prerequisite is to have configure the lib >> with: >> >> --enable-libstdcxx-backtrace=yes >> >> libstdc++-v3/ChangeLog: >> >> * include/debug/formatter.h >> [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_state): Declare. >> [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_create_state): Declare. >> [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full_callback): Define. >> [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_error_callback): Define. >> [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full_func): Define. >> [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full): Declare. >> [_GLIBCXX_HAVE_STACKTRACE](_Error_formatter::_M_backtrace_state): New. >> [_GLIBCXX_HAVE_STACKTRACE](_Error_formatter::_M_backtrace_full): New. >> * src/c++11/debug.cc (pretty_print): Rename into... >> (print_function): ...that. > This does more than just rename it, what are the other changes for? Nothing, I'm starting to remember what you did on this, reverted. > > >> [_GLIBCXX_HAVE_STACKTRACE](print_backtrace): New. >> (_Error_formatter::_M_error()): Adapt. >> * src/libbacktrace/Makefile.am: Add backtrace.c. >> * src/libbacktrace/Makefile.in: Regenerate. >> * src/libbacktrace/backtrace-rename.h (backtrace_full): New. >> * testsuite/23_containers/vector/debug/assign4_neg.cc: Add backtrace >> generation. >> * doc/xml/manual/debug_mode.xml: Document _GLIBCXX_DEBUG_BACKTRACE. >> * doc/xml/manual/using.xml: Likewise. >> >> Tested under Linux x86_64 normal and _GLIBCXX_DEBUG modes. >> >> Ok to commit ? > >> --- a/libstdc++-v3/testsuite/23_containers/vector/debug/assign4_neg.cc >> +++ b/libstdc++-v3/testsuite/23_containers/vector/debug/assign4_neg.cc >> @@ -16,6 +16,7 @@ >> // <http://www.gnu.org/licenses/>. >> // >> // { dg-do run { xfail *-*-* } } >> +// { dg-options "-D_GLIBCXX_DEBUG_BACKTRACE -lstdc++_libbacktrace" } >> >> #include <debug/vector> >> #include <debug/checks.h> > This will fail to link if the static lib isn't available. > Good point ! So I am introducing a new test case with the necessary dg directive. It is a 'run' test case even if what is really tested is only the compilation/link part. For the run part someone has to look at the log file. François
After a second thought here is an even cleaner version. No more function rename, current pretty_print is fine. libstdc++: [_GLIBCXX_DEBUG] Add backtrace generation on demand Add _GLIBCXX_DEBUG_BACKTRACE macro to activate backtrace generation on _GLIBCXX_DEBUG assertions. Prerequisite is to have configure the lib with: --enable-libstdcxx-backtrace=yes libstdc++-v3/ChangeLog: * include/debug/formatter.h [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_state): Declare. [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_create_state): Declare. [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full_callback): Define. [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_error_callback): Define. [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full_func): Define. [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full): Declare. [_GLIBCXX_HAVE_STACKTRACE](_Error_formatter::_M_backtrace_state): New. [_GLIBCXX_HAVE_STACKTRACE](_Error_formatter::_M_backtrace_full): New. * src/c++11/debug.cc [_GLIBCXX_HAVE_STACKTRACE](print_backtrace): New. (_Error_formatter::_M_error()): Adapt. * src/libbacktrace/Makefile.am: Add backtrace.c. * src/libbacktrace/Makefile.in: Regenerate. * src/libbacktrace/backtrace-rename.h (backtrace_full): New. * testsuite/23_containers/vector/debug/assign4_backtrace_neg.cc: New test. * doc/xml/manual/debug_mode.xml: Document _GLIBCXX_DEBUG_BACKTRACE. * doc/xml/manual/using.xml: Likewise. Ok to commit ? François On 09/08/22 10:07, François Dumont wrote: > On 08/08/22 15:29, Jonathan Wakely wrote: >> On Wed, 13 Jul 2022 at 18:28, François Dumont via Libstdc++ >> <libstdc++@gcc.gnu.org> wrote: >>> libstdc++: [_GLIBCXX_DEBUG] Add backtrace generation on demand >>> >>> Add _GLIBCXX_DEBUG_BACKTRACE macro to activate backtrace generation >>> on _GLIBCXX_DEBUG assertions. Prerequisite is to have configure the lib >>> with: >>> >>> --enable-libstdcxx-backtrace=yes >>> >>> libstdc++-v3/ChangeLog: >>> >>> * include/debug/formatter.h >>> [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_state): Declare. >>> [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_create_state): Declare. >>> [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full_callback): Define. >>> [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_error_callback): Define. >>> [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full_func): Define. >>> [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full): Declare. >>> [_GLIBCXX_HAVE_STACKTRACE](_Error_formatter::_M_backtrace_state): New. >>> [_GLIBCXX_HAVE_STACKTRACE](_Error_formatter::_M_backtrace_full): New. >>> * src/c++11/debug.cc (pretty_print): Rename into... >>> (print_function): ...that. >> This does more than just rename it, what are the other changes for? > > Nothing, I'm starting to remember what you did on this, reverted. > > >> >> >>> [_GLIBCXX_HAVE_STACKTRACE](print_backtrace): New. >>> (_Error_formatter::_M_error()): Adapt. >>> * src/libbacktrace/Makefile.am: Add backtrace.c. >>> * src/libbacktrace/Makefile.in: Regenerate. >>> * src/libbacktrace/backtrace-rename.h (backtrace_full): New. >>> * testsuite/23_containers/vector/debug/assign4_neg.cc: Add >>> backtrace >>> generation. >>> * doc/xml/manual/debug_mode.xml: Document _GLIBCXX_DEBUG_BACKTRACE. >>> * doc/xml/manual/using.xml: Likewise. >>> >>> Tested under Linux x86_64 normal and _GLIBCXX_DEBUG modes. >>> >>> Ok to commit ? >> >>> --- a/libstdc++-v3/testsuite/23_containers/vector/debug/assign4_neg.cc >>> +++ b/libstdc++-v3/testsuite/23_containers/vector/debug/assign4_neg.cc >>> @@ -16,6 +16,7 @@ >>> // <http://www.gnu.org/licenses/>. >>> // >>> // { dg-do run { xfail *-*-* } } >>> +// { dg-options "-D_GLIBCXX_DEBUG_BACKTRACE -lstdc++_libbacktrace" } >>> >>> #include <debug/vector> >>> #include <debug/checks.h> >> This will fail to link if the static lib isn't available. >> > Good point ! So I am introducing a new test case with the necessary dg > directive. > > It is a 'run' test case even if what is really tested is only the > compilation/link part. For the run part someone has to look at the log > file. > > François
On Wed, 31 Aug 2022 at 06:05, François Dumont <frs.dumont@gmail.com> wrote: > > After a second thought here is an even cleaner version. No more function > rename, current pretty_print is fine. > > libstdc++: [_GLIBCXX_DEBUG] Add backtrace generation on demand > > Add _GLIBCXX_DEBUG_BACKTRACE macro to activate backtrace > generation on > _GLIBCXX_DEBUG assertions. Prerequisite is to have configure the > lib with: > > --enable-libstdcxx-backtrace=yes > > libstdc++-v3/ChangeLog: > > * include/debug/formatter.h > [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_state): Declare. > [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_create_state): Declare. > [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full_callback): Define. > [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_error_callback): Define. > [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full_func): Define. > [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full): Declare. > [_GLIBCXX_HAVE_STACKTRACE](_Error_formatter::_M_backtrace_state): New. > [_GLIBCXX_HAVE_STACKTRACE](_Error_formatter::_M_backtrace_full): New. > * src/c++11/debug.cc > [_GLIBCXX_HAVE_STACKTRACE](print_backtrace): New. > (_Error_formatter::_M_error()): Adapt. > * src/libbacktrace/Makefile.am: Add backtrace.c. > * src/libbacktrace/Makefile.in: Regenerate. > * src/libbacktrace/backtrace-rename.h (backtrace_full): New. > * > testsuite/23_containers/vector/debug/assign4_backtrace_neg.cc: New test. > * doc/xml/manual/debug_mode.xml: Document > _GLIBCXX_DEBUG_BACKTRACE. > * doc/xml/manual/using.xml: Likewise. > Ok to commit ? OK for trunk, thanks. The small change to print_raw in this patch makes me wonder whether that function is actually useful. It supports two modes, print with max precision, and print without. The only time we use it to print with max precision we pass a string of exactly the right length, so the precision is not needed (but the caller has to get the string length correct: if we increase _S_indent and do not increase the " " literal passed to print_raw, the effects would be wrong). Wouldn't it be better to just use fprintf directly when we want to print without precision, and use a minimum field width instead of precision for indenting? i.e. ... --- a/libstdc++-v3/src/c++11/debug.cc +++ b/libstdc++-v3/src/c++11/debug.cc @@ -608,15 +608,6 @@ namespace print_literal(PrintContext& ctx, const char(&word)[Length]) { print_word(ctx, word, Length - 1); } - void - print_raw(PrintContext& ctx, const char* str, ptrdiff_t nbc = -1) - { - if (nbc >= 0) - ctx._M_column += fprintf(stderr, "%.*s", (int)nbc, str); - else - ctx._M_column += fprintf(stderr, "%s", str); - } - void print_word(PrintContext& ctx, const char* word, ptrdiff_t nbc = -1) { @@ -643,12 +634,9 @@ namespace || (ctx._M_column + visual_length < ctx._M_max_length) || (visual_length >= ctx._M_max_length && ctx._M_column == 1)) { - // If this isn't the first line, indent + // If this isn't the first line, indent. if (ctx._M_column == 1 && !ctx._M_first_line) - { - const char spacing[PrintContext::_S_indent + 1] = " "; - print_raw(ctx, spacing, PrintContext::_S_indent); - } + ctx._M_column += fprintf(stderr, "%*c", PrintContext::_S_indent, ' '); int written = fprintf(stderr, "%.*s", (int)length, word); @@ -1112,7 +1100,7 @@ namespace __gnu_debug PrintContext ctx; if (_M_file) { - print_raw(ctx, _M_file); + ctx._M_column += fprintf(stderr, "%s", _M_file); print_literal(ctx, ":"); go_to_next_line = true; }
On 31/08/22 12:11, Jonathan Wakely wrote: > On Wed, 31 Aug 2022 at 06:05, François Dumont <frs.dumont@gmail.com> wrote: >> After a second thought here is an even cleaner version. No more function >> rename, current pretty_print is fine. >> >> libstdc++: [_GLIBCXX_DEBUG] Add backtrace generation on demand >> >> Add _GLIBCXX_DEBUG_BACKTRACE macro to activate backtrace >> generation on >> _GLIBCXX_DEBUG assertions. Prerequisite is to have configure the >> lib with: >> >> --enable-libstdcxx-backtrace=yes >> >> libstdc++-v3/ChangeLog: >> >> * include/debug/formatter.h >> [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_state): Declare. >> [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_create_state): Declare. >> [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full_callback): Define. >> [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_error_callback): Define. >> [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full_func): Define. >> [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full): Declare. >> [_GLIBCXX_HAVE_STACKTRACE](_Error_formatter::_M_backtrace_state): New. >> [_GLIBCXX_HAVE_STACKTRACE](_Error_formatter::_M_backtrace_full): New. >> * src/c++11/debug.cc >> [_GLIBCXX_HAVE_STACKTRACE](print_backtrace): New. >> (_Error_formatter::_M_error()): Adapt. >> * src/libbacktrace/Makefile.am: Add backtrace.c. >> * src/libbacktrace/Makefile.in: Regenerate. >> * src/libbacktrace/backtrace-rename.h (backtrace_full): New. >> * >> testsuite/23_containers/vector/debug/assign4_backtrace_neg.cc: New test. >> * doc/xml/manual/debug_mode.xml: Document >> _GLIBCXX_DEBUG_BACKTRACE. >> * doc/xml/manual/using.xml: Likewise. >> Ok to commit ? > OK for trunk, thanks. > > The small change to print_raw in this patch makes me wonder whether > that function is actually useful. > > It supports two modes, print with max precision, and print without. > The only time we use it to print with max precision we pass a string > of exactly the right length, so the precision is not needed (but the > caller has to get the string length correct: if we increase _S_indent > and do not increase the " " literal passed to print_raw, the > effects would be wrong). > > Wouldn't it be better to just use fprintf directly when we want to > print without precision, and use a minimum field width instead of > precision for indenting? i.e. ... > > --- a/libstdc++-v3/src/c++11/debug.cc > +++ b/libstdc++-v3/src/c++11/debug.cc > @@ -608,15 +608,6 @@ namespace > print_literal(PrintContext& ctx, const char(&word)[Length]) > { print_word(ctx, word, Length - 1); } > > - void > - print_raw(PrintContext& ctx, const char* str, ptrdiff_t nbc = -1) > - { > - if (nbc >= 0) > - ctx._M_column += fprintf(stderr, "%.*s", (int)nbc, str); > - else > - ctx._M_column += fprintf(stderr, "%s", str); > - } > - > void > print_word(PrintContext& ctx, const char* word, ptrdiff_t nbc = -1) > { > @@ -643,12 +634,9 @@ namespace > || (ctx._M_column + visual_length < ctx._M_max_length) > || (visual_length >= ctx._M_max_length && ctx._M_column == 1)) > { > - // If this isn't the first line, indent > + // If this isn't the first line, indent. > if (ctx._M_column == 1 && !ctx._M_first_line) > - { > - const char spacing[PrintContext::_S_indent + 1] = " "; > - print_raw(ctx, spacing, PrintContext::_S_indent); > - } > + ctx._M_column += fprintf(stderr, "%*c", PrintContext::_S_indent, ' '); I did not know this syntax, it looks definitely better. > > int written = fprintf(stderr, "%.*s", (int)length, word); > > @@ -1112,7 +1100,7 @@ namespace __gnu_debug > PrintContext ctx; > if (_M_file) > { > - print_raw(ctx, _M_file); > + ctx._M_column += fprintf(stderr, "%s", _M_file); > print_literal(ctx, ":"); > go_to_next_line = true; > } > Do you take care or you prefer I do ?
On Wed, 31 Aug 2022 at 20:33, François Dumont <frs.dumont@gmail.com> wrote: > > On 31/08/22 12:11, Jonathan Wakely wrote: > > On Wed, 31 Aug 2022 at 06:05, François Dumont <frs.dumont@gmail.com> wrote: > >> After a second thought here is an even cleaner version. No more function > >> rename, current pretty_print is fine. > >> > >> libstdc++: [_GLIBCXX_DEBUG] Add backtrace generation on demand > >> > >> Add _GLIBCXX_DEBUG_BACKTRACE macro to activate backtrace > >> generation on > >> _GLIBCXX_DEBUG assertions. Prerequisite is to have configure the > >> lib with: > >> > >> --enable-libstdcxx-backtrace=yes > >> > >> libstdc++-v3/ChangeLog: > >> > >> * include/debug/formatter.h > >> [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_state): Declare. > >> [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_create_state): Declare. > >> [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full_callback): Define. > >> [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_error_callback): Define. > >> [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full_func): Define. > >> [_GLIBCXX_HAVE_STACKTRACE](__glibcxx_backtrace_full): Declare. > >> [_GLIBCXX_HAVE_STACKTRACE](_Error_formatter::_M_backtrace_state): New. > >> [_GLIBCXX_HAVE_STACKTRACE](_Error_formatter::_M_backtrace_full): New. > >> * src/c++11/debug.cc > >> [_GLIBCXX_HAVE_STACKTRACE](print_backtrace): New. > >> (_Error_formatter::_M_error()): Adapt. > >> * src/libbacktrace/Makefile.am: Add backtrace.c. > >> * src/libbacktrace/Makefile.in: Regenerate. > >> * src/libbacktrace/backtrace-rename.h (backtrace_full): New. > >> * > >> testsuite/23_containers/vector/debug/assign4_backtrace_neg.cc: New test. > >> * doc/xml/manual/debug_mode.xml: Document > >> _GLIBCXX_DEBUG_BACKTRACE. > >> * doc/xml/manual/using.xml: Likewise. > >> Ok to commit ? > > OK for trunk, thanks. > > > > The small change to print_raw in this patch makes me wonder whether > > that function is actually useful. > > > > It supports two modes, print with max precision, and print without. > > The only time we use it to print with max precision we pass a string > > of exactly the right length, so the precision is not needed (but the > > caller has to get the string length correct: if we increase _S_indent > > and do not increase the " " literal passed to print_raw, the > > effects would be wrong). > > > > Wouldn't it be better to just use fprintf directly when we want to > > print without precision, and use a minimum field width instead of > > precision for indenting? i.e. ... > > > > --- a/libstdc++-v3/src/c++11/debug.cc > > +++ b/libstdc++-v3/src/c++11/debug.cc > > @@ -608,15 +608,6 @@ namespace > > print_literal(PrintContext& ctx, const char(&word)[Length]) > > { print_word(ctx, word, Length - 1); } > > > > - void > > - print_raw(PrintContext& ctx, const char* str, ptrdiff_t nbc = -1) > > - { > > - if (nbc >= 0) > > - ctx._M_column += fprintf(stderr, "%.*s", (int)nbc, str); > > - else > > - ctx._M_column += fprintf(stderr, "%s", str); > > - } > > - > > void > > print_word(PrintContext& ctx, const char* word, ptrdiff_t nbc = -1) > > { > > @@ -643,12 +634,9 @@ namespace > > || (ctx._M_column + visual_length < ctx._M_max_length) > > || (visual_length >= ctx._M_max_length && ctx._M_column == 1)) > > { > > - // If this isn't the first line, indent > > + // If this isn't the first line, indent. > > if (ctx._M_column == 1 && !ctx._M_first_line) > > - { > > - const char spacing[PrintContext::_S_indent + 1] = " "; > > - print_raw(ctx, spacing, PrintContext::_S_indent); > > - } > > + ctx._M_column += fprintf(stderr, "%*c", PrintContext::_S_indent, ' '); > I did not know this syntax, it looks definitely better. > > > > int written = fprintf(stderr, "%.*s", (int)length, word); > > > > @@ -1112,7 +1100,7 @@ namespace __gnu_debug > > PrintContext ctx; > > if (_M_file) > > { > > - print_raw(ctx, _M_file); > > + ctx._M_column += fprintf(stderr, "%s", _M_file); > > print_literal(ctx, ":"); > > go_to_next_line = true; > > } > > > Do you take care or you prefer I do ? I can do it.
diff --git a/libstdc++-v3/doc/xml/manual/debug_mode.xml b/libstdc++-v3/doc/xml/manual/debug_mode.xml index 988c4a93601..dadc0cd1bb4 100644 --- a/libstdc++-v3/doc/xml/manual/debug_mode.xml +++ b/libstdc++-v3/doc/xml/manual/debug_mode.xml @@ -161,6 +161,12 @@ which always works correctly. <code>GLIBCXX_DEBUG_MESSAGE_LENGTH</code> can be used to request a different length.</para> +<para>Note that libstdc++ is able to produce backtraces on error. + It requires that you configure libstdc++ build with + <option>--enable-libstdcxx-backtrace=yes</option>. + Use <code>-D_GLIBCXX_DEBUG_BACKTRACE</code> to activate it. + You'll then have to link with libstdc++_libbacktrace static library + (<option>-lstdc++_libbacktrace</option>) to build your application.</para> </section> <section xml:id="debug_mode.using.specific" xreflabel="Using Specific"><info><title>Using a Specific Debug Container</title></info> diff --git a/libstdc++-v3/doc/xml/manual/using.xml b/libstdc++-v3/doc/xml/manual/using.xml index 36b86702d22..26f14fae194 100644 --- a/libstdc++-v3/doc/xml/manual/using.xml +++ b/libstdc++-v3/doc/xml/manual/using.xml @@ -1129,6 +1129,15 @@ g++ -Winvalid-pch -I. -include stdc++.h -H -g -O2 hello.cc -o test.exe extensions and libstdc++-specific behavior into errors. </para> </listitem></varlistentry> + <varlistentry><term><code>_GLIBCXX_DEBUG_BACKTRACE</code></term> + <listitem> + <para> + Undefined by default. Considered only if libstdc++ has been configured with + <option>--enable-libstdcxx-backtrace=yes</option> and if <code>_GLIBCXX_DEBUG</code> + is defined. When defined display backtraces on + <link linkend="manual.ext.debug_mode">debug mode</link> assertions. + </para> + </listitem></varlistentry> <varlistentry><term><code>_GLIBCXX_PARALLEL</code></term> <listitem> <para>Undefined by default. When defined, compiles user code @@ -1635,6 +1644,7 @@ A quick read of the relevant part of the GCC header will remain compatible between different GCC releases. </para> </section> + </section> <section xml:id="manual.intro.using.concurrency" xreflabel="Concurrency"><info><title>Concurrency</title></info> diff --git a/libstdc++-v3/include/debug/formatter.h b/libstdc++-v3/include/debug/formatter.h index 80e8ba46d1e..f31b44d184a 100644 --- a/libstdc++-v3/include/debug/formatter.h +++ b/libstdc++-v3/include/debug/formatter.h @@ -31,6 +31,37 @@ #include <bits/c++config.h> +#if _GLIBCXX_HAVE_STACKTRACE +struct __glibcxx_backtrace_state; + +extern "C" +{ + __glibcxx_backtrace_state* + __glibcxx_backtrace_create_state(const char*, int, + void(*)(void*, const char*, int), + void*); + + typedef int (*__glibcxx_backtrace_full_callback) ( + void*, __UINTPTR_TYPE__, const char *, int, const char*); + + typedef void (*__glibcxx_backtrace_error_callback) ( + void*, const char*, int); + + typedef int (*__glibcxx_backtrace_full_func) ( + __glibcxx_backtrace_state*, int, + __glibcxx_backtrace_full_callback, + __glibcxx_backtrace_error_callback, + void*); + + int + __glibcxx_backtrace_full( + __glibcxx_backtrace_state*, int, + __glibcxx_backtrace_full_callback, + __glibcxx_backtrace_error_callback, + void*); +} +#endif + #if __cpp_rtti # include <typeinfo> # define _GLIBCXX_TYPEID(_Type) &typeid(_Type) @@ -565,6 +596,15 @@ namespace __gnu_debug const char* __function) : _M_file(__file), _M_line(__line), _M_num_parameters(0), _M_text(0) , _M_function(__function) +#if _GLIBCXX_HAVE_STACKTRACE +# ifdef _GLIBCXX_DEBUG_BACKTRACE + , _M_backtrace_state( + __glibcxx_backtrace_create_state(nullptr, 0, nullptr, nullptr)) + , _M_backtrace_full(&__glibcxx_backtrace_full) +# else + , _M_backtrace_state() +# endif +#endif { } #if !_GLIBCXX_INLINE_VERSION @@ -580,6 +620,10 @@ namespace __gnu_debug unsigned int _M_num_parameters; const char* _M_text; const char* _M_function; +#if _GLIBCXX_HAVE_STACKTRACE + __glibcxx_backtrace_state* _M_backtrace_state; + __glibcxx_backtrace_full_func _M_backtrace_full; +#endif public: static _Error_formatter& diff --git a/libstdc++-v3/src/c++11/debug.cc b/libstdc++-v3/src/c++11/debug.cc index 4706defedf1..3e45433be22 100644 --- a/libstdc++-v3/src/c++11/debug.cc +++ b/libstdc++-v3/src/c++11/debug.cc @@ -609,10 +609,12 @@ namespace void print_raw(PrintContext& ctx, const char* str, ptrdiff_t nbc = -1) { - if (nbc >= 0) - ctx._M_column += fprintf(stderr, "%.*s", (int)nbc, str); - else - ctx._M_column += fprintf(stderr, "%s", str); + if (nbc != 0) + { + ctx._M_column += (nbc > 0) + ? fprintf(stderr, "%.*s", (int)nbc, str) + : fprintf(stderr, "%s", str); + } } void @@ -666,25 +668,35 @@ namespace } void - pretty_print(PrintContext& ctx, const char* str, _Print_func_t print_func) + print_function(PrintContext& ctx, const char* func, _Print_func_t print_func) { - const char cxx1998[] = "cxx1998::"; + const char cxx1998[] = "__cxx1998::"; + const char uglification[] = "__"; for (;;) { - if (auto pos = strstr(str, "__")) + size_t offset; + auto idx = strstr(func, cxx1998); + if (idx) + offset = sizeof(cxx1998) - 1; + else if ((idx = strstr(func, uglification))) + offset = sizeof(uglification) - 1; + + if (idx) { - if (pos != str) - print_func(ctx, str, pos - str); + if (idx != func) + print_func(ctx, func, idx - func); + + func = idx + offset; - pos += 2; // advance past "__" - if (memcmp(pos, cxx1998, 9) == 0) - pos += 9; // advance part "cxx1998::" + while (*func && isspace((unsigned char)*func)) + ++func; - str = pos; + if (!*func) + break; } else { - print_func(ctx, str, -1); + print_func(ctx, func, -1); break; } } @@ -704,7 +716,7 @@ namespace char* demangled_name = __cxxabiv1::__cxa_demangle(info->name(), NULL, NULL, &status); if (status == 0) - pretty_print(ctx, demangled_name, &print_word); + print_function(ctx, demangled_name, &print_word); else print_word(ctx, info->name()); free(demangled_name); @@ -735,7 +747,7 @@ namespace print_named_name(PrintContext& ctx, const _Parameter::_Named& named) { assert(named._M_name); - pretty_print(ctx, named._M_name, print_word); + print_function(ctx, named._M_name, print_word); } template<typename _Iterator> @@ -1090,6 +1102,58 @@ namespace void print_string(PrintContext& ctx, const char* str, ptrdiff_t nbc) { print_string(ctx, str, nbc, nullptr, 0); } + +#if _GLIBCXX_HAVE_STACKTRACE + int + print_backtrace(void* data, __UINTPTR_TYPE__ pc, const char* filename, + int lineno, const char* function) + { + const int bufsize = 64; + char buf[bufsize]; + + PrintContext& ctx = *static_cast<PrintContext*>(data); + + int written = __builtin_sprintf(buf, "%p ", (void*)pc); + print_word(ctx, buf, written); + + int ret = 0; + if (function) + { + int status; + char* demangled_name = + __cxxabiv1::__cxa_demangle(function, NULL, NULL, &status); + if (status == 0) + print_function(ctx, demangled_name, &print_raw); + else + print_word(ctx, function); + + free(demangled_name); + ret = strstr(function, "main") ? 1 : 0; + } + + print_literal(ctx, "\n"); + + if (filename) + { + bool wordwrap = false; + swap(wordwrap, ctx._M_wordwrap); + print_word(ctx, filename); + + if (lineno) + { + written = __builtin_sprintf(buf, ":%u\n", lineno); + print_word(ctx, buf, written); + } + else + print_literal(ctx, "\n"); + swap(wordwrap, ctx._M_wordwrap); + } + else + print_literal(ctx, "???:0\n"); + + return ret; + } +#endif } namespace __gnu_debug @@ -1130,11 +1194,22 @@ namespace __gnu_debug if (_M_function) { print_literal(ctx, "In function:\n"); - pretty_print(ctx, _M_function, &print_string); + print_function(ctx, _M_function, &print_string); + print_literal(ctx, "\n"); + ctx._M_first_line = true; print_literal(ctx, "\n"); + } + +#if _GLIBCXX_HAVE_STACKTRACE + if (_M_backtrace_state) + { + print_literal(ctx, "Backtrace:\n"); + _M_backtrace_full( + _M_backtrace_state, 1, print_backtrace, nullptr, &ctx); ctx._M_first_line = true; print_literal(ctx, "\n"); } +#endif print_literal(ctx, "Error: "); diff --git a/libstdc++-v3/src/libbacktrace/Makefile.am b/libstdc++-v3/src/libbacktrace/Makefile.am index 0f1143507f3..52d8f81b97b 100644 --- a/libstdc++-v3/src/libbacktrace/Makefile.am +++ b/libstdc++-v3/src/libbacktrace/Makefile.am @@ -60,6 +60,7 @@ libstdc___libbacktrace_la_SHORTNAME = $(obj_prefix) libstdc___libbacktrace_la_SOURCES = \ atomic.c \ + backtrace.c \ dwarf.c \ fileline.c \ posix.c \ diff --git a/libstdc++-v3/src/libbacktrace/Makefile.in b/libstdc++-v3/src/libbacktrace/Makefile.in index 7545894d59a..5c6b4dd1a0c 100644 --- a/libstdc++-v3/src/libbacktrace/Makefile.in +++ b/libstdc++-v3/src/libbacktrace/Makefile.in @@ -181,10 +181,10 @@ am__uninstall_files_from_dir = { \ am__installdirs = "$(DESTDIR)$(toolexeclibdir)" LTLIBRARIES = $(toolexeclib_LTLIBRARIES) am_libstdc___libbacktrace_la_OBJECTS = $(obj_prefix)-atomic.lo \ - $(obj_prefix)-dwarf.lo $(obj_prefix)-fileline.lo \ - $(obj_prefix)-posix.lo $(obj_prefix)-sort.lo \ - $(obj_prefix)-simple.lo $(obj_prefix)-state.lo \ - $(obj_prefix)-cp-demangle.lo + $(obj_prefix)-backtrace.lo $(obj_prefix)-dwarf.lo \ + $(obj_prefix)-fileline.lo $(obj_prefix)-posix.lo \ + $(obj_prefix)-sort.lo $(obj_prefix)-simple.lo \ + $(obj_prefix)-state.lo $(obj_prefix)-cp-demangle.lo libstdc___libbacktrace_la_OBJECTS = \ $(am_libstdc___libbacktrace_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) @@ -507,6 +507,7 @@ obj_prefix = std_stacktrace libstdc___libbacktrace_la_SHORTNAME = $(obj_prefix) libstdc___libbacktrace_la_SOURCES = \ atomic.c \ + backtrace.c \ dwarf.c \ fileline.c \ posix.c \ @@ -647,6 +648,9 @@ distclean-compile: $(obj_prefix)-atomic.lo: atomic.c $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstdc___libbacktrace_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o $(obj_prefix)-atomic.lo `test -f 'atomic.c' || echo '$(srcdir)/'`atomic.c +$(obj_prefix)-backtrace.lo: backtrace.c + $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstdc___libbacktrace_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o $(obj_prefix)-backtrace.lo `test -f 'backtrace.c' || echo '$(srcdir)/'`backtrace.c + $(obj_prefix)-dwarf.lo: dwarf.c $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libstdc___libbacktrace_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o $(obj_prefix)-dwarf.lo `test -f 'dwarf.c' || echo '$(srcdir)/'`dwarf.c diff --git a/libstdc++-v3/src/libbacktrace/backtrace-rename.h b/libstdc++-v3/src/libbacktrace/backtrace-rename.h index 7a59f166e62..79bdef6309f 100644 --- a/libstdc++-v3/src/libbacktrace/backtrace-rename.h +++ b/libstdc++-v3/src/libbacktrace/backtrace-rename.h @@ -4,6 +4,7 @@ #define backtrace_create_state __glibcxx_backtrace_create_state #define backtrace_dwarf_add __glibcxx_backtrace_dwarf_add #define backtrace_free __glibcxx_backtrace_free +#define backtrace_full __glibcxx_backtrace_full #define backtrace_get_view __glibcxx_backtrace_get_view #define backtrace_initialize __glibcxx_backtrace_initialize #define backtrace_open __glibcxx_backtrace_open diff --git a/libstdc++-v3/testsuite/23_containers/vector/debug/assign4_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/debug/assign4_neg.cc index 7ab658d0ba1..cb1b1740cfe 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/debug/assign4_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/debug/assign4_neg.cc @@ -16,6 +16,7 @@ // <http://www.gnu.org/licenses/>. // // { dg-do run { xfail *-*-* } } +// { dg-options "-D_GLIBCXX_DEBUG_BACKTRACE -lstdc++_libbacktrace" } #include <debug/vector> #include <debug/checks.h>