Skip to content

Commit

Permalink
MINOR: [CI][C++] Enable core dumps and stack traces in Linux/macOS jo…
Browse files Browse the repository at this point in the history
…bs (apache#43937)

### Rationale for this change

In apache#43936 I noticed that core dumps were not written out for crashing C++ tests. One problem is that, by default, Ubuntu hosts pipe core dumps to `apport`, but it is not available inside containers. Another is that the `ulimit` must be set in the host, not in the container.

In addition, this PR restores automatic traceback generation when running C++ tests, on Linux and macOS jobs.

### Are these changes tested?

Manually by introducing a spurious segfault and running Docker containers.

### Are there any user-facing changes?

No.

Lead-authored-by: Antoine Pitrou <antoine@python.org>
Co-authored-by: Antoine Pitrou <pitrou@free.fr>
Co-authored-by: Sutou Kouhei <kou@cozmixng.org>
Signed-off-by: Sutou Kouhei <kou@clear-code.com>
  • Loading branch information
3 people authored and khwilson committed Sep 14, 2024
1 parent 2fc9dc1 commit d658f64
Show file tree
Hide file tree
Showing 20 changed files with 70 additions and 31 deletions.
5 changes: 2 additions & 3 deletions .github/workflows/cpp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,7 @@ jobs:
run: |
# GH-40558: reduce ASLR to avoid ASAN/LSAN crashes
sudo sysctl -w vm.mmap_rnd_bits=28
sudo sysctl -w kernel.core_pattern="core.%e.%p"
ulimit -c unlimited
source ci/scripts/util_enable_core_dumps.sh
archery docker run ${{ matrix.image }}
- name: Docker Push
if: >-
Expand Down Expand Up @@ -272,7 +271,7 @@ jobs:
shell: bash
run: |
sudo sysctl -w kern.coredump=1
sudo sysctl -w kern.corefile=core.%N.%P
sudo sysctl -w kern.corefile=/tmp/core.%N.%P
ulimit -c unlimited # must enable within the same shell
ci/scripts/cpp_test.sh $(pwd) $(pwd)/build
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,7 @@ jobs:
ARCHERY_DOCKER_USER: ${{ secrets.DOCKERHUB_USER }}
ARCHERY_DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }}
run: |
sudo sysctl -w kernel.core_pattern="core.%e.%p"
ulimit -c unlimited
source ci/scripts/util_enable_core_dumps.sh
archery docker run -e GITHUB_ACTIONS=true ubuntu-lint
- name: Docker Push
if: >-
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ jobs:
ARCHERY_DOCKER_USER: ${{ secrets.DOCKERHUB_USER }}
ARCHERY_DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }}
run: >
source ci/scripts/util_enable_core_dumps.sh
archery docker run \
-e ARCHERY_DEFAULT_BRANCH=${{ github.event.repository.default_branch }} \
-e ARCHERY_INTEGRATION_WITH_NANOARROW=1 \
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/java_jni.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ jobs:
env:
ARCHERY_DOCKER_USER: ${{ secrets.DOCKERHUB_USER }}
ARCHERY_DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }}
run: archery docker run java-jni-manylinux-2014
run: |
source ci/scripts/util_enable_core_dumps.sh
archery docker run java-jni-manylinux-2014
- name: Docker Push
if: >-
success() &&
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,7 @@ jobs:
ARCHERY_DOCKER_USER: ${{ secrets.DOCKERHUB_USER }}
ARCHERY_DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }}
run: |
sudo sysctl -w kernel.core_pattern="core.%e.%p"
ulimit -c unlimited
source ci/scripts/util_enable_core_dumps.sh
archery docker run debian-js
- name: Docker Push
if: >-
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,7 @@ jobs:
ARCHERY_DOCKER_USER: ${{ secrets.DOCKERHUB_USER }}
ARCHERY_DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }}
run: |
sudo sysctl -w kernel.core_pattern="core.%e.%p"
ulimit -c unlimited
source ci/scripts/util_enable_core_dumps.sh
archery docker run ${{ matrix.image }}
- name: Docker Push
if: >-
Expand Down
6 changes: 2 additions & 4 deletions .github/workflows/r.yml
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,7 @@ jobs:
ARCHERY_DOCKER_USER: ${{ secrets.DOCKERHUB_USER }}
ARCHERY_DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }}
run: |
sudo sysctl -w kernel.core_pattern="core.%e.%p"
ulimit -c unlimited
source ci/scripts/util_enable_core_dumps.sh
# Setting a non-default and non-probable Marquesas French Polynesia time
# it has both with a .45 offset and very very few people who live there.
archery docker run -e TZ=MART -e ARROW_R_FORCE_TESTS=${{ matrix.force-tests }} ubuntu-r
Expand Down Expand Up @@ -218,8 +217,7 @@ jobs:
ARCHERY_DOCKER_USER: ${{ secrets.DOCKERHUB_USER }}
ARCHERY_DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }}
run: |
sudo sysctl -w kernel.core_pattern="core.%e.%p"
ulimit -c unlimited
source ci/scripts/util_enable_core_dumps.sh
# Don't set a TZ here to test that case. These builds will have the following warning in them:
# System has not been booted with systemd as init system (PID 1). Can't operate.
# Failed to connect to bus: Host is down
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/ruby.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,7 @@ jobs:
ARCHERY_DOCKER_USER: ${{ secrets.DOCKERHUB_USER }}
ARCHERY_DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }}
run: |
sudo sysctl -w kernel.core_pattern="core.%e.%p"
ulimit -c unlimited
source ci/scripts/util_enable_core_dumps.sh
archery docker run \
-e ARROW_FLIGHT=ON \
-e ARROW_FLIGHT_SQL=ON \
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/swift.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ jobs:
ARCHERY_DOCKER_USER: ${{ secrets.DOCKERHUB_USER }}
ARCHERY_DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }}
run: |
sudo sysctl -w kernel.core_pattern="core.%e.%p"
ulimit -c unlimited
source ci/scripts/util_enable_core_dumps.sh
archery docker run ubuntu-swift
- name: Docker Push
if: >-
Expand Down
1 change: 1 addition & 0 deletions ci/docker/fedora-39-cpp.dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ RUN dnf update -y && \
curl-devel \
gcc \
gcc-c++ \
gdb \
gflags-devel \
git \
glog-devel \
Expand Down
1 change: 1 addition & 0 deletions ci/docker/ubuntu-20.04-cpp-minimal.dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ RUN apt-get update -y -q && \
ccache \
cmake \
curl \
gdb \
git \
libssl-dev \
libcurl4-openssl-dev \
Expand Down
1 change: 1 addition & 0 deletions ci/docker/ubuntu-22.04-cpp-minimal.dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ RUN apt-get update -y -q && \
ccache \
cmake \
curl \
gdb \
git \
libssl-dev \
libcurl4-openssl-dev \
Expand Down
1 change: 1 addition & 0 deletions ci/docker/ubuntu-24.04-cpp-minimal.dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ RUN apt-get update -y -q && \
ccache \
cmake \
curl \
gdb \
git \
libssl-dev \
libcurl4-openssl-dev \
Expand Down
33 changes: 33 additions & 0 deletions ci/scripts/util_enable_core_dumps.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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
#
# http://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.

# NOTE: this script is not marked executable as it should be source'd
# for `ulimit` to take effect.

set -e

platform=$(uname)

if [ "${platform}" = "Linux" ]; then
# We need to override `core_pattern` because
# 1. the original setting may reference apport, which is not available under
# most Docker containers;
# 2. we want to write the core file in a well-known directory.
sudo sysctl -w kernel.core_pattern="/tmp/core.%e.%p"
fi

ulimit -c unlimited
23 changes: 14 additions & 9 deletions cpp/build-support/run-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -121,32 +121,37 @@ function print_coredumps() {
# patterns must be set with prefix `core.{test-executable}*`:
#
# In case of macOS:
# sudo sysctl -w kern.corefile=core.%N.%P
# sudo sysctl -w kern.corefile=/tmp/core.%N.%P
# On Linux:
# sudo sysctl -w kernel.core_pattern=core.%e.%p
# sudo sysctl -w kernel.core_pattern=/tmp/core.%e.%p
#
# and the ulimit must be increased:
# ulimit -c unlimited
#
# If the tests are run in a Docker container, the instructions are slightly
# different: see the 'Coredumps' comment section in `docker-compose.yml`.

# filename is truncated to the first 15 characters in case of linux, so limit
# the pattern for the first 15 characters
FILENAME=$(basename "${TEST_EXECUTABLE}")
FILENAME=$(echo ${FILENAME} | cut -c-15)
PATTERN="^core\.${FILENAME}"

COREFILES=$(ls | grep $PATTERN)
COREFILES=$(ls /tmp | grep $PATTERN)
if [ -n "$COREFILES" ]; then
echo "Found core dump, printing backtrace:"

for COREFILE in $COREFILES; do
COREPATH="/tmp/${COREFILE}"
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
echo "Running '${TEST_EXECUTABLE}' produced core dump at '${COREPATH}', printing backtrace:"
# Print backtrace
if [ "$(uname)" == "Darwin" ]; then
lldb -c "${COREFILE}" --batch --one-line "thread backtrace all -e true"
lldb -c "${COREPATH}" --batch --one-line "thread backtrace all -e true"
else
gdb -c "${COREFILE}" $TEST_EXECUTABLE -ex "thread apply all bt" -ex "set pagination 0" -batch
gdb -c "${COREPATH}" $TEST_EXECUTABLE -ex "thread apply all bt" -ex "set pagination 0" -batch
fi
# Remove the coredump, regenerate it via running the test case directly
rm "${COREFILE}"
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
# Remove the coredump, it can be regenerated via running the test case directly
rm "${COREPATH}"
done
fi
}
Expand Down
1 change: 1 addition & 0 deletions dev/tasks/docker-tests/github.cuda.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ jobs:
env:
{{ macros.github_set_sccache_envvars()|indent(8) }}
run: |
source arrow/ci/scripts/util_enable_core_dumps.sh
archery docker run \
-e SETUPTOOLS_SCM_PRETEND_VERSION="{{ arrow.no_rc_version }}" \
{{ flags|default("") }} \
Expand Down
1 change: 1 addition & 0 deletions dev/tasks/docker-tests/github.linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ jobs:
run: |
# GH-40558: reduce ASLR to avoid TSAN crashing
sudo sysctl -w vm.mmap_rnd_bits=28
source arrow/ci/scripts/util_enable_core_dumps.sh
archery docker run \
-e SETUPTOOLS_SCM_PRETEND_VERSION="{{ arrow.no_rc_version }}" \
{{ flags|default("") }} \
Expand Down
1 change: 1 addition & 0 deletions dev/tasks/python-wheels/github.linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ jobs:
- name: Test wheel
shell: bash
run: |
source arrow/ci/scripts/util_enable_core_dumps.sh
archery docker run python-wheel-manylinux-test-imports
archery docker run python-wheel-manylinux-test-unittests
Expand Down
3 changes: 1 addition & 2 deletions dev/tasks/r/github.packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,7 @@ jobs:
UBUNTU: {{ '"${{ matrix.ubuntu }}"' }}
{{ macros.github_set_sccache_envvars()|indent(8) }}
run: |
sudo sysctl -w kernel.core_pattern="core.%e.%p"
ulimit -c unlimited
source ci/scripts/util_enable_core_dumps.sh
archery docker run \
-e EXTRA_CMAKE_FLAGS="{{ '${{ matrix.extra-cmake-flags }}' }}" \
{{ '${{ matrix.os }}' }}-cpp-static
Expand Down
4 changes: 2 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@
# WARNING: setting this will affect the host machine.
#
# Linux host:
# $ sudo sysctl -w kernel.core_pattern=core.%e.%p
# $ sudo sysctl -w kernel.core_pattern=/tmp/core.%e.%p
#
# macOS host running Docker for Mac (won't persist between restarts):
# $ screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty
# # echo "core.%e.%p" > /proc/sys/kernel/core_pattern
# # echo "/tmp/core.%e.%p" > /proc/sys/kernel/core_pattern
#
# The setup attempts to generate coredumps by default, but the correct paths
# above must be set. In order to disable the coredump generation set
Expand Down

0 comments on commit d658f64

Please sign in to comment.