Skip to content

Commit a60eb66

Browse files
Fix segfaults from CRAN, including GHA to catch ASAN/UBSAN issue (#318)
* GHA to catch ASAN/UBSAN issue * fix installation * pushing further * another attempt * expect_no_error * overhaul * kitchen sink * missed library(patrick) * incidental numeric issue * more kitchen sink turning off compiler optimization * another pass * whitespace yay YAML * another pass * attempt to resolve install issue * another one * ugh * we seem pretty lost here... * try string clang * fix setup? * trying to read straight from the CRAN manual * go harder * down the rabbit hole * sure why not * stick with R CMD check * sneaky sneaky * minimize * stripping down * did we over-do it? maybe * partial restoration * fix segfaults * trigger only on limited PRs * NEWS
1 parent 0451382 commit a60eb66

3 files changed

Lines changed: 51 additions & 9 deletions

File tree

.github/workflows/R-CMD-check.yaml

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ on:
55
branches: [main, master]
66
pull_request:
77
branches: [main, master]
8+
paths:
9+
- 'src/**'
810

911
name: R-CMD-check.yaml
1012

@@ -50,6 +52,36 @@ jobs:
5052
upload-snapshots: true
5153
build_args: 'c("--no-manual","--compact-vignettes=gs+qpdf")'
5254

55+
clang-ASAN:
56+
name: "Minimal clang-ASAN"
57+
runs-on: ubuntu-latest
58+
container: rocker/r-devel-ubsan-clang
59+
env:
60+
_R_CHECK_TESTS_NLINES_: 0
61+
ASAN_OPTIONS: 'detect_leaks=0:halt_on_error=1'
62+
UBSAN_OPTIONS: 'print_stacktrace=1:halt_on_error=1'
63+
CC: "clang -fsanitize=address,undefined -fno-omit-frame-pointer"
64+
CXX: "clang++ -fsanitize=address,undefined -fno-omit-frame-pointer"
65+
CFLAGS: "-g -O3"
66+
CXXFLAGS: "-g -O3"
67+
steps:
68+
- uses: actions/checkout@v4
69+
- name: Set up ASAN
70+
run: echo "LD_PRELOAD=$(clang -print-file-name=libclang_rt.asan-x86_64.so)" >> $GITHUB_ENV
71+
- name: Install dependencies
72+
run: |
73+
apt-get update && apt-get install -y libuv1-dev
74+
mkdir -p ~/.R
75+
echo "CC=$CC" >> ~/.R/Makevars
76+
echo "CXX=$CXX" >> ~/.R/Makevars
77+
echo "CFLAGS=$CFLAGS" >> ~/.R/Makevars
78+
echo "CXXFLAGS=$CXXFLAGS" >> ~/.R/Makevars
79+
Rscript -e 'install.packages("remotes", repos="https://cloud.r-project.org"); remotes::install_deps(dependencies = TRUE, type = "source")'
80+
- name: Build and Check
81+
run: |
82+
R CMD build .
83+
R CMD check bit64_*.tar.gz --as-cran --no-manual --no-vignettes
84+
5385
test-ancient:
5486
runs-on: ubuntu-latest
5587
steps:
@@ -75,16 +107,16 @@ jobs:
75107
for FILE in tests/testthat/test-*.R; do
76108
echo "----------------------------------------------------------------"
77109
echo "Running $FILE"
78-
110+
79111
sed -E "s/(patrick|withr):://g" "$FILE" > "${FILE}_SHIMMED.R"
80112
Rscript -e "library(methods); suppressWarnings(suppressMessages(library(bit64))); source('tests/testthat/helper.R'); source('${FILE}_SHIMMED.R')"
81113
rm "${FILE}_SHIMMED.R"
82-
114+
83115
# Capture failure
84116
if [ $? -ne 0 ]; then
85117
EXIT_CODE=1
86118
fi
87-
119+
88120
done
89121
90122
exit $EXIT_CODE

NEWS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# bit64 4.8.99 (in development)
22

3+
## BUG FIXES
4+
5+
1. Fix some potential segfaults from shellsort algorithms (#315). The culprit code has been faulty for many years, but only newly caught by CRAN's rigorous environment with extensive new test coverage.
6+
37
# bit64 4.8.0 (2025-04-19)
48

59
## NOTICE OF PLANNED BREAKING CHANGES

src/sort64.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,8 @@ void ram_integer64_shellsort_asc(ValueT *data, IndexT l, IndexT r)
383383
IndexT i, j, h, lh, t, n=r-l+1;
384384
if (n < 2) return;
385385
for (t = 0; shellincs[t] > n; t++);
386-
for (h = shellincs[t]; t < SHELLARRAYSIZE; h = shellincs[++t]){
386+
for (; t < SHELLARRAYSIZE; t++){
387+
h = shellincs[t];
387388
lh = l+h;
388389
for (i = lh; i <= r; i++) {
389390
MOVE(v, data[i])
@@ -402,7 +403,8 @@ void ram_integer64_shellsort_desc(ValueT *data, IndexT l, IndexT r)
402403
IndexT i, j, h, lh, t, n=r-l+1;
403404
if (n < 2) return;
404405
for (t = 0; shellincs[t] > n; t++);
405-
for (h = shellincs[t]; t < SHELLARRAYSIZE; h = shellincs[++t]){
406+
for (; t < SHELLARRAYSIZE; t++){
407+
h = shellincs[t];
406408
lh = l+h;
407409
for (i = lh; i <= r; i++) {
408410
MOVE(v, data[i])
@@ -422,7 +424,8 @@ void ram_integer64_shellsortorder_asc(ValueT *data, IndexT *index, IndexT l, Ind
422424
IndexT vi, i, j, h, lh, t, n=r-l+1;
423425
if (n < 2) return;
424426
for (t = 0; shellincs[t] > n; t++);
425-
for (h = shellincs[t]; t < SHELLARRAYSIZE; h = shellincs[++t]){
427+
for (; t < SHELLARRAYSIZE; t++){
428+
h = shellincs[t];
426429
lh = l+h;
427430
for (i = lh; i <= r; i++) {
428431
MOVE(vi, index[i])
@@ -444,7 +447,8 @@ void ram_integer64_shellsortorder_desc(ValueT *data, IndexT *index, IndexT l, In
444447
IndexT vi, i, j, h, lh, t, n=r-l+1;
445448
if (n < 2) return;
446449
for (t = 0; shellincs[t] > n; t++);
447-
for (h = shellincs[t]; t < SHELLARRAYSIZE; h = shellincs[++t]){
450+
for (; t < SHELLARRAYSIZE; t++){
451+
h = shellincs[t];
448452
lh = l+h;
449453
for (i = lh; i <= r; i++) {
450454
MOVE(vi, index[i])
@@ -467,7 +471,8 @@ void ram_integer64_shellorder_asc(ValueT *data, IndexT *index, IndexT l, IndexT
467471
IndexT vi, i, j, h, lh, t, n=r-l+1;
468472
if (n < 2) return;
469473
for (t = 0; shellincs[t] > n; t++);
470-
for (h = shellincs[t]; t < SHELLARRAYSIZE; h = shellincs[++t]){
474+
for (; t < SHELLARRAYSIZE; t++){
475+
h = shellincs[t];
471476
lh = l+h;
472477
for (i = lh; i <= r; i++) {
473478
MOVE(vi, index[i])
@@ -487,7 +492,8 @@ void ram_integer64_shellorder_desc(ValueT *data, IndexT *index, IndexT l, IndexT
487492
IndexT vi, i, j, h, lh, t, n=r-l+1;
488493
if (n < 2) return;
489494
for (t = 0; shellincs[t] > n; t++);
490-
for (h = shellincs[t]; t < SHELLARRAYSIZE; h = shellincs[++t]){
495+
for (; t < SHELLARRAYSIZE; t++){
496+
h = shellincs[t];
491497
lh = l+h;
492498
for (i = lh; i <= r; i++) {
493499
MOVE(vi, index[i])

0 commit comments

Comments
 (0)