CNA-BUG-090: GraphicsDeviceInformation accepts a null Adapter, and GraphicsDeviceManager then binds a reference through that null pointer
Evidence basis: source-verified at the pinned commit; tests exist (not executed for this page). Claims on this page were checked by reading the CNA source at commit 009d40f5; unless a sentence says otherwise, nothing here was built or executed. Nothing on this page was executed unless the Evidence section says so.
XNA's documentation says the GraphicsDeviceInformation.Adapter setter throws ArgumentNullException for a null value (the shipped IL only tests the stored adapter, so the first null slips through in real XNA). CNA's setter stores any pointer, and applyToExistingRenderer then passes *gdi.getAdapterProperty() to GraphicsDevice::Reset, which is undefined behaviour for a null adapter; in practice the device keeps its previous adapter.
- Identifier
CNA-BUG-090- Category
- Bug
- Subsystem
- Core & runtime
- Status
- Open
- Verified against
- CNA
009d40f5(009d40f5dd085c4e674d3479675fac84b12b3e0a) - Severity
- Low (a triage suggestion, not a project priority)
- Evidence basis
- Source-verified: read at TARGET, not executed
- Tests touching this area
- Yes: see Current tests
- Affected contract
- Microsoft::Xna::Framework::GraphicsDeviceInformation::setAdapterProperty; PreparingDeviceSettings handlers
Expected behaviour
The XNA 4.0 documentation for GraphicsDeviceInformation.Adapter lists ArgumentNullException ("Adapter is null. Try using DefaultAdapter instead."), so a PreparingDeviceSettings handler is told not to produce a device information without an adapter. (The IL of set_Adapter tests the stored field rather than the incoming value, so real XNA 4.0 lets the first null through and fails later; the documented contract is the exception.) Independently of XNA, CNA's own code must not form a reference through a null pointer.
Actual behaviour at TARGET
GraphicsDeviceInformation.cpp stores any pointer in setAdapterProperty. ApplyChanges and CreateDevice in GraphicsDeviceManager.cpp already guard the adapter with a null check when they name the device, but applyToExistingRenderer then calls graphicsDevice_->Reset(pp, *gdi.getAdapterProperty()), forming a reference from a null pointer, which is undefined behaviour. With current compilers the address simply reaches the pointer overload of GraphicsDevice::Reset, which treats null as "keep the current adapter", so the handler's mistake is silently ignored rather than reported.
Source locations
modules/runtime/src/GraphicsDeviceInformation.cpp— GraphicsDeviceInformation::setAdapterPropertymodules/runtime/src/GraphicsDeviceManager.cpp— applyToExistingRenderer (Reset(pp, *adapter))modules/graphics/src/Xna/GraphicsDevice.cpp— GraphicsDevice::Reset(const PresentationParameters&, GraphicsAdapter*) null-adapter branch
Evidence
Checked by reading the named sources at 009d40f5; nothing was built or executed for this entry. The practical outcome depends on the compiler not exploiting the undefined behaviour.
Independent re-verification: Checked by reading the named sources at 009d40f5 and disassembling XNA 4.0's GraphicsDeviceInformation.set_Adapter, which loads the adapter field instead of the argument; the earlier statement that the IL rejects a null value is withdrawn, while the XNA documentation still lists the exception. Not executed; the practical outcome depends on the compiler not exploiting the undefined behaviour.
Focused reproduction
No focused reproduction is known. Nothing has been invented here; the evidence above is what exists.
Current tests
GraphicsDeviceInformationTests.cpp does not set a null adapter.
Regression test
A test that sets Adapter = nullptr and expects ArgumentNullException from the setter.
Blast radius
Only PreparingDeviceSettings handlers that clear the adapter.
Workaround
Never assign a null adapter.
Related pages
The same subject is explained at several altitudes. These are the neighbouring pages at each one.
- Internals
- Runtime module: objects
- Known issues
- Bug index