Skip to content

Crash on CPUs without POPCNT due to unconditional popcount use in ispow2 (asserts forced on in all builds) #399

@mk185147

Description

@mk185147

Summary

Description: The application crashes with an illegal instruction (POPCNT) on older or virtualized x86/x64 CPUs that do not support the POPCNT instruction (CPUID ECX bit 23 = 0).
The failure originates in the debug helper ispow2, which used POPCNT intrinsics inside #ifndef NDEBUG. However, the build system (CMakeLists.txt) explicitly strips -DNDEBUG from Release / MinSizeRel / RelWithDebInfo configurations:

# Do not disable assertions based on CMAKE_BUILD_TYPE.
foreach(_build_type "Release" "MinSizeRel" "RelWithDebInfo")
  foreach(_lang C CXX)
    string(TOUPPER "CMAKE_${_lang}_FLAGS_${_build_type}" _var)
    string(REGEX REPLACE "(^| )[/-]D *NDEBUG($| )" " " ${_var} "${${_var}}")
  endforeach()
endforeach()

As a result, the “debug-only” POPCNT code ran in production builds. On CPUs lacking POPCNT support, execution of the intrinsic caused an immediate crash during assertion checks (e.g. validating ring buffer sizes).

This was already semi-fixed by #325 that allowed compilation without POPCNT, but default is still to use POPCNT.

Impact:

• Release builds can crash at startup or during buffer operations on non-POPCNT hardware.
• Hard to diagnose without symbols; happens before higher-level logic runs.

Expected Behavior:

A power-of-two assertion should not execute unsupported instructions and should work on all x86/x64 CPUs.

Actual Behavior:

Unconditional POPCNT intrinsic leads to illegal instruction fault.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions