This commit expands on r15-3973-g4c7a58ac2617e2, which added debug "dump" member functiosn to pretty_printer and output_buffer.
This followup adds "dump" member functions to diagnostic_context and diagnostic_format, extends the existing dump functions and adds indentation to make it much easier to see the various relationships between context, format, printer, etc. Hence you can now do: (gdb) call global_dc->dump () and get a useful summary of what the diagnostic subsystem is doing; for example: (gdb) call global_dc->dump() diagnostic_context: counts: output format: sarif_output_format printer: m_show_color: false m_url_format: bel m_buffer: m_formatted_obstack current object: length 0: m_chunk_obstack current object: length 0: pp_formatted_chunks: depth 0 0: TEXT("Function ")] 1: BEGIN_QUOTE, TEXT("program"), END_QUOTE] 2: TEXT(" requires an argument list at ")] 3: TEXT("(1)")] showing the counts of all diagnostic kind that are non-zero (none yet), that we have a sarif output format, and the printer is part-way through formatting a string. Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu. Pushed to trunk as r15-4491-g2ca19d43fb5d75. gcc/ChangeLog: * diagnostic-format-json.cc (json_output_format::dump): New. * diagnostic-format-sarif.cc (sarif_output_format::dump): New. (sarif_file_output_format::dump): New. * diagnostic-format-text.cc (diagnostic_text_output_format::dump): New. * diagnostic-format-text.h (diagnostic_text_output_format::dump): New decl. * diagnostic-format.h (diagnostic_output_format::dump): New decls. * diagnostic.cc (diagnostic_context::dump): New. (diagnostic_output_format::dump): New. * diagnostic.h (diagnostic_context::dump): New decls. * pretty-print-format-impl.h (pp_formatted_chunks::dump): Add "indent" param. * pretty-print.cc (bytes_per_hexdump_line): New constant. (print_hexdump_line): New. (print_hexdump): New. (output_buffer::dump): Add "indent" param and use it. Add hexdump of current object in m_formatted_obstack and m_chunk_obstack. (pp_formatted_chunks::dump): Add "indent" param and use it. (pretty_printer::dump): Likewise. Add dumping of m_show_color and m_url_format. * pretty-print.h (output_buffer::dump): Add "indent" param. (pretty_printer::dump): Likewise. gcc/testsuite/ChangeLog: * gcc.dg/plugin/diagnostic_plugin_xhtml_format.c (xhtml_output_format::dump): New. Signed-off-by: David Malcolm <dmalc...@redhat.com> --- gcc/diagnostic-format-json.cc | 6 ++ gcc/diagnostic-format-sarif.cc | 13 +++ gcc/diagnostic-format-text.cc | 7 ++ gcc/diagnostic-format-text.h | 3 + gcc/diagnostic-format.h | 4 + gcc/diagnostic.cc | 24 +++++ gcc/diagnostic.h | 3 + gcc/pretty-print-format-impl.h | 4 +- gcc/pretty-print.cc | 96 +++++++++++++++++-- gcc/pretty-print.h | 8 +- .../plugin/diagnostic_plugin_xhtml_format.c | 6 ++ 11 files changed, 160 insertions(+), 14 deletions(-) diff --git a/gcc/diagnostic-format-json.cc b/gcc/diagnostic-format-json.cc index b4c1f13ee671..4f035dd2fae3 100644 --- a/gcc/diagnostic-format-json.cc +++ b/gcc/diagnostic-format-json.cc @@ -38,6 +38,12 @@ along with GCC; see the file COPYING3. If not see class json_output_format : public diagnostic_output_format { public: + void dump (FILE *out, int indent) const override + { + fprintf (out, "%*sjson_output_format\n", indent, ""); + diagnostic_output_format::dump (out, indent); + } + void on_begin_group () final override { /* No-op. */ diff --git a/gcc/diagnostic-format-sarif.cc b/gcc/diagnostic-format-sarif.cc index 89ac9a5424c9..f64c83ad6e14 100644 --- a/gcc/diagnostic-format-sarif.cc +++ b/gcc/diagnostic-format-sarif.cc @@ -3302,6 +3302,12 @@ public: gcc_assert (!pending_result); } + void dump (FILE *out, int indent) const override + { + fprintf (out, "%*ssarif_output_format\n", indent, ""); + diagnostic_output_format::dump (out, indent); + } + void on_begin_group () final override { /* No-op, */ @@ -3386,6 +3392,13 @@ public: { m_builder.flush_to_file (m_output_file.get_open_file ()); } + void dump (FILE *out, int indent) const override + { + fprintf (out, "%*ssarif_file_output_format: %s\n", + indent, "", + m_output_file.get_filename ()); + diagnostic_output_format::dump (out, indent); + } bool machine_readable_stderr_p () const final override { return false; diff --git a/gcc/diagnostic-format-text.cc b/gcc/diagnostic-format-text.cc index 0d58d5fb082d..f6ec88155c7f 100644 --- a/gcc/diagnostic-format-text.cc +++ b/gcc/diagnostic-format-text.cc @@ -69,6 +69,13 @@ diagnostic_text_output_format::~diagnostic_text_output_format () } } +void +diagnostic_text_output_format::dump (FILE *out, int indent) const +{ + fprintf (out, "%*sdiagnostic_text_output_format\n", indent, ""); + diagnostic_output_format::dump (out, indent); +} + /* Implementation of diagnostic_output_format::on_report_diagnostic vfunc for GCC's standard textual output. */ diff --git a/gcc/diagnostic-format-text.h b/gcc/diagnostic-format-text.h index 2e57e27c739d..d3b10dd518ae 100644 --- a/gcc/diagnostic-format-text.h +++ b/gcc/diagnostic-format-text.h @@ -39,6 +39,9 @@ public: m_includes_seen (nullptr) {} ~diagnostic_text_output_format (); + + void dump (FILE *out, int indent) const override; + void on_begin_group () override {} void on_end_group () override {} void on_report_diagnostic (const diagnostic_info &, diff --git a/gcc/diagnostic-format.h b/gcc/diagnostic-format.h index 1fd3fe0c64e8..e514c6f1ced8 100644 --- a/gcc/diagnostic-format.h +++ b/gcc/diagnostic-format.h @@ -32,6 +32,8 @@ class diagnostic_output_format public: virtual ~diagnostic_output_format () {} + virtual void dump (FILE *out, int indent) const; + virtual void on_begin_group () = 0; virtual void on_end_group () = 0; @@ -52,6 +54,8 @@ public: return m_context.get_diagram_theme (); } + void DEBUG_FUNCTION dump () const { dump (stderr, 0); } + protected: diagnostic_output_format (diagnostic_context &context) : m_context (context) diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc index 4a1e347776e9..2a72717d16d0 100644 --- a/gcc/diagnostic.cc +++ b/gcc/diagnostic.cc @@ -418,6 +418,24 @@ diagnostic_context::finish () m_original_argv = nullptr; } +/* Dump state of this diagnostic_context to OUT, for debugging. */ + +void +diagnostic_context::dump (FILE *out) const +{ + fprintf (out, "diagnostic_context:\n"); + fprintf (out, " counts:\n"); + for (int i = 0; i < DK_LAST_DIAGNOSTIC_KIND; i++) + if (m_diagnostic_count[i] > 0) + fprintf (out, " %s%i\n", + get_diagnostic_kind_text (static_cast<diagnostic_t> (i)), + m_diagnostic_count[i]); + fprintf (out, " output format:\n"); + m_output_format->dump (out, 4); + fprintf (out, " printer:\n"); + m_printer->dump (out, 4); +} + /* Return true if sufficiently severe diagnostics have been seen that we ought to exit with a non-zero exit code. */ @@ -1555,6 +1573,12 @@ diagnostic_context::end_group () } } +void +diagnostic_output_format::dump (FILE *, int) const +{ + /* No-op for now. */ +} + /* Set the output format for CONTEXT to FORMAT, using BASE_FILE_NAME for file-based output formats. */ diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h index dbb3803ffb19..edd221f1a8ce 100644 --- a/gcc/diagnostic.h +++ b/gcc/diagnostic.h @@ -477,6 +477,9 @@ public: void finish (); + void dump (FILE *out) const; + void DEBUG_FUNCTION dump () const { dump (stderr); } + bool execution_failed_p () const; void set_original_argv (unique_argv original_argv); diff --git a/gcc/pretty-print-format-impl.h b/gcc/pretty-print-format-impl.h index ec4425c9dafb..8c969cdfed73 100644 --- a/gcc/pretty-print-format-impl.h +++ b/gcc/pretty-print-format-impl.h @@ -373,8 +373,8 @@ public: void append_formatted_chunk (obstack &s, const char *content); - void dump (FILE *out) const; - void DEBUG_FUNCTION dump () const { dump (stderr); } + void dump (FILE *out, int indent) const; + void DEBUG_FUNCTION dump () const { dump (stderr, 0); } // For use in selftests pp_formatted_chunks *get_prev () const { return m_prev; } diff --git a/gcc/pretty-print.cc b/gcc/pretty-print.cc index 18c4b2fa3509..8082dbcdddda 100644 --- a/gcc/pretty-print.cc +++ b/gcc/pretty-print.cc @@ -794,18 +794,75 @@ output_buffer::pop_formatted_chunks () obstack_free (&m_chunk_obstack, old_top); } +static const int bytes_per_hexdump_line = 16; + +static void +print_hexdump_line (FILE *out, int indent, + const void *buf, size_t size, size_t line_start_idx) +{ + fprintf (out, "%*s%08lx: ", indent, "", (unsigned long)line_start_idx); + for (size_t offset = 0; offset < bytes_per_hexdump_line; ++offset) + { + const size_t idx = line_start_idx + offset; + if (idx < size) + fprintf (out, "%02x ", ((const unsigned char *)buf)[idx]); + else + fprintf (out, " "); + } + fprintf (out, "| "); + for (size_t offset = 0; offset < bytes_per_hexdump_line; ++offset) + { + const size_t idx = line_start_idx + offset; + if (idx < size) + { + unsigned char ch = ((const unsigned char *)buf)[idx]; + if (!ISPRINT (ch)) + ch = '.'; + fputc (ch, out); + } + else + break; + } + fprintf (out, "\n"); + +} + +static void +print_hexdump (FILE *out, int indent, const void *buf, size_t size) +{ + for (size_t idx = 0; idx < size; idx += bytes_per_hexdump_line) + print_hexdump_line (out, indent, buf, size, idx); +} + /* Dump state of this output_buffer to OUT, for debugging. */ void -output_buffer::dump (FILE *out) const +output_buffer::dump (FILE *out, int indent) const { + { + size_t obj_size = obstack_object_size (&m_formatted_obstack); + fprintf (out, "%*sm_formatted_obstack current object: length %li:\n", + indent, "", (long)obj_size); + print_hexdump (out, indent + 2, + m_formatted_obstack.object_base, obj_size); + } + { + size_t obj_size = obstack_object_size (&m_chunk_obstack); + fprintf (out, "%*sm_chunk_obstack current object: length %li:\n", + indent, "", (long)obj_size); + print_hexdump (out, indent + 2, + m_chunk_obstack.object_base, obj_size); + } + int depth = 0; for (pp_formatted_chunks *iter = m_cur_formatted_chunks; iter; iter = iter->m_prev, depth++) { - fprintf (out, "pp_formatted_chunks: depth %i\n", depth); - iter->dump (out); + fprintf (out, "%*spp_formatted_chunks: depth %i\n", + indent, "", + depth); + iter->dump (out, indent + 2); } } @@ -1505,7 +1562,6 @@ pp_token_list::apply_urlifier (const urlifier &urlifier) void pp_token_list::dump (FILE *out) const { - fprintf (out, "["); for (auto iter = m_first; iter; iter = iter->m_next) { iter->dump (out); @@ -1532,11 +1588,13 @@ pp_formatted_chunks::append_formatted_chunk (obstack &s, const char *content) } void -pp_formatted_chunks::dump (FILE *out) const +pp_formatted_chunks::dump (FILE *out, int indent) const { for (size_t idx = 0; m_args[idx]; ++idx) { - fprintf (out, "%i: ", (int)idx); + fprintf (out, "%*s%i: ", + indent, "", + (int)idx); m_args[idx]->dump (out); } } @@ -3035,9 +3093,31 @@ pretty_printer::end_url () /* Dump state of this pretty_printer to OUT, for debugging. */ void -pretty_printer::dump (FILE *out) const +pretty_printer::dump (FILE *out, int indent) const { - m_buffer->dump (out); + fprintf (out, "%*sm_show_color: %s\n", + indent, "", + m_show_color ? "true" : "false"); + + fprintf (out, "%*sm_url_format: ", indent, ""); + switch (m_url_format) + { + case URL_FORMAT_NONE: + fprintf (out, "none"); + break; + case URL_FORMAT_ST: + fprintf (out, "st"); + break; + case URL_FORMAT_BEL: + fprintf (out, "bel"); + break; + default: + gcc_unreachable (); + } + fprintf (out, "\n"); + + fprintf (out, "%*sm_buffer:\n", indent, ""); + m_buffer->dump (out, indent + 2); } /* class pp_markup::context. */ diff --git a/gcc/pretty-print.h b/gcc/pretty-print.h index ec64a167327b..05dbb1986da8 100644 --- a/gcc/pretty-print.h +++ b/gcc/pretty-print.h @@ -93,8 +93,8 @@ public: pp_formatted_chunks *push_formatted_chunks (); void pop_formatted_chunks (); - void dump (FILE *out) const; - void DEBUG_FUNCTION dump () const { dump (stderr); } + void dump (FILE *out, int indent) const; + void DEBUG_FUNCTION dump () const { dump (stderr, 0); } /* Obstack where the text is built up. */ struct obstack m_formatted_obstack; @@ -316,8 +316,8 @@ public: void set_real_maximum_length (); int remaining_character_count_for_line (); - void dump (FILE *out) const; - void DEBUG_FUNCTION dump () const { dump (stderr); } + void dump (FILE *out, int indent) const; + void DEBUG_FUNCTION dump () const { dump (stderr, 0); } private: /* Where we print external representation of ENTITY. */ diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_xhtml_format.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_xhtml_format.c index c74ecb018efa..d38250761b73 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_xhtml_format.c +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_xhtml_format.c @@ -594,6 +594,12 @@ public: gcc_assert (!pending_diag); } + void dump (FILE *out, int indent) const override + { + fprintf (out, "%*xhtml_output_format\n", indent, ""); + diagnostic_output_format::dump (out, indent); + } + void on_begin_group () final override { /* No-op, */ -- 2.26.3