Skip to content

Commit

Permalink
gcc: use SARIF output with --gcc-analyzer-bin [EXPERIMENTAL]
Browse files Browse the repository at this point in the history
With https://copr.fedorainfracloud.org/coprs/dmalcolm/gcc-latest/
added to the `fedora-41-x86_64` mock config, this can be tested
using the following commands:
```
koji download-build -a src units-2.23-3.fc41
csmock -f units-2.23-3.fc41.src.rpm -r fedora-41-x86_64 --install gcc-latest --gcc-analyzer-bin /opt/gcc-latest/bin/gcc
```

Depends-on: csutils/csdiff#210
  • Loading branch information
kdudka committed Oct 14, 2024
1 parent 05259db commit 8956f6d
Showing 1 changed file with 32 additions and 2 deletions.
34 changes: 32 additions & 2 deletions py/plugins/gcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
# along with csmock. If not, see <http://www.gnu.org/licenses/>.

# standard imports
import os
import subprocess

# local imports
Expand All @@ -25,10 +26,21 @@

CSGCCA_BIN = "/usr/bin/csgcca"

# directory for GCC results (currently used only with `--gcc-analyzer-bin`)
GCC_RESULTS_DIR = "/builddir/gcc-results"

CSMOCK_GCC_WRAPPER_NAME = 'csmock-gcc-wrapper'
CSMOCK_GCC_WRAPPER_PATH = '/usr/bin/%s' % CSMOCK_GCC_WRAPPER_NAME
CSMOCK_GCC_WRAPPER_TEMPLATE = '#!/bin/bash\n' \
'exec %s "$@"'

# script to run gcc analyzer and dump its output to a seaprate SARIF file in GCC_RESULTS_DIR
CSMOCK_GCC_WRAPPER_TEMPLATE = f"""#!/bin/bash
fn=$(flock {GCC_RESULTS_DIR} mktemp "{GCC_RESULTS_DIR}/$$-XXXX.sarif")
set -x
exec %s "$@" -fdiagnostics-format=json-file -fdiagnostics-add-output="sarif:file=$fn"
"""

# command to read and join all captured SARIF files
FILTER_CMD = "csgrep --mode=json --remove-duplicates"

SANITIZER_CAPTURE_DIR = "/builddir/gcc-sanitizer-capture"

Expand Down Expand Up @@ -289,6 +301,24 @@ def csgcca_hook(results, mock):
# tell csgcca to use the wrapped script rather than system gcc analyzer
props.env["CSGCCA_ANALYZER_BIN"] = CSMOCK_GCC_WRAPPER_NAME

# create directory for gcc results
def create_gcc_results_dir_hook(results, mock):
cmd = f"mkdir -pv '{GCC_RESULTS_DIR}' && touch '{GCC_RESULTS_DIR}/empty.sarif'"
return mock.exec_mockbuild_cmd(cmd)
props.post_depinst_hooks += [create_gcc_results_dir_hook]

# copy gcc results out of the chroot
props.copy_out_files += [GCC_RESULTS_DIR]

# process all captured SARIF files
# TODO: avoid exceeding maximum command line length
def filter_hook(results):
src = os.path.join(results.dbgdir_raw, GCC_RESULTS_DIR[1:])
dst = os.path.join(results.dbgdir_uni, "gcc-results.json")
cmd = f"cd {src} && {FILTER_CMD} *.sarif > {dst}"
return results.exec_cmd(cmd, shell=True)
props.post_process_hooks += [filter_hook]

# XXX: changing props this way is extremely fragile
# insert csgcca right before cswrap to avoid chaining
# csclng/cscppc while invoking `gcc -fanalyzer`
Expand Down

0 comments on commit 8956f6d

Please sign in to comment.