diagnostics: attempt to capture crash info in SARIF output [PR109097]
commit79aaba0a71f34ac1ac2c4cec907ff74740a6cf1a
authorDavid Malcolm <dmalcolm@redhat.com>
Wed, 15 Mar 2023 22:16:17 +0000 (15 18:16 -0400)
committerDavid Malcolm <dmalcolm@redhat.com>
Wed, 15 Mar 2023 22:16:17 +0000 (15 18:16 -0400)
treead711922dc84fab4a2730846463d8eb2cf6521d8
parent8f1711ef3486b0727ccf6b5aabddda5c7d986457
diagnostics: attempt to capture crash info in SARIF output [PR109097]

As noted in PR analyzer/109097, if an internal compiler error occurs
when -fdiagnostics-format=sarif-file is specified, we currently fail
to write out a .sarif file, and the output to stderr doesn't contain
"internal compiler error" or "Internal compiler error"; just the
backtrace if we're lucky, and the "Please submit a full bug report"
messages.

This is a nuisance e.g. for my integration testing of -fanalyzer, where
I'm gathering the results of builds via the .sarif output: if it crashes
on a particular source file, then no output is generated, and it's
effectively silent about the crash.

This patch fixes things by adding a callback to diagnostic_context so
that the SARIF output code can make one final attempt to write its
output if an ICE occurs.  It also special-cases the output, so that an
ICE is treated as an "error"-level "notification" relating to the
operation of the tool (SARIF v2.1.0 section 3.58), rather than a
"result" about the code being analyzed by the tool.

The patch adds test coverage for this via a plugin that can inject:
* calls to internal_compiler_error, and
* writes through a NULL pointer
and verifying that a  .sarif file is written out capturing the crash
(and also that an ICE occurs via dg-ice, which seems to treat the ICE as
an XFAIL, which is reasonable).

I've added support for this to my integration-testing scripts: testing
shows that with this patch we capture analyzer crashes in .sarif files
(specifically, the analyzer crash on qemu: PR analyzer/109094), and I've
updated my scripts to work with and report such output.

I manually verified that the resulting .sarif files validate against the
schema.

gcc/ChangeLog:
PR analyzer/109097
* diagnostic-format-sarif.cc (class sarif_invocation): New.
(class sarif_ice_notification): New.
(sarif_builder::m_invocation_obj): New field.
(sarif_invocation::add_notification_for_ice): New.
(sarif_invocation::prepare_to_flush): New.
(sarif_ice_notification::sarif_ice_notification): New.
(sarif_builder::sarif_builder): Add m_invocation_obj.
(sarif_builder::end_diagnostic): Special-case DK_ICE and
DK_ICE_NOBT.
(sarif_builder::flush_to_file): Call prepare_to_flush on
m_invocation_obj.  Pass the latter to make_top_level_object.
(sarif_builder::make_result_object): Move creation of "locations"
array to...
(sarif_builder::make_locations_arr): ...this new function.
(sarif_builder::make_top_level_object): Add "invocation_obj" param
and pass it to make_run_object.
(sarif_builder::make_run_object): Add "invocation_obj" param and
use it.
(sarif_ice_handler): New callback.
(diagnostic_output_format_init_sarif): Wire up sarif_ice_handler.
* diagnostic.cc (diagnostic_initialize): Initialize new field
"ice_handler_cb".
(diagnostic_action_after_output): If it is set, make one attempt
to call ice_handler_cb.
* diagnostic.h (diagnostic_context::ice_handler_cb): New field.

gcc/testsuite/ChangeLog:
PR analyzer/109097
* c-c++-common/diagnostic-format-sarif-file-1.c: Verify that we
have an invocation object marked as succeeding, with no
notifications.
* gcc.dg/plugin/crash-test-ice-sarif.c: New test.
* gcc.dg/plugin/crash-test-ice-stderr.c: New test.
* gcc.dg/plugin/crash-test-write-though-null-sarif.c: New test.
* gcc.dg/plugin/crash-test-write-though-null-stderr.c: New test.
* gcc.dg/plugin/crash_test_plugin.c: New plugin.
* gcc.dg/plugin/plugin.exp (plugin_test_list): Add the new plugin
and test cases.

Signed-off-by: David Malcolm <dmalcolm@redhat.com>
gcc/diagnostic-format-sarif.cc
gcc/diagnostic.cc
gcc/diagnostic.h
gcc/testsuite/c-c++-common/diagnostic-format-sarif-file-1.c
gcc/testsuite/gcc.dg/plugin/crash-test-ice-sarif.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/plugin/crash-test-ice-stderr.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/plugin/crash-test-write-though-null-sarif.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/plugin/crash-test-write-though-null-stderr.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/plugin/crash_test_plugin.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/plugin/plugin.exp