Skip to content

Weird Error from the measles R package #164

@gvegayon

Description

@gvegayon

Error

Checking the R package measles (which depends on epiworldR`) threw this error:

=================================================================
  ==4179968==ERROR: AddressSanitizer: container-overflow on address 0x7b28fba811f0 at pc 0x7b08edd735c2 bp 0x7b08ec6c4590 sp 0x7b08ec6c4588
  READ of size 8 at 0x7b28fba811f0 thread T1
  _________________________________________________________________________
  ||    #0 0x7b08edd735c1 in epiworld::Agent<int>::get_entity(unsigned long) const /data/gannet/ripley/R/test-clang/epiworldR/include/epiworld/agent-meat.hpp:890:30
      #1 0x7b08edd87a18 in epiworld::epimodels::ModelMeaslesMixingRiskQuarantine<int>::m_update_infectious_list() /data/gannet/ripley/R/test-clang/epiworldR/include/epiworld/models/measlesmixingriskquarantine.hpp:447:19
      #2 0x7b08edd83217 in epiworld::epimodels::ModelMeaslesMixingRiskQuarantine<int>::reset() /data/gannet/ripley/R/test-clang/epiworldR/include/epiworld/models/measlesmixingriskquarantine.hpp:1398:11
      #3 0x7b08edd1d322 in epiworld::Model<int>::run(unsigned long long, int) /data/gannet/ripley/R/test-clang/epiworldR/include/epiworld/model-meat.hpp:1471:5
      #4 0x7b08edd82afd in epiworld::epimodels::ModelMeaslesMixingRiskQuarantine<int>::run(unsigned long long, int) /data/gannet/ripley/R/test-clang/epiworldR/include/epiworld/models/measlesmixingriskquarantine.hpp:1335:18
      #5 0x7b08f28cdf34 in epiworld::Model<int>::run_multiple(unsigned long long, unsigned long long, int, std::__1::function<void (unsigned long, epiworld::Model<int>*)>, bool, bool, int) (.omp_outlined.136) model.cpp
      #6 0x7f08ff548128 in __kmp_invoke_microtask (/usr/local/clang21/lib/x86_64-unknown-linux-gnu/libomp.so+0xa8128)
      #7 0x7f08ff4c491e  (/usr/local/clang21/lib/x86_64-unknown-linux-gnu/libomp.so+0x2491e)
      #8 0x7f08ff4c357d  (/usr/local/clang21/lib/x86_64-unknown-linux-gnu/libomp.so+0x2357d)
      #9 0x7f08ff527b77  (/usr/local/clang21/lib/x86_64-unknown-linux-gnu/libomp.so+0x87b77)
      #10 0x55fa7aa849f6 in asan_thread_start(void*) /data/gannet/ripley/Sources2/LLVM/21/latest/compiler-rt/lib/asan/asan_interceptors.cpp:239:28
      #11 0x7f08fec7f1d3 in start_thread (/lib64/libc.so.6+0x711d3) (BuildId: a1dda014206b55b07f58fe8db80121b752dc3d03)
      #12 0x7f08fed01ceb in __GI___clone3 (/lib64/libc.so.6+0xf3ceb) (BuildId: a1dda014206b55b07f58fe8db80121b752dc3d03)
  
  0x7b28fba811f0 is located 0 bytes inside of 8-byte region [0x7b28fba811f0,0x7b28fba811f8)
  allocated by thread T1 here:
      #0 0x55fa7aa87114 in malloc /data/gannet/ripley/Sources2/LLVM/21/latest/compiler-rt/lib/asan/asan_malloc_linux.cpp:67:3
      #1 0x7f08fc81f2fb in operator new(unsigned long) (/lib64/libstdc++.so.6+0x1f2fb) (BuildId: a34f3756a2aefc3d2b7ae49335dfdd1b4555be43)
  
  Thread T1 created by T0 here:
      #0 0x55fa7aa6b371 in pthread_create /data/gannet/ripley/Sources2/LLVM/21/latest/compiler-rt/lib/asan/asan_interceptors.cpp:250:3
      #1 0x7f08ff5271e2  (/usr/local/clang21/lib/x86_64-unknown-linux-gnu/libomp.so+0x871e2)
  
  HINT: if you don't care about these errors you may set ASAN_OPTIONS=detect_container_overflow=0.
  If you suspect a false positive see also: https://github.com/google/sanitizers/wiki/AddressSanitizerContainerOverflow.
  SUMMARY: AddressSanitizer: container-overflow /data/gannet/ripley/R/test-clang/epiworldR/include/epiworld/agent-meat.hpp:890:30 in epiworld::Agent<int>::get_entity(unsigned long) const
  Shadow bytes around the buggy address:
    0x7b28fba80f00: fa fa fc fa fa fa fc fa fa fa fc fa fa fa fc fa
    0x7b28fba80f80: fa fa fc fa fa fa fc fa fa fa fc fa fa fa fc fa
    0x7b28fba81000: fa fa fc fa fa fa fc fa fa fa fc fa fa fa fc fa
    0x7b28fba81080: fa fa fc fa fa fa fc fa fa fa fc fa fa fa fc fa
    0x7b28fba81100: fa fa fc fa fa fa fc fa fa fa fc fa fa fa fc fa
  =>0x7b28fba81180: fa fa fc fa fa fa fc fa fa fa fc fa fa fa[fc]fa
    0x7b28fba81200: fa fa fc fa fa fa fc fa fa fa fc fa fa fa fc fa
    0x7b28fba81280: fa fa fc fa fa fa fc fa fa fa fc fa fa fa fc fa
    0x7b28fba81300: fa fa fc fa fa fa fc fa fa fa fc fa fa fa fc fa
    0x7b28fba81380: fa fa fc fa fa fa fc fa fa fa fc fa fa fa fc fa
    0x7b28fba81400: fa fa fc fa fa fa fc fa fa fa fc fa fa fa fc fa
  Shadow byte legend (one shadow byte represents 8 application bytes):
    Addressable:           00
    Partially addressable: 01 02 03 04 05 06 07 
    Heap left redzone:       fa
    Freed heap region:       fd
    Stack left redzone:      f1
    Stack mid redzone:       f2
    Stack right redzone:     f3
    Stack after return:      f5
    Stack use after scope:   f8
    Global redzone:          f9
    Global init order:       f6
    Poisoned by user:        f7
    Container overflow:      fc
    Array cookie:            ac
    Intra object redzone:    bb
    ASan internal:           fe
    Left alloca redzone:     ca
    Right alloca redzone:    cb

With session info:

* using log directory ‘/data/gannet/ripley/R/packages/tests-clang-ASAN/measles.Rcheck’
* using R Under development (unstable) (2026-02-11 r89406)
* using platform: x86_64-pc-linux-gnu
* R was compiled by
    clang version 21.1.8
    flang version 21.1.8
* running under: Fedora Linux 42 (Workstation Edition)
* using session charset: UTF-8
* current time: 2026-02-12 11:08:55 UTC
* using option ‘--no-stop-on-test-error’
* checking for file ‘measles/DESCRIPTION’ ... OK
* checking extension type ... Package
* this is package ‘measles’ version ‘0.1.0’

The measles package

The measles R package wraps the class ModelMeaslesMixingRiskQuarantine, which is available here under inst/include/epiworld/models. It seems that the problem is related to the class entity in the code. For more context, I am dropping a couple of logs from executing R with valgrind, particularly, this code:

library(measles)

# Test just this file: tinytest::run_test_file("inst/tinytest/test-measlesmixingriskquarantine.R")
# Row-stochastic matrix (rowsums 1)
self <- .83
others <- (1 - self) / 2
cmatrix <- c(
  c(self, others, others),
  c(others, self, others),
  c(others, others, self)
) |> as.double() |> matrix(byrow = TRUE, nrow = 3)

N <- 600

r0 <- 15
c_rate <- 20
i_rate <- r0 / c_rate * (1/3)

model_factory <- function(durations, nsims = 100) {

  e1 <- entity("Population 1", 200, FALSE)
  e2 <- entity("Population 2", 200, FALSE)
  e3 <- entity("Population 3", 200, FALSE)

  measles_model <- measles::ModelMeaslesMixingRiskQuarantine(
    n                          = N,
    prevalence                 = 1 / N,
    contact_rate               = c_rate,
    transmission_rate          = i_rate,
    vax_efficacy               = 0.97,
    incubation_period          = 10,
    prodromal_period           = 3,
    rash_period                = 7,
    contact_matrix             = cmatrix,
    hospitalization_rate       = 0.1,
    hospitalization_period     = 10,
    days_undetected            = 2,
    quarantine_period_high     = durations[1],
    quarantine_period_medium   = durations[2],
    quarantine_period_low      = durations[3],
    quarantine_willingness     = 0.9,
    isolation_willingness      = 0.8,
    isolation_period           = 10,
    prop_vaccinated            = 0.3,
    detection_rate_quarantine  = 0.5,
    contact_tracing_success_rate = 0.8,
    contact_tracing_days_prior = 4
  )

  # Adding the entities 
  measles_model |>
    add_entity(e1) |>
    add_entity(e2) |>
    add_entity(e3)

  run_multiple(
    measles_model, ndays = 60, nsims = nsims, seed = 221,
    saver = make_saver("total_hist"),
    nthreads = 2
    )

  res <- run_multiple_get_results(
    measles_model, freader = data.table::fread,
    nthreads = 1
    )$total_hist

  res[
    (date == get_ndays(measles_model)) &
    !(state %in% c("Susceptible", "Quarantined Susceptible"))
    ][, sum(counts), by = "sim_num"]$V1
}

nsims <- 50
ans_base <- model_factory(c(21L, 21L, 21L), nsims = nsims) |> mean()
q("no") 

If you want to look at the measles package, you can find it here. I ran it using one thread and two threads.

log_single_thread.log
log_two_threads.log

Notice that there's a lot of issues from R itself, I think we can ignore those safely.

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions