{"record":{"id":"df8c064a4e0683a3","repo":"commaai/openpilot","slug":"signal-s-out-of-bounds-start-bit-d-size-d","errorCode":null,"errorMessage":"signal %s out of bounds.start_bit: %d size: %d\n","messagePattern":"signal (.+?) out of bounds\\.start_bit: (.+?) size: (.+?)\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"openpilot/tools/cabana/binaryview.cc","lineNumber":264,"sourceCode":"  int size = is_lb ? std::abs(cur_bit_pos - anchor_bit_pos) + 1 : std::abs(flipBitPos(cur_bit_pos) - flipBitPos(anchor_bit_pos)) + 1;\n  return {start_bit, size, is_lb};\n}\n\n// BinaryViewModel\n\nvoid BinaryViewModel::refresh() {\n  beginResetModel();\n  bit_flip_tracker = {};\n  items.clear();\n  if (auto dbc_msg = dbc()->msg(msg_id)) {\n    row_count = dbc_msg->size;\n    items.resize(row_count * column_count);\n    for (auto sig : dbc_msg->getSignals()) {\n      for (int j = 0; j < sig->size; ++j) {\n        int pos = sig->is_little_endian ? flipBitPos(sig->start_bit + j) : flipBitPos(sig->start_bit) + j;\n        int idx = column_count * (pos / 8) + pos % 8;\n        if (idx >= items.size()) {\n          fprintf(stderr, \"signal %s out of bounds.start_bit: %d size: %d\\n\",\n                  sig->name.c_str(), sig->start_bit, sig->size);\n          break;\n        }\n        if (j == 0) sig->is_little_endian ? items[idx].is_lsb = true : items[idx].is_msb = true;\n        if (j == sig->size - 1) sig->is_little_endian ? items[idx].is_msb = true : items[idx].is_lsb = true;\n\n        auto &sigs = items[idx].sigs;\n        sigs.push_back(sig);\n        if (sigs.size() > 1) {\n          std::sort(sigs.begin(), sigs.end(), [](auto l, auto r) { return l->size > r->size; });\n        }\n      }\n    }\n  } else {\n    row_count = can->lastMessage(msg_id).dat.size();\n    items.resize(row_count * column_count);\n  }\n  endResetModel();","sourceCodeStart":246,"sourceCodeEnd":282,"githubUrl":"https://github.com/commaai/openpilot/blob/516ec1e68203439a73f340f1d0b3b91eabc626ee/openpilot/tools/cabana/binaryview.cc#L246-L282","documentation":"Printed by BinaryViewModel::refresh() in cabana's binary view when a DBC signal, mapped to its bit positions, lands past the end of the message's byte grid — i.e. start_bit + size extends beyond dbc_msg->size bytes. The offending signal's remaining bits are skipped (break) and refresh continues, so it is a diagnostic for an inconsistent DBC rather than a crash.","triggerScenarios":"Loading a DBC where a message's declared length (size) is smaller than its largest signal requires — e.g. message length 8 but a signal starting at bit 55 with size 16. Bit position math: for little-endian, flipBitPos(start_bit + j); for big-endian, flipBitPos(start_bit) + j; if the resulting byte index exceeds size, this fires. Overlapping/late-added signals to a DBC without bumping the message length also trigger it.","commonSituations":"Community DBCs edited by hand where a signal was appended but the message BO_ length was never increased, wrong-endian start_bit values from a dbc conversion tool, or a DBC written for a longer variant of a message applied to a shorter one.","solutions":["Open the DBC and check the flagged signal's start_bit and size against its message's declared byte length; enlarge the BO_ length or fix the signal bounds.","Watch endianness: for Motorola/big-endian signals start_bit is the MSB position — a wrong endianness flag makes computed positions run off the end.","If the DBC came from a converter (canmatrix etc.), re-export with correct start-bit semantics.","Reload the fixed DBC in cabana (--dbc file) and confirm the binary view renders all signals without the stderr line."],"exampleFix":"# before\nBO_ 100 driverControls: 8 driver\n SG_ steerCommand : 55|16@1- ...   # needs bits 55..70 -> beyond 8 bytes\n\n# after\nBO_ 100 driverControls: 10 driver\n SG_ steerCommand : 55|16@1- ...   # message length covers the signal","handlingStrategy":"validation","validationCode":"def signal_fits(signal, msg_size_bytes):\n    # little-endian: highest bit touched = start_bit + size - 1; Motorola: MSB-first via flipBitPos\n    if signal.is_little_endian:\n        return (signal.start_bit + signal.size + 7) // 8 <= msg_size_bytes\n    start_byte = (signal.start_bit // 8)\n    end_bit = (start_byte * 8) + (7 - (signal.start_bit % 8)) + signal.size - 1\n    return (end_bit // 8) + 1 <= msg_size_bytes","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Lint DBCs on load: assert every signal fits within its message's byte length.","When appending signals, bump the BO_ message length to cover the highest bit used.","Verify endianness flags after converting DBCs with canmatrix-style tools."],"tags":["cabana","dbc","can","parsing","openpilot"],"backgroundTag":null,"analyzedSha":"516ec1e68203439a73f340f1d0b3b91eabc626ee","analyzedAt":"2026-08-15T00:17:37.461Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}