Skip to content

Commit

Permalink
apacheGH-39973: [C++][CI] Disable debug memory pool for ASAN and Valg…
Browse files Browse the repository at this point in the history
…rind (apache#39975)

### Rationale for this change

Disable debug memory pool for ASAN and Valgrind so that they can detect more subtle memory issues regarding to buffer tail bytes.

### What changes are included in this PR?

1. Add a `none` option to debug memory pool env var to make other things slightly easier.
2. Change `*_test.sh` scripts to conditionally set debug memory pool env var.
3. Top-level docker compose change to pass none to debug memory pool env var for ASAN and Valgrind.

### Are these changes tested?

The CI should cover it well.

### Are there any user-facing changes?

No.

* Closes: apache#39973

Authored-by: Ruoxi Sun <[email protected]>
Signed-off-by: Antoine Pitrou <[email protected]>
  • Loading branch information
zanmato1984 authored and thisisnic committed Mar 8, 2024
1 parent 8a5ed96 commit 8921173
Show file tree
Hide file tree
Showing 10 changed files with 59 additions and 18 deletions.
5 changes: 4 additions & 1 deletion ci/appveyor-cpp-build.bat
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ git submodule update --init || exit /B
set ARROW_TEST_DATA=%CD%\testing\data
set PARQUET_TEST_DATA=%CD%\cpp\submodules\parquet-testing\data

set ARROW_DEBUG_MEMORY_POOL=trap
@rem Enable memory debug checks if the env is not set already
IF "%ARROW_DEBUG_MEMORY_POOL%"=="" (
set ARROW_DEBUG_MEMORY_POOL=trap
)

set CMAKE_BUILD_PARALLEL_LEVEL=%NUMBER_OF_PROCESSORS%
set CTEST_PARALLEL_LEVEL=%NUMBER_OF_PROCESSORS%
Expand Down
6 changes: 4 additions & 2 deletions ci/scripts/c_glib_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ export LD_LIBRARY_PATH=${ARROW_HOME}/lib:${LD_LIBRARY_PATH}
export PKG_CONFIG_PATH=${ARROW_HOME}/lib/pkgconfig
export GI_TYPELIB_PATH=${ARROW_HOME}/lib/girepository-1.0

# Enable memory debug checks.
export ARROW_DEBUG_MEMORY_POOL=trap
# Enable memory debug checks if the env is not set already
if [ -z "${ARROW_DEBUG_MEMORY_POOL}" ]; then
export ARROW_DEBUG_MEMORY_POOL=trap
fi

pushd ${source_dir}

Expand Down
6 changes: 4 additions & 2 deletions ci/scripts/cpp_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@ export LD_LIBRARY_PATH=${ARROW_HOME}/${CMAKE_INSTALL_LIBDIR:-lib}:${LD_LIBRARY_P
# to retrieve metadata. Disable this so that S3FileSystem tests run faster.
export AWS_EC2_METADATA_DISABLED=TRUE

# Enable memory debug checks.
export ARROW_DEBUG_MEMORY_POOL=trap
# Enable memory debug checks if the env is not set already
if [ -z "${ARROW_DEBUG_MEMORY_POOL}" ]; then
export ARROW_DEBUG_MEMORY_POOL=trap
fi

ctest_options=()
case "$(uname)" in
Expand Down
6 changes: 4 additions & 2 deletions ci/scripts/python_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ export ARROW_GDB_SCRIPT=${arrow_dir}/cpp/gdb_arrow.py
# Enable some checks inside Python itself
export PYTHONDEVMODE=1

# Enable memory debug checks.
export ARROW_DEBUG_MEMORY_POOL=trap
# Enable memory debug checks if the env is not set already
if [ -z "${ARROW_DEBUG_MEMORY_POOL}" ]; then
export ARROW_DEBUG_MEMORY_POOL=trap
fi

# By default, force-test all optional components
: ${PYARROW_TEST_ACERO:=${ARROW_ACERO:-ON}}
Expand Down
6 changes: 4 additions & 2 deletions ci/scripts/r_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,10 @@ export _R_CHECK_STOP_ON_INVALID_NUMERIC_VERSION_INPUTS_=TRUE
# to retrieve metadata. Disable this so that S3FileSystem tests run faster.
export AWS_EC2_METADATA_DISABLED=TRUE

# Enable memory debug checks.
export ARROW_DEBUG_MEMORY_POOL=trap
# Enable memory debug checks if the env is not set already
if [ -z "${ARROW_DEBUG_MEMORY_POOL}" ]; then
export ARROW_DEBUG_MEMORY_POOL=trap
fi

# Hack so that texlive2020 doesn't pollute the home dir
export TEXMFCONFIG=/tmp/texmf-config
Expand Down
6 changes: 4 additions & 2 deletions ci/scripts/ruby_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ export LD_LIBRARY_PATH=${ARROW_HOME}/lib:${LD_LIBRARY_PATH}
export PKG_CONFIG_PATH=${ARROW_HOME}/lib/pkgconfig
export GI_TYPELIB_PATH=${ARROW_HOME}/lib/girepository-1.0

# Enable memory debug checks.
export ARROW_DEBUG_MEMORY_POOL=trap
# Enable memory debug checks if the env is not set already
if [ -z "${ARROW_DEBUG_MEMORY_POOL}" ]; then
export ARROW_DEBUG_MEMORY_POOL=trap
fi

rake -f ${source_dir}/Rakefile BUILD_DIR=${build_dir} USE_BUNDLER=yes
4 changes: 2 additions & 2 deletions cpp/src/arrow/memory_pool.cc
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ bool IsDebugEnabled() {
return false;
}
auto env_value = *std::move(maybe_env_value);
if (env_value.empty()) {
if (env_value.empty() || env_value == "none") {
return false;
}
auto debug_state = DebugState::Instance();
Expand All @@ -212,7 +212,7 @@ bool IsDebugEnabled() {
return true;
}
ARROW_LOG(WARNING) << "Invalid value for " << kDebugMemoryEnvVar << ": '" << env_value
<< "'. Valid values are 'abort', 'trap', 'warn'.";
<< "'. Valid values are 'abort', 'trap', 'warn', 'none'.";
return false;
}();

Expand Down
4 changes: 4 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,8 @@ services:
# Shrink test runtime by enabling minimal optimizations
ARROW_C_FLAGS_DEBUG: "-g1 -Og"
ARROW_CXX_FLAGS_DEBUG: "-g1 -Og"
# GH-39973: Do not use debug memory pool for valgrind
ARROW_DEBUG_MEMORY_POOL: "none"
ARROW_ENABLE_TIMING_TESTS: # inherit
ARROW_FLIGHT: "OFF"
ARROW_FLIGHT_SQL: "OFF"
Expand Down Expand Up @@ -598,6 +600,8 @@ services:
CXX: clang++-${CLANG_TOOLS}
# Avoid creating huge static libraries
ARROW_BUILD_STATIC: "OFF"
# GH-39973: Do not use debug memory pool for ASAN
ARROW_DEBUG_MEMORY_POOL: "none"
ARROW_ENABLE_TIMING_TESTS: # inherit
# GH-33920: Disable Flight SQL to reduce build time.
# We'll be able to re-enable this with Ubuntu 24.04 because
Expand Down
4 changes: 3 additions & 1 deletion docs/source/cpp/env_vars.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,10 @@ that changing their value later will have an effect.
- ``abort`` exits the processus with a non-zero return value;
- ``trap`` issues a platform-specific debugger breakpoint / trap instruction;
- ``warn`` prints a warning on stderr and continues execution;
- ``none`` disables memory checks;

If this variable is not set, or has empty an value, memory checks are disabled.
If this variable is not set, or has an empty value, it has the same effect
as the value ``none`` - memory checks are disabled.

.. note::
While this functionality can be useful and has little overhead, it
Expand Down
30 changes: 26 additions & 4 deletions python/pyarrow/tests/test_memory.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,13 +243,35 @@ def test_debug_memory_pool_warn(pool_factory):
assert "Wrong size on deallocation" in res.stderr


@pytest.mark.parametrize('pool_factory', supported_factories())
def test_debug_memory_pool_disabled(pool_factory):
res = run_debug_memory_pool(pool_factory.__name__, "")
def check_debug_memory_pool_disabled(pool_factory, env_value, msg):
res = run_debug_memory_pool(pool_factory.__name__, env_value)
# The subprocess either returned successfully or was killed by a signal
# (due to writing out of bounds), depending on the underlying allocator.
if os.name == "posix":
assert res.returncode <= 0
else:
res.check_returncode()
assert res.stderr == ""
if msg == "":
assert res.stderr == ""
else:
assert msg in res.stderr


@pytest.mark.parametrize('pool_factory', supported_factories())
def test_debug_memory_pool_none(pool_factory):
check_debug_memory_pool_disabled(pool_factory, "none", "")


@pytest.mark.parametrize('pool_factory', supported_factories())
def test_debug_memory_pool_empty(pool_factory):
check_debug_memory_pool_disabled(pool_factory, "", "")


@pytest.mark.parametrize('pool_factory', supported_factories())
def test_debug_memory_pool_unknown(pool_factory):
env_value = "some_arbitrary_value"
msg = (
f"Invalid value for ARROW_DEBUG_MEMORY_POOL: '{env_value}'. "
"Valid values are 'abort', 'trap', 'warn', 'none'."
)
check_debug_memory_pool_disabled(pool_factory, env_value, msg)

0 comments on commit 8921173

Please sign in to comment.