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

ci: add open fds valgrind check #4851

Merged
merged 21 commits into from
Nov 12, 2024
Merged
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
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,7 @@ if (BUILD_TESTING)
--error-limit=no \
--num-callers=40 \
--undef-value-errors=no \
--track-fds=yes \
--log-fd=2 \
--suppressions=valgrind.suppressions")

Expand Down
65 changes: 65 additions & 0 deletions codebuild/bin/s2n_open_fds_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
jmayclin marked this conversation as resolved.
Show resolved Hide resolved
# SPDX-License-Identifier: Apache-2.0

# This script parses the LastDynamicAnalysis file generated by Valgrind running through CTest memcheck.
# It identifies any leaking file descriptors and triggers an error when detected.
# This enhances the capabilities of existing Valgrind checks.
# Output snippet for open file descriptors:
# ==6652== FILE DESCRIPTORS: 6 open (3 std) at exit.
# ==6652== Open AF_INET socket 6: 127.0.0.1:36915 <-> unbound
# ==6652== at 0x498B2EB: socket (syscall-template.S:120)
# ==6652== by 0x16CD16: s2n_new_inet_socket_pair (s2n_self_talk_ktls_test.c:69)
# ==6652== by 0x15DBB2: main (s2n_self_talk_ktls_test.c:168)
# ==6652==
import os
jmayclin marked this conversation as resolved.
Show resolved Hide resolved
import sys

EXIT_SUCCESS = 0
# Exit with error code 1 if leaking fds are detected.
ERROR_EXIT_CODE = 1
# This test is designed to be informational only, so we only print fifteen lines of error messages when a leak is detected.
NUM_OF_LINES_TO_PRINT = 15


def find_log_file(path):
for f in os.listdir(path):
if "LastDynamicAnalysis" in f:
return os.path.join(path, f)

raise FileNotFoundError("LastDynamicAnalysis log file is not found!")


def detect_leak(file):
fd_leak_detected = False
lines = file.readlines()
for i in range(len(lines)):
jmayclin marked this conversation as resolved.
Show resolved Hide resolved
if "FILE DESCRIPTORS:" in lines[i]:
# Example line: `==6096== FILE DESCRIPTORS: 4 open (3 std) at exit.`
line_elements = lines[i].split()
open_fd_count = line_elements[line_elements.index("DESCRIPTORS:") + 1]
std_fd_count = line_elements[line_elements.index("std)") - 1][1:]
# CTest memcheck writes to a LastDynamicAnslysis log file.
# We allow that fd to remain opened.
if int(open_fd_count) > int(std_fd_count) + 1:
for j in range(NUM_OF_LINES_TO_PRINT):
print(lines[i + j], end="")
print()
fd_leak_detected = True
return fd_leak_detected


def main():
# Print banner of the test
print("############################################################################")
print("################# Test for Leaking File Descriptors ########################")
print("############################################################################")

with open(find_log_file(sys.argv[1]), 'r') as file:
if detect_leak(file):
sys.exit(ERROR_EXIT_CODE)

return EXIT_SUCCESS


if __name__ == '__main__':
main()
4 changes: 3 additions & 1 deletion codebuild/spec/buildspec_valgrind.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ batch:
- identifier: gcc_openssl_1_1_1
env:
compute-type: BUILD_GENERAL1_LARGE
image: 024603541914.dkr.ecr.us-west-2.amazonaws.com/docker:ubuntu18codebuild
image: 024603541914.dkr.ecr.us-west-2.amazonaws.com/docker:ubuntu24
variables:
S2N_LIBCRYPTO: openssl-1.1.1
COMPILER: gcc
Expand Down Expand Up @@ -70,3 +70,5 @@ phases:
CTEST_OUTPUT_ON_FAILURE=1 \
cmake --build build/ --target test \
-- ARGS="--test-action memcheck"
- cd codebuild/bin
- python3 s2n_open_fds_test.py $CODEBUILD_SRC_DIR/build/Testing/Temporary
Loading