From 7e15ed7080c45f5283938e86af33fe4794b91b43 Mon Sep 17 00:00:00 2001 From: Sam Thursfield Date: Thu, 18 Feb 2016 14:42:42 +0000 Subject: Avoid stack overflow in cachekeycomputer I managed to trigger a stack overflow in Morph, by having two chunks with the same name and same build instructions in different strata (by mistake, obviously). The error before was this: .... File "/src/morph/morphlib/cachekeycomputer.py", line 77, in get_cache_id cacheid = self._calculate(source) File "/src/morph/morphlib/cachekeycomputer.py", line 86, in _calculate for a in source.dependencies], File "/src/morph/morphlib/cachekeycomputer.py", line 38, in compute_key ret = self._hash_id(self.get_cache_id(source)) File "/src/morph/morphlib/cachekeycomputer.py", line 77, in get_cache_id cacheid = self._calculate(source) File "/src/morph/morphlib/cachekeycomputer.py", line 83, in _calculate 'env': self._filterenv(self._build_env.env), File "/src/morph/morphlib/cachekeycomputer.py", line 32, in _filterenv return dict([(k, env[k]) for k in keys]) RuntimeError: maximum recursion depth exceeded while calling a Python object The error afterwards is this: 2016-02-18 13:53:14 Deciding on task order ERROR: There are multiple versions of component 'cython' Change-Id: I96a41cabe4d9aa81bddc5186c5248a636a0843c2 --- morphlib/sourceresolver.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/morphlib/sourceresolver.py b/morphlib/sourceresolver.py index ce395645..d7c9707a 100644 --- a/morphlib/sourceresolver.py +++ b/morphlib/sourceresolver.py @@ -491,6 +491,18 @@ def create_source_pool(lrc, rrc, repo, ref, filenames, cachedir, def add_to_pool(reponame, ref, filename, absref, tree, morphology, predefined_split_rules): + # If there are duplicate chunks which have the same 'name' and the + # same build instructions, we might cause a stack overflow in + # cachekeycomputer.py when trying to hash the build graph. The + # _find_duplicate_chunks() function doesn't handle this case, it + # is checking for duplicates with the same name but different build + # instructions. + if morphology['kind'] != 'stratum': + if pool.lookup(reponame, ref, filename): + raise morphlib.Error( + "There are multiple versions of component '%s'" % + morphology['name']) + sources = morphlib.source.make_sources( reponame, ref, filename, absref, tree, morphology, predefined_split_rules) -- cgit v1.2.1