]> git.ipfire.org Git - thirdparty/openembedded/openembedded-core-contrib.git/commitdiff
bitbake: parse/ast: ensure saved event handlers really do get restored
authorPaul Eggleton <paul.eggleton@linux.intel.com>
Fri, 24 Aug 2018 04:17:54 +0000 (16:17 +1200)
committerRichard Purdie <richard.purdie@linuxfoundation.org>
Fri, 24 Aug 2018 06:53:14 +0000 (07:53 +0100)
In finalize() we save event handlers, register the ones relevant to the
recipe being finalised, trigger events, and then restore the handlers so
that one recipe's custom handlers (actually implemented within a class
inherited by the recipe) do not affect other recipes. However, if an
exception occurs during parsing, the saved handlers were not being
restored. Use a try...finally block to ensure that the handlers are
always restored.

This issue became apparent since in OpenEmbedded-Core we have recently
introduced a find_intercepts() handler for the
bb.event.RecipePreFinalise event in image-postinst-intercepts.bbclass
that images and old-style SDK recipes will end up inheriting. So far it
doesn't seem that the the error has manifested itself in normal builds,
but when parsing OE-Core recipes in the OE layer index it has:
core-image-rt-* image recipes were parsed which in the default
configuration raise SkipRecipe. The next non-image recipe that is parsed
will trigger a real exception, because the find_intercepts() handler is
still registered and gets fired, but in the context of the new recipe
the POSTINST_INTERCEPTS_PATHS variable is not set, and the code in
find_intercepts() is written with the reasonable assumption that that
isn't possible given that the class itself sets a default, and thus it
fails.

(Bitbake rev: e5f1f8fa201774e0c3c554d59b277baa2128708f)

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
bitbake/lib/bb/parse/ast.py

index 6690dc51c216286647c92e16526c520220bf9b09..9d20c323feea90bd45f9ed40494181be29b6b175 100644 (file)
@@ -343,30 +343,31 @@ def runAnonFuncs(d):
 
 def finalize(fn, d, variant = None):
     saved_handlers = bb.event.get_handlers().copy()
+    try:
+        for var in d.getVar('__BBHANDLERS', False) or []:
+            # try to add the handler
+            handlerfn = d.getVarFlag(var, "filename", False)
+            if not handlerfn:
+                bb.fatal("Undefined event handler function '%s'" % var)
+            handlerln = int(d.getVarFlag(var, "lineno", False))
+            bb.event.register(var, d.getVar(var, False), (d.getVarFlag(var, "eventmask") or "").split(), handlerfn, handlerln)
 
-    for var in d.getVar('__BBHANDLERS', False) or []:
-        # try to add the handler
-        handlerfn = d.getVarFlag(var, "filename", False)
-        if not handlerfn:
-            bb.fatal("Undefined event handler function '%s'" % var)
-        handlerln = int(d.getVarFlag(var, "lineno", False))
-        bb.event.register(var, d.getVar(var, False), (d.getVarFlag(var, "eventmask") or "").split(), handlerfn, handlerln)
-
-    bb.event.fire(bb.event.RecipePreFinalise(fn), d)
+        bb.event.fire(bb.event.RecipePreFinalise(fn), d)
 
-    bb.data.expandKeys(d)
-    runAnonFuncs(d)
+        bb.data.expandKeys(d)
+        runAnonFuncs(d)
 
-    tasklist = d.getVar('__BBTASKS', False) or []
-    bb.event.fire(bb.event.RecipeTaskPreProcess(fn, list(tasklist)), d)
-    bb.build.add_tasks(tasklist, d)
+        tasklist = d.getVar('__BBTASKS', False) or []
+        bb.event.fire(bb.event.RecipeTaskPreProcess(fn, list(tasklist)), d)
+        bb.build.add_tasks(tasklist, d)
 
-    bb.parse.siggen.finalise(fn, d, variant)
+        bb.parse.siggen.finalise(fn, d, variant)
 
-    d.setVar('BBINCLUDED', bb.parse.get_file_depends(d))
+        d.setVar('BBINCLUDED', bb.parse.get_file_depends(d))
 
-    bb.event.fire(bb.event.RecipeParsed(fn), d)
-    bb.event.set_handlers(saved_handlers)
+        bb.event.fire(bb.event.RecipeParsed(fn), d)
+    finally:
+        bb.event.set_handlers(saved_handlers)
 
 def _create_variants(datastores, names, function, onlyfinalise):
     def create_variant(name, orig_d, arg = None):