[bitbake-devel] Broken COW? Any python gurus who fancy an odd problem to debug?

Richard Purdie richard.purdie at linuxfoundation.org
Sun Jan 25 21:50:22 UTC 2015


Whilst playing with the datastore I noticed something very odd, a
supposedly empty datastore had shadows of "things" in it. The selftests
are a great way to show this. To demo, apply the patch below, then run:

BB_SKIP_NETTESTS=yes bitbake-selftest

and you will see the output:

here 0 <COWDict Level: 1 Current Keys: 11> libinstall__mutable__ __module__ UTMPDIR__mutable__ foo__mutable__ __count__ BASE_NAME__mutable__ LOGDIR__mutable__ NAME__mutable__ MAILFILE__mutable__ of_foo__mutable__ MAILDIR__mutable__ something__mutable__ __hasmutable__ __doc__

The odd part is this is an empty data store so where did libinstall,
UTMPDIR, BASE_NAME, LOGDIR and so on come from? The answer is other data
stores :(.

in data.py, if you change init() to be:

- return _dict_type()
+ return _dict_type(special = COWDictBase.copy(), seen = COWDictBase.copy())

then it "works". Why? I've no idea but I'd love to understand it.

Cheers,

Richard

diff --git a/bitbake/lib/bb/COW.py b/bitbake/lib/bb/COW.py
index 6917ec3..29ecbc2 100644
--- a/bitbake/lib/bb/COW.py
+++ b/bitbake/lib/bb/COW.py
@@ -50,7 +50,11 @@ class COWDictMeta(COWMeta):
 
     def __str__(cls):
         # FIXME: I have magic numbers!
-        return "<COWDict Level: %i Current Keys: %i>" % (cls.__count__, len(cls.__dict__) - 3)
+        r = ""
+        for k in cls.__dict__:
+            r = r + " " + str(k)
+
+        return "<COWDict Level: %i Current Keys: %i>" % (cls.__count__, len(cls.__dict__) - 3) + r
     __repr__ = __str__
 
     def cow(cls):
diff --git a/bitbake/lib/bb/tests/data.py b/bitbake/lib/bb/tests/data.py
index 81e4091..1c8c1f9 100644
--- a/bitbake/lib/bb/tests/data.py
+++ b/bitbake/lib/bb/tests/data.py
@@ -294,6 +294,11 @@ class TestOverrides(unittest.TestCase):
         bb.data.update_data(self.d)
         self.assertEqual(self.d.getVar("TEST", True), "testvalue3")
 
+class TestCOW(unittest.TestCase):
+    def test_cow(self):
+        self.d = bb.data.init()
+        self.d.setVar("OVERRIDES", "foo:bar:local")
+        print("here 0 %s" % str(self.d._seen_overrides))
 
 class TestFlags(unittest.TestCase):
     def setUp(self):





More information about the bitbake-devel mailing list