bitbake: cooker: Avoid parser deadlocks

If you make parsing fail (e.g. add something like:

X := "${@d.getVar('MCMACHINES').split()[1]}"

to meson.bbclass, then run "while true; do bitbake -g bash; done"
it will eventually hang. It appears the cancel_join_thread() call the
parsing failure triggers, breaks the results_queue badly enough that it
sits in read() indefintely (called from self.result_queue.get(timeout=0.25)).
The timeout only applies to lock aquisition, not the read call.

I've tried various other approaches such as using cancel_join_thread()
in other places but the only way things don't lock up is to avoid
cancel_join_thread() entirely for results_queue.

I do have a concern that this may adversely affect Ctrl+C handling
but equally, its broken now already and this appears to improve
things.

[YOCTO #14034]

(Bitbake rev: 9c61a1cc7be46c23da1f4ef3bee070fb83c4be57)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Richard Purdie
2020-09-02 23:14:04 +01:00
parent f19f252e2b
commit 1ba387a12c

View File

@@ -1993,7 +1993,8 @@ class Parser(multiprocessing.Process):
except queue.Empty:
pass
else:
self.results.cancel_join_thread()
self.results.close()
self.results.join_thread()
break
if pending:
@@ -2002,6 +2003,8 @@ class Parser(multiprocessing.Process):
try:
job = self.jobs.pop()
except IndexError:
self.results.close()
self.results.join_thread()
break
result = self.parse(*job)
# Clear the siggen cache after parsing to control memory usage, its huge
@@ -2121,8 +2124,6 @@ class CookerParser(object):
bb.event.fire(event, self.cfgdata)
# Allow data left in the cancel queue to be discarded
self.parser_quit.cancel_join_thread()
for process in self.processes:
self.parser_quit.put(None)
@@ -2142,7 +2143,8 @@ class CookerParser(object):
process.join()
self.parser_quit.close()
self.parser_quit.join_thread()
# Allow data left in the cancel queue to be discarded
self.parser_quit.cancel_join_thread()
def sync_caches():
for c in self.bb_caches.values():