Skip to content

Bug: TransactionLog BEGIN/END bitfields race between same-priority threads causes SIGABRT #797

Description

@tfa2si

Description

Severity

Critical — deterministic SIGABRT crash in real-time workloads (SCHED_FIFO >= 40)

Summary

S-CORE LoLa's TransactionLog::ReferenceTransactionBegin() asserts on BEGIN bit being TRUE when two threads at the same RT priority (e.g., RT thread + LoLa executor thread) concurrently access the same event slot via GetNewSamples(). The TransactionLogSlot uses non-atomic bitfields (uint8_t transaction_begin_ : 1; uint8_t transaction_end_ : 2;) with no synchronization, violating its own single-threaded assumption when Subscribe() spawns executor threads.

Root Cause

1. Non-atomic TransactionLogSlot

// transaction_log_slot.h
class TransactionLogSlot {
    std::uint8_t transaction_begin_ : 1;  // ← NOT atomic
    std::uint8_t transaction_end_ : 2;    // ← NOT atomic
};  

2. Unprotected BEGIN/END manipulation
`// transaction_log.cpp:117-122
void TransactionLog::ReferenceTransactionBegin(SlotIndexType slot_index) noexcept {
    TransactionLogSlot& slot = reference_count_slots_.at(slot_index);
    SCORE_LANGUAGE_FUTURECPP_PRECONDITION(!slot.GetTransactionBegin());  // ← ASSERTION
    WaitForTransactionEndToBecomeFalse(slot);
    slot.SetTransactionBegin(true);  // ← Plain write, no CAS
}`

3. Executor thread shares same TransactionLog
Subscribe() creates a LoLa executor/notification thread (see messaging/message_passing_service_instance.cpp:925-931). User code elevates this thread to SCHED_FIFO 80 via elevate_new_threads(). Both threads now access the same TransactionLog (allocated in SHM via ManagedMemoryResource).

4. Race condition at same priority
Executor Thread (SCHED_FIFO 80):     RT Thread (SCHED_FIFO 80):
ReferenceTransactionBegin(slot X)    [preempts — same priority, time-slices]
  → BEGIN=true                        ReferenceTransactionBegin(slot X)
                                      → PRECONDITION(!BEGIN) → FAIL → abort

**At same SCHED_FIFO priority, threads time-slice. Either thread can preempt the other mid-transaction, leaving BEGIN stuck TRUE.**
Why Existing Tests Miss This
S-CORE test suite runs at SCHED_OTHER — fair scheduling avoids preemption within transactions
S-CORE examples (e.g., sample_sender_receiver.cpp) use SCHED_OTHER
slot_collector.h warns "not thread-safe" but the TransactionLog has no such warning
AoU comment says "event sender has to be single-threaded/non-concurrent" — but consumer side (executor + user thread) is also multi-threaded
Reproduction
HFC Configuration: rt_priority: 80, rt_policy: SCHED_FIFO (mix config)

Subscribe() to any LoLa event
elevate_new_threads(priority=80, policy=SCHED_FIFO) — promotes executor thread
RT thread polls GetNewSamples() every 1-2ms
Executor thread also calls GetNewSamples() on event notifications (even without SetReceiveHandler, executor exists and can fire callbacks)
Both touch same TransactionLog → PRECONDITION fires → SIGABRT at ~cycle 300-500
Note: Crash also occurs with pure single-thread polling if elevate_new_threads() promotes the executor thread, even when user never calls SetReceiveHandler().

Workaround
Use SetReceiveHandler pattern — moves GetNewSamples() to a single executor thread. RT thread reads plain shared structs with zero S-CORE calls.

Affected Files
score/mw/com/impl/bindings/lola/transaction_log_slot.h — non-atomic bitfields
score/mw/com/impl/bindings/lola/transaction_log.cpp — PRECONDITION assertions, sleep_for()
score/mw/com/impl/bindings/lola/slot_collector.h — thread-safety warning (mentions slot_collector but not TransactionLog)


Additional Notes
sleep_for(10ms) in WaitForTransactionEndToBecomeFalse() is anti-pattern for RT systems
Design doc claims "wait-free algorithms" but TransactionLog path blocks
Crash is deterministic with SCHED_FIFO ≥ 40, timing-dependent (~300-500 cycles)

### Error Occurrence  Rate

None

### How to reproduce

_No response_

### Supporting Information

_No response_

### Classification

minor

### Affected Version

v0.3.0

### Category

- [ ] Safety Related
- [ ] Security Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    Status
    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions