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/analyzer | |
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/analyzer')
-rw-r--r-- | gcc/analyzer/checker-event.h | 4 | ||||
-rw-r--r-- | gcc/analyzer/checker-path.h | 17 |
2 files changed, 20 insertions, 1 deletions
diff --git a/gcc/analyzer/checker-event.h b/gcc/analyzer/checker-event.h index 5dd25cb..7ba92f1 100644 --- a/gcc/analyzer/checker-event.h +++ b/gcc/analyzer/checker-event.h @@ -113,6 +113,10 @@ public: return NULL; } meaning get_meaning () const override; + diagnostic_thread_id_t get_thread_id () const final override + { + return 0; + } /* Additional functionality. */ diff --git a/gcc/analyzer/checker-path.h b/gcc/analyzer/checker-path.h index 627f64e..93c807c 100644 --- a/gcc/analyzer/checker-path.h +++ b/gcc/analyzer/checker-path.h @@ -30,7 +30,11 @@ namespace ana { class checker_path : public diagnostic_path { public: - checker_path (logger *logger) : diagnostic_path (), m_logger (logger) {} + checker_path (logger *logger) + : diagnostic_path (), + m_thread ("main"), + m_logger (logger) + {} /* Implementation of diagnostic_path vfuncs. */ @@ -43,6 +47,15 @@ public: { return *m_events[idx]; } + unsigned num_threads () const final override + { + return 1; + } + const diagnostic_thread & + get_thread (diagnostic_thread_id_t) const final override + { + return m_thread; + } checker_event *get_checker_event (int idx) { @@ -120,6 +133,8 @@ public: private: DISABLE_COPY_AND_ASSIGN(checker_path); + simple_diagnostic_thread m_thread; + /* The events that have occurred along this path. */ auto_delete_vec<checker_event> m_events; |