Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check Delta Valgrind Logs #21

Draft
wants to merge 18 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 119 additions & 0 deletions .github/workflows/valgrind.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# Copyright (C) 2021 Intel Corporation
# SPDX-License-Identifier: BSD-3-Clause

# https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions

name: valgrind incremental checks

permissions:
# Grant read permissions to repository in case it is not a forked public
# repository, but a private repository that was created manually.
contents: read

# Grant read permissions to private container images.
packages: read

on:
pull_request:
paths:
- '**'
- '!**.md'
- '!**/.clang-format'
- '!**/COPYING'
- '!**/LICENSE'
- '!.github/**'
- '.github/workflows/valgrind.yml'
- '!.gitignore'
- '!cmake/manifests/**'
- 'cmake/manifests/linux/**'
- '!container/**'
- '!docs/**'
- '!scripts/**'

jobs:
build:
runs-on: ubuntu-20.04

container:
image: ghcr.io/intel/fpga-runtime-for-opencl/ubuntu-20.04-dev:main

env:
TMP_DIR: /home/build/

steps:
- name: change ownership of workspace to current user
run: sudo chown -R build:build .

- name: install valgrind
run: sudo apt-get install -y valgrind gawk

- name: checkout current branch
uses: actions/checkout@v2

- name: copy necessary suppression files
run: cp ./scripts/valgrind_suppression.supp "$TMP_DIR/valgrind_suppression_base.supp"

- name: checkout main branch
uses: actions/checkout@v2
with:
ref: ${{ github.base_ref }}

- name: create build directories
run: mkdir "$TMP_DIR/child_build" "$TMP_DIR/parent_build"

- name: create parent build files
run: cd "$TMP_DIR/parent_build" && cmake -G Ninja "$GITHUB_WORKSPACE" -DCMAKE_BUILD_TYPE=Debug

- name: build parent runtime
run: cd "$TMP_DIR/parent_build" && ninja -v -k0

- name: parent runtime valgrind scan
run: cd "$TMP_DIR/parent_build" && ctest --overwrite MemoryCheckCommandOptions="--leak-check=full --show-reachable=yes --error-limit=no --gen-suppressions=all" -T memcheck

- name: checkout current branch
uses: actions/checkout@v2

- name: get parent valgrind suppression file
run: |
cat "$TMP_DIR/parent_build/Testing/Temporary/MemoryChecker.6.log" | ./scripts/parse_valgrind_suppressions.sh > "$TMP_DIR/valgrind_suppression.supp"
cat "$TMP_DIR/valgrind_suppression_base.supp" >> "$TMP_DIR/valgrind_suppression.supp"

- name: upload valgrind report as manifest
uses: actions/upload-artifact@v2
with:
name: suppression-${{ github.run_id }}
path: /home/build/valgrind_suppression.supp

- name: create child build files
run: cd "$TMP_DIR/child_build" && cmake -G Ninja "$GITHUB_WORKSPACE" -DCMAKE_BUILD_TYPE=Debug

- name: build child runtime
run: cd "$TMP_DIR/child_build" && ninja -v -k0

- name: child runtime valgrind scan
run: cd "$TMP_DIR/child_build" && ctest --overwrite MemoryCheckCommandOptions="--leak-check=full --show-reachable=yes --error-limit=no" --overwrite MemoryCheckSuppressionFile="$TMP_DIR/valgrind_suppression.supp" -T memcheck

- name: upload parent valgrind report as manifest
uses: actions/upload-artifact@v2
with:
name: parent-valgrind-${{ github.run_id }}
path: /home/build/parent_build/Testing/Temporary/MemoryChecker.6.log

- name: upload child valgrind report as manifest
uses: actions/upload-artifact@v2
with:
name: valgrind-${{ github.run_id }}
path: /home/build/child_build/Testing/Temporary/MemoryChecker.6.log

- name: valgrind incremental
run: |
if [ -s "$TMP_DIR/child_build/Testing/Temporary/MemoryChecker.6.log" ]; then
# The valgrind log after suppressing all parent log is not empty
cat "$TMP_DIR/child_build/Testing/Temporary/MemoryChecker.6.log"
exit 1
fi


- name: revert ownership of workspace to root
run: sudo chown -R root:root .
if: always()
35 changes: 35 additions & 0 deletions scripts/delta_valgrind.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/bin/bash
# Copyright (C) 2021 Intel Corporation
# SPDX-License-Identifier: BSD-3-Clause

# Install Intel FPGA SDK for OpenCL Pro Edition
# https://fpgasoftware.intel.com/

set -eu -o pipefail

parent_valgrind_report="$1"
child_valgrind_report="$2"

# remove ==29048== patern from beginning
echo 'Removing line prefix'
sed -i -E "s/==.*== //" ${parent_valgrind_report}
sed -i -E "s/==.*== //" ${child_valgrind_report}
# remove memory address
echo 'Removing memory address'
sed -i -E "s/0x.*: //" ${parent_valgrind_report}
sed -i -E "s/0x.*: //" ${child_valgrind_report}
# remove file header
echo 'Removing file header'
sed -i -e '1,/Parent PID/ d' ${parent_valgrind_report}
sed -i -e '1,/Parent PID/ d' ${child_valgrind_report}
# remove source code line number
echo 'Removing source code line number'
sed -i -E "s/\(([^)]*)\)[^(]*$//" ${parent_valgrind_report}
sed -i -E "s/\(([^)]*)\)[^(]*$//" ${child_valgrind_report}
# remove file ending
echo 'Removing file ending'
sed -i -e '/LEAK SUMMARY/Q' ${parent_valgrind_report}
sed -i -e '/LEAK SUMMARY/Q' ${child_valgrind_report}
# check what is added to second file
echo 'Delta check'
comm -13 ${parent_valgrind_report} ${child_valgrind_report}
57 changes: 57 additions & 0 deletions scripts/parse_valgrind_suppressions.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#! /usr/bin/gawk -f
# A script to extract the actual suppression info from the output of (for example) valgrind --leak-check=full --show-reachable=yes --error-limit=no --gen-suppressions=all ./minimal
# The desired bits are between ^{ and ^} (including the braces themselves).
# The combined output should either be appended to /usr/lib/valgrind/default.supp, or placed in a .supp of its own
# If the latter, either tell valgrind about it each time with --suppressions=<filename>, or add that line to ~/.valgrindrc

# NB This script uses the |& operator, which I believe is gawk-specific. In case of failure, check that you're using gawk rather than some other awk

# The script looks for suppressions. When it finds one it stores it temporarily in an array,
# and also feeds it line by line to the external app 'md5sum' which generates a unique checksum for it.
# The checksum is used as an index in a different array. If an item with that index already exists the suppression must be a duplicate and is discarded.

BEGIN { suppression=0; md5sum = "md5sum" }
# If the line begins with '{', it's the start of a supression; so set the var and initialise things
/^{/ {
suppression=1; i=0; next
}
# If the line begins with '}' its the end of a suppression
/^}/ {
if (suppression)
{ suppression=0;
close(md5sum, "to") # We've finished sending data to md5sum, so close that part of the pipe
ProcessInput() # Do the slightly-complicated stuff in functions
delete supparray # We don't want subsequent suppressions to append to it!
}
}
# Otherwise, it's a normal line. If we're inside a supression, store it, and pipe it to md5sum. Otherwise it's cruft, so ignore it
{ if (suppression)
{
supparray[++i] = $0
print |& md5sum
}
}


function ProcessInput()
{
# Pipe the result from md5sum, then close it
md5sum |& getline result
close(md5sum)
# gawk can't cope with enormous ints like $result would be, so stringify it first by prefixing a definite string
resultstring = "prefix"result

if (! (resultstring in chksum_array) )
{ chksum_array[resultstring] = 0; # This checksum hasn't been seen before, so add it to the array
OutputSuppression() # and output the contents of the suppression
}
}

function OutputSuppression()
{
# A suppression is surrounded by '{' and '}'. Its data was stored line by line in the array
print "{"
for (n=1; n <= i; ++n)
{ print supparray[n] }
print "}"
}
56 changes: 56 additions & 0 deletions scripts/valgrind_suppression.supp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
getenv-Cond
Memcheck:Cond
...
fun:getenv
...
}
{
getenv-Addr1
Memcheck:Addr1
...
fun:getenv
...
}
{
getenv-Addr2
Memcheck:Addr2
...
fun:getenv
...
}
{
getenv-Addr4
Memcheck:Addr4
...
fun:getenv
...
}
{
getenv-Addr8
Memcheck:Addr8
...
fun:getenv
...
}
{
getenv-Addr16
Memcheck:Addr16
...
fun:getenv
...
}
{
setenv
Memcheck:Cond
...
fun:setenv
...
}
{
unsetenv
Memcheck:Cond
...
fun:unsetenv
...
}