tornewuff / pycorn

An interpreted operating system written in Python.
GNU General Public License v3.0
65 stars 13 forks source link

Field._cachedvalue not initialised leading to errors when reading registers e.g. main_id #5

Open Bouteillebleu opened 11 years ago

Bouteillebleu commented 11 years ago

Reproduction steps:

  1. makepp seeds/pycorn/pycorn.uimage (to build the Pycorn image)
  2. makepp seeds/pycorn/run (to launch it in qemu)
  3. Type the following into the interpreter:

from metal import cpu cpu.SystemControlCoprocessor.main_id.implementor

You get the following error: Traceback (most recent call last): File "", line 1, in File "/initrd/metal/bits.py", line 65, in get File "/initrd/metal/bits.py", line 46, in extract TypeError: unsupported operand type(s) for &: 'NoneType' and 'long'

From looking into this, this is because:

So if I'd set the values of a field first I'd expect this to be okay.

But in a read-only register like main_id, it doesn't make sense to do that - and yet nowhere in setting up the register does self._cachedvalue gets set, so any attempt at get on any of main_id's fields will cause a TypeError.

tornewuff commented 11 years ago

Yeah, you can't access the fields of a register outside of a "with" block, because of the read-modify-write requirements. It shouldn't just crash, obviously :)

For read-only registers it may be okay to support directly reading, but there's still a potential problem for registers that are read-only to the CPU but not constant - allowing them to be read outside of a with block means you can inadvertently read an inconsistent snapshot of two fields that should be read atomically.