diff options
author | David Malcolm <dmalcolm@redhat.com> | 2023-09-14 16:28:45 -0400 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2023-09-14 16:28:45 -0400 |
commit | 3a1e9f3ed7aa49adad02190ace0614e0b37fc089 (patch) | |
tree | 71ebe918a9745e69d37686d69658ba7772022890 /gcc/diagnostic-path.h | |
parent | 59f6185b59f71175bb2bf7f380a2a6ec706ee8c9 (diff) | |
download | gcc-3a1e9f3ed7aa49adad02190ace0614e0b37fc089.zip gcc-3a1e9f3ed7aa49adad02190ace0614e0b37fc089.tar.gz gcc-3a1e9f3ed7aa49adad02190ace0614e0b37fc089.tar.bz2 |
diagnostics: support multithreaded diagnostic paths
This patch extends the existing diagnostic_path class so that as well
as list of events, there is a list of named threads, with each event
being associated with one of the threads.
No GCC diagnostics take advantage of this, but GCC plugins may find a
use for this; an example is provided in the testsuite.
Given that there is still a single list of events within a
diagnostic_path, the events in a diagnostic_path have a specific global
ordering even if they are in multiple threads.
Within the SARIF serialization, the patch adds the "executionOrder"
property to threadFlowLocation objects (SARIF v2.1.0 3.38.11). This is
1-based in order to match the human-readable numbering of events shown
in messages emitted by pretty-printer.cc's "%@".
With -fdiagnostics-path-format=separate-events, the threads are not
shown.
With -fdiagnostics-path-format=inline-events, the threads and the
per-thread stack activity are tracked and visalized separately. An
example can be seen in the testsuite.
gcc/analyzer/ChangeLog:
* checker-event.h (checker_event::get_thread_id): New.
* checker-path.h (class checker_path): Implement thread-related
vfuncs via a single simple_diagnostic_thread instance named
"main".
gcc/ChangeLog:
* diagnostic-event-id.h (diagnostic_thread_id_t): New typedef.
* diagnostic-format-sarif.cc (class sarif_thread_flow): New.
(sarif_thread_flow::sarif_thread_flow): New.
(sarif_builder::make_code_flow_object): Reimplement, creating
per-thread threadFlow objects, populating them with the relevant
events.
(sarif_builder::make_thread_flow_object): Delete, moving the
code into sarif_builder::make_code_flow_object.
(sarif_builder::make_thread_flow_location_object): Add
"path_event_idx" param. Use it to set "executionOrder"
property.
* diagnostic-path.h (diagnostic_event::get_thread_id): New
pure-virtual vfunc.
(class diagnostic_thread): New.
(diagnostic_path::num_threads): New pure-virtual vfunc.
(diagnostic_path::get_thread): New pure-virtual vfunc.
(diagnostic_path::multithreaded_p): New decl.
(simple_diagnostic_event::simple_diagnostic_event): Add optional
thread_id param.
(simple_diagnostic_event::get_thread_id): New accessor.
(simple_diagnostic_event::m_thread_id): New.
(class simple_diagnostic_thread): New.
(simple_diagnostic_path::simple_diagnostic_path): Move definition
to diagnostic.cc.
(simple_diagnostic_path::num_threads): New.
(simple_diagnostic_path::get_thread): New.
(simple_diagnostic_path::add_thread): New.
(simple_diagnostic_path::add_thread_event): New.
(simple_diagnostic_path::m_threads): New.
* diagnostic-show-locus.cc (layout::layout): Add pretty_printer
param for overriding the context's printer.
(diagnostic_show_locus): Likwise.
* diagnostic.cc (simple_diagnostic_path::simple_diagnostic_path):
Move here from diagnostic-path.h. Add main thread.
(simple_diagnostic_path::num_threads): New.
(simple_diagnostic_path::get_thread): New.
(simple_diagnostic_path::add_thread): New.
(simple_diagnostic_path::add_thread_event): New.
(simple_diagnostic_event::simple_diagnostic_event): Add thread_id
param and use it to initialize m_thread_id. Reformat.
* diagnostic.h: Add pretty_printer param for overriding the
context's printer.
* tree-diagnostic-path.cc: Add #define INCLUDE_VECTOR.
(can_consolidate_events): Compare thread ids.
(class per_thread_summary): New.
(event_range::event_range): Add per_thread_summary arg.
(event_range::print): Add "pp" param and use it rather than dc's
printer.
(event_range::m_thread_id): New field.
(event_range::m_per_thread_summary): New field.
(path_summary::multithreaded_p): New.
(path_summary::get_events_for_thread_id): New.
(path_summary::m_per_thread_summary): New field.
(path_summary::m_thread_id_to_events): New field.
(path_summary::get_or_create_events_for_thread_id): New.
(path_summary::path_summary): Create per_thread_summary instances
as needed and associate the event_range instances with them.
(base_indent): Move here from print_path_summary_as_text.
(per_frame_indent): Likewise.
(class thread_event_printer): New, adapted from parts of
print_path_summary_as_text.
(print_path_summary_as_text): Make static. Reimplement to
moving most of existing code to class thread_event_printer,
capturing state as per-thread as appropriate.
(default_tree_diagnostic_path_printer): Add missing 'break' on
final case.
gcc/testsuite/ChangeLog:
* gcc.dg/plugin/diagnostic-test-paths-multithreaded-inline-events.c:
New test.
* gcc.dg/plugin/diagnostic-test-paths-multithreaded-sarif.c: New
test.
* gcc.dg/plugin/diagnostic-test-paths-multithreaded-separate-events.c:
New test.
* gcc.dg/plugin/diagnostic_plugin_test_paths.c: Add support for
generating multithreaded paths.
* gcc.dg/plugin/plugin.exp: Add the new tests.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Diffstat (limited to 'gcc/diagnostic-path.h')
-rw-r--r-- | gcc/diagnostic-path.h | 55 |
1 files changed, 52 insertions, 3 deletions
diff --git a/gcc/diagnostic-path.h b/gcc/diagnostic-path.h index 9d9d629..d39872a 100644 --- a/gcc/diagnostic-path.h +++ b/gcc/diagnostic-path.h @@ -155,6 +155,20 @@ class diagnostic_event virtual const logical_location *get_logical_location () const = 0; virtual meaning get_meaning () const = 0; + + virtual diagnostic_thread_id_t get_thread_id () const = 0; +}; + +/* Abstract base class representing a thread of execution within + a diagnostic_path. + Each diagnostic_event is associated with one thread. + Typically there is just one thread per diagnostic_path. */ + +class diagnostic_thread +{ +public: + virtual ~diagnostic_thread () {} + virtual label_text get_name (bool can_colorize) const = 0; }; /* Abstract base class for getting at a sequence of events. */ @@ -165,8 +179,12 @@ class diagnostic_path virtual ~diagnostic_path () {} virtual unsigned num_events () const = 0; virtual const diagnostic_event & get_event (int idx) const = 0; + virtual unsigned num_threads () const = 0; + virtual const diagnostic_thread & + get_thread (diagnostic_thread_id_t) const = 0; bool interprocedural_p () const; + bool multithreaded_p () const; private: bool get_first_event_in_a_function (unsigned *out_idx) const; @@ -180,7 +198,8 @@ class simple_diagnostic_event : public diagnostic_event { public: simple_diagnostic_event (location_t loc, tree fndecl, int depth, - const char *desc); + const char *desc, + diagnostic_thread_id_t thread_id = 0); ~simple_diagnostic_event (); location_t get_location () const final override { return m_loc; } @@ -198,12 +217,32 @@ class simple_diagnostic_event : public diagnostic_event { return meaning (); } + diagnostic_thread_id_t get_thread_id () const final override + { + return m_thread_id; + } private: location_t m_loc; tree m_fndecl; int m_depth; char *m_desc; // has been i18n-ed and formatted + diagnostic_thread_id_t m_thread_id; +}; + +/* A simple implementation of diagnostic_thread. */ + +class simple_diagnostic_thread : public diagnostic_thread +{ +public: + simple_diagnostic_thread (const char *name) : m_name (name) {} + label_text get_name (bool) const final override + { + return label_text::borrow (m_name); + } + +private: + const char *m_name; // has been i18n-ed and formatted }; /* A simple implementation of diagnostic_path, as a vector of @@ -212,17 +251,27 @@ class simple_diagnostic_event : public diagnostic_event class simple_diagnostic_path : public diagnostic_path { public: - simple_diagnostic_path (pretty_printer *event_pp) - : m_event_pp (event_pp) {} + simple_diagnostic_path (pretty_printer *event_pp); unsigned num_events () const final override; const diagnostic_event & get_event (int idx) const final override; + unsigned num_threads () const final override; + const diagnostic_thread & + get_thread (diagnostic_thread_id_t) const final override; + + diagnostic_thread_id_t add_thread (const char *name); diagnostic_event_id_t add_event (location_t loc, tree fndecl, int depth, const char *fmt, ...) ATTRIBUTE_GCC_DIAG(5,6); + diagnostic_event_id_t + add_thread_event (diagnostic_thread_id_t thread_id, + location_t loc, tree fndecl, int depth, + const char *fmt, ...) + ATTRIBUTE_GCC_DIAG(6,7); private: + auto_delete_vec<simple_diagnostic_thread> m_threads; auto_delete_vec<simple_diagnostic_event> m_events; /* (for use by add_event). */ |