aboutsummaryrefslogtreecommitdiff
path: root/gcc/diagnostic-path.h
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2023-09-14 16:28:45 -0400
committerDavid Malcolm <dmalcolm@redhat.com>2023-09-14 16:28:45 -0400
commit3a1e9f3ed7aa49adad02190ace0614e0b37fc089 (patch)
tree71ebe918a9745e69d37686d69658ba7772022890 /gcc/diagnostic-path.h
parent59f6185b59f71175bb2bf7f380a2a6ec706ee8c9 (diff)
downloadgcc-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.h55
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). */