Skip to content

common, phy: DL_NUM_TXMODE and UL_NUM_TXMODE follow the TxMode enum - #4

Open
tabgab wants to merge 1 commit into
inet-framework:devfrom
tabgab:fix/txmode-count
Open

tabgab wants to merge 1 commit into
inet-framework:devfrom
tabgab:fix/txmode-count

Conversation

@tabgab

@tabgab tabgab commented Nov 8, 2026

Copy link
Copy Markdown

This repository has issues disabled, so the problem description is here.

Problem

TxMode (src/simu5g/common/LteCommonEnum.msg) has two modes and a sentinel since the MIMO removal:

SINGLE_ANTENNA_PORT0 = 0; TRANSMIT_DIVERSITY = 1; UNKNOWN_TX_MODE = 2;

but src/simu5g/common/LteCommon.h still says

const unsigned char DL_NUM_TXMODE = 6; //UNKNOWN_TX_MODE;
const unsigned char UL_NUM_TXMODE = 6; //UNKNOWN_TX_MODE;

LteFeedbackComputationRealistic::computeFeedback sizes its per-mode vectors with DL_NUM_TXMODE and stores (TxMode)z for every index. So it writes 3, 4 and 5 into a TxMode. 3 is not an enumerator. 4 and 5 are outside the representable range of the enum (an enum without a fixed underlying type whose largest enumerator is 2 has the range 0..3), so storing and loading them is undefined behaviour. UBSan reports it on every feedback report:

simu5g/stack/phy/feedback/LteFeedback.h:250:19: runtime error: load of value 4, which is not a valid value for type 'const TxMode'
    #0 simu5g::LteFeedback::setTxMode(simu5g::TxMode) LteFeedback.h:250
    #1 simu5g::LteFeedbackComputationRealistic::computeFeedback(...) LteFeedbackComputationRealistic.cc
    #2 simu5g::PhyEnb::requestFeedback(...) PhyEnb.cc:272
    #3 simu5g::PhyEnb::handleFeedbackPkt(...) PhyEnb.cc:312
simu5g/stack/phy/feedback/LteFeedback.h:80:16: runtime error: load of value 4, which is not a valid value for type 'TxMode'
    #0 simu5g::LteFeedback::isEmptyFeedback() const LteFeedback.h:80
    #1 simu5g::LteMacEnb::macHandleFeedbackPkt(omnetpp::cPacket*) LteMacEnb.cc:923

Seen with a -fsanitize=address,undefined debug build (Homebrew clang 22.1.8, macOS arm64, OMNeT++ 6.5.0, INET 4.7.0), running a gNB with six NR UEs for 17.5 s. These two are the only sanitizer reports of that run.

Besides the undefined behaviour, LteAmc (lines 289, 980, 989, 1063, 1071) and D2dAmcHelper (70, 140, 271, 336) allocate and scan one LteSummaryBuffer per counted mode, so every UE carries four history buffers for modes that no longer exist.

Results do not change today: the feedbacks of the stale modes are empty (fb.reset() sets status_ = EMPTY), and LteMacEnb::macHandleFeedbackPkt pushes only non-empty feedbacks to the AMC.

Change

  • LteCommon.h: DL_NUM_TXMODE = UNKNOWN_TX_MODE and UL_NUM_TXMODE = UNKNOWN_TX_MODE, with a comment that the feedback vectors and the AMC histories hold one entry per mode, indexed by TxMode.
  • LteCommonEnum.msg: the note on TxMode now says that the sentinel stays last and the two constants follow it. The old note asked for a manual update of the constants, which is what was missed.
  • LteFeedbackComputationRealistic.cc: the double-vector computeFeedback looped z < DL_NUM_TXMODE - 1 to skip the removed last mode (MULTI_USER). With the count equal to the number of modes, it loops z < DL_NUM_TXMODE.
  • tests/unit/TxModeCount.test (new): both constants equal UNKNOWN_TX_MODE, and both computeFeedback variants return one entry per mode, each with a valid TxMode.

Verification

  • tests/unit/TxModeCount.test: 6 of its 8 checks fail without the change (DL_NUM_TXMODE ... actual=6 expected=2, every stored TxMode is an enumerator, ...). With the change: modelchecks=8 modelfailures=0. The whole unit test set with the change: PASS 36, FAIL 0, ERROR 0, EXPECTEDFAIL 6 (the six expected failures that dev has today).
  • Sanitizer run (the scenario above): two UBSan reports before the change, none after. The same number of events in both runs (#3648283 at 17.5 s).
  • Fingerprint suite (tests/fingerprint/fingerprints, release, simulations.csv and simulations_d2d.csv, 254 rows): the computed fingerprints before and after the change are identical in all 254 rows, and the .UPDATED files are byte-identical. This was run on macOS arm64, where many stored values differ from the Linux CI values anyway (108 failures and 33 errors, the same set in both runs), so CI should confirm on Linux.

The commit is on top of dev (1a3d71b). The macOS measurements above were made on dev plus #1 (the macOS build fix), which this PR does not include.

The MIMO transmission modes were removed and TxMode shrank to
SINGLE_ANTENNA_PORT0, TRANSMIT_DIVERSITY and the UNKNOWN_TX_MODE sentinel,
but the two count constants stayed at 6. LteFeedbackComputationRealistic
sizes its per-mode feedback vectors with DL_NUM_TXMODE and stores
(TxMode)z for every index, so it wrote 3, 4 and 5 into a TxMode. 3 is not an enumerator, and 4 and 5
are outside the enum's representable range, 0..3 (undefined behaviour; UBSan reports the
loads in LteFeedback::setTxMode and LteFeedback::isEmptyFeedback). The AMC
also allocated and scanned feedback history buffers for four modes that
no longer exist.

The constants now take their value from UNKNOWN_TX_MODE, and the loop of
the per-remote feedback computation that excluded the removed last mode
(MULTI_USER) runs over every mode. The empty feedbacks of the stale modes
were never pushed to the AMC, so the fingerprints do not move.

tests/unit/TxModeCount.test checks the constants against the enum and
that every feedback the realistic computation returns carries a valid
TxMode, one entry per mode.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant