Skip to content
Open
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 @@ -51,6 +51,7 @@ if (ENABLE_SANITIZER)
"${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
set(CMAKE_SHARED_LINKER_FLAGS
"${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=address")
add_compile_definitions(ODBC_ADDRESS_SANITIZER)
else ()
message(WARNING "AddressSanitizer is only supported on UNIX platforms")
endif ()
Expand Down
9 changes: 7 additions & 2 deletions ci/cloudbuild/builds/integration-bq-driver-asan.sh
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ mapfile -t cmake_args < <(cmake::common_args)
BUILD_DIR="/opt/odbc-driver"
# This is the name of DSN set in odbc.ini
export ODBC_TESTS_DSN="SampleDSNGoogleDriver"
export LSAN_OPTIONS="use_tls=0:suppressions=/opt/odbc-driver/lsan.supp:print_suppressions=0"
export LSAN_OPTIONS="use_tls=0:suppressions=/opt/odbc-driver/lsan.supp:print_suppressions=0:fast_unwind_on_malloc=0"
ASAN_SYMBOLIZER_PATH="$(command -v llvm-symbolizer)"
export ASAN_SYMBOLIZER_PATH

export CPP_BIGQUERY_ODBC_TEST_TABLE_PREFIX=${TRIGGER_NAME//[-:;.,?]/_}_${BRANCH_NAME//[-:;.,?]/_}

Expand All @@ -76,6 +78,8 @@ fi
io::run cmake -B "$BUILD_DIR" \
"${cmake_args[@]}" \
-DCMAKE_TOOLCHAIN_FILE="${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" \
-DVCPKG_OVERLAY_TRIPLETS="${WORKSPACE_DIR}/ci/cloudbuild/triplets" \
-DVCPKG_TARGET_TRIPLET=x64-linux-asan \
-DCMAKE_CXX_STANDARD=17 \
-DODBC_INTEGRATION_TESTING=ON \
-DBQ_DRIVER_INTEGRATION_TESTS=ON \
Expand All @@ -84,8 +88,9 @@ io::run cmake -B "$BUILD_DIR" \
-DODBC_EXAMPLES=ON \
-DODBC_UNIT_TESTING=OFF \
-DCLIENT_LIBRARY_INTEGRATION_TESTING=OFF

io::run cmake --build cmake-out

# Copy the roots.pem file to the .so directory to run test cases.
io::run cp /opt/odbc-driver/roots.pem "cmake-out/google/cloud/odbc/roots.pem"
mapfile -t ctest_args < <(ctest::common_args)
io::run env -C cmake-out ctest "${ctest_args[@]}"
23 changes: 23 additions & 0 deletions ci/cloudbuild/triplets/x64-linux-asan.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.

# Keep ASan-instrumented dependencies separate from the normal x64-linux
# binaries in vcpkg's binary cache.
set(VCPKG_TARGET_ARCHITECTURE x64)
set(VCPKG_CMAKE_SYSTEM_NAME Linux)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE static)
set(VCPKG_C_FLAGS "-O1 -fsanitize=address -fno-omit-frame-pointer -g")
set(VCPKG_CXX_FLAGS "-O1 -fsanitize=address -fno-omit-frame-pointer -g")
set(VCPKG_LINKER_FLAGS "-fsanitize=address")
5 changes: 5 additions & 0 deletions ci/gha/builds/lib/lsan.supp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ leak:conv_text_m2d
leak:__interceptor_malloc
leak:__interceptor_calloc
leak:_iodbcdm_driverload
leak:_iodbcdm_driverunload
leak:_iodbcdm_pushsqlerr
leak:grpc_jwt_encode_and_sign
leak:grpc_core::DoSslRead
leak:grpc_core::DoSslWrite
leak:calloc
leak:Diagnostics::AddStatusRecord
leak:StatusRecord
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1227,9 +1227,7 @@ TEST(ConnectionTest, SQLBrowseConnect_InvalidConnectionAttribute) {
HasSubstr("Catalog:Catalog=?;OAuthMechanism:OAuthMechanism=?"));
#endif // _WIN32
}
// Pass `false` to indicate that the Driver Manager (DM) will automatically
// free the environment handle when the last connection handle is released.
CleanupODBCHandles(*conn, false);
CleanupODBCHandles(*conn);
}

TEST(ConnectionTest, SQLBrowseConnect_InvalidConnectionString) {
Expand Down Expand Up @@ -1489,6 +1487,9 @@ TEST(SQLDisconnect, CheckAllHandlesAreFreed) {
auto status = SQLAllocHandle(SQL_HANDLE_DESC, conn->hdbc, &conn->ard);
CheckError(status, "SQLAllocHandle(SQL_HANDLE_DESC)", conn);

status = SQLFreeHandle(SQL_HANDLE_DESC, conn->ard);
CheckError(status, "SQLFreeHandle(SQL_HANDLE_DESC)", conn);

status = SQLDisconnect(conn->hdbc);
CheckError(status, "SQLDisconnect", conn);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,9 @@ TEST(SQLGetTypeInfoTest, all_datatypes) {
// reach this TEST
// TODO(b/477506552): Fix memory issue in SQLGetTypeInfoTest bind offset
TEST(SQLGetTypeInfoTest, all_datatypes_with_offset) {
#ifdef ODBC_ADDRESS_SANITIZER
GTEST_SKIP() << "The row-bind-offset test is not ASAN-safe.";
#endif
#ifdef NDEBUG
GTEST_SKIP();
#endif // NDEBUG
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -830,6 +830,9 @@ TEST(StatementTest, SQLExecute_UsingDescriptor) {
CheckError(status, "SQLAllocHandle", conn);

EXPECT_EQ(InsertStatementWithoutBindParameter(conn), SQL_SUCCESS);
status = SQLFreeHandle(SQL_HANDLE_DESC, conn->apd);
CheckError(status, "SQLFreeHandle(SQL_HANDLE_DESC)", conn);
conn->apd = nullptr;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need to explicitly need to set the descriptor here?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

conn->apd is an explicitly allocated application parameter descriptor, so its lifetime is separate from the statement handle. In this test, Disconnect() frees the statement/connection/environment handles but does not free conn->apd. ASAN therefore reports the descriptor allocation as leaked.

EXPECT_EQ(Disconnect(conn), SQL_SUCCESS);
////////////////
/// USE ANSI
Expand All @@ -852,6 +855,9 @@ TEST(StatementTest, SQLExecute_UsingDescriptor) {
CheckError(status, "SQLAllocHandle", conn);

EXPECT_EQ(InsertStatementWithoutBindParameter(conn, true), SQL_SUCCESS);
status = SQLFreeHandle(SQL_HANDLE_DESC, conn->apd);
CheckError(status, "SQLFreeHandle(SQL_HANDLE_DESC)", conn);
conn->apd = nullptr;
EXPECT_EQ(Disconnect(conn), SQL_SUCCESS);
}

Expand Down
Loading