From 7bf83a5d7be036969807c0f44ff75d211e039a02 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 19 Oct 2021 21:43:24 -0600 Subject: buildman: Detect Kconfig loops Hex and int Kconfig options are supposed to have defaults. This is so we can configure U-Boot without having to enter particular values for the items that don't have specific values in the board's defconfig file. If this rule is not followed, then introducing a new Kconfig can produce a loop like this: Break things (BREAK_ME) [] (NEW) Error in reading or end of file. Break things (BREAK_ME) [] (NEW) Error in reading or end of file. The continues forever since buildman passes /dev/null to 'conf', and the build system just tries again. Eventually there is so much output that buildman runs out of memory. We can detect this situation by looking for a symbol (like 'BREAK_ME') which has no default (the '[]' above) and is marked as new. If this appears multiple times in the output, we know something is wrong. Add a filter function for the output which detects this situation. Allow it to return True to terminate the process. Implement this termination in cros_subprocess. With this we get a nice message: buildman --board sandbox -T0 Building current source for 1 boards (0 threads, 32 jobs per thread) sandbox: w+ sandbox +.config:66:warning: symbol value '' invalid for BREAK_ME + +Error in reading or end of file. +make[3]: *** [scripts/kconfig/Makefile:75: syncconfig] Terminated +make[2]: *** [Makefile:569: syncconfig] Terminated +make: *** [Makefile:177: sub-make] Terminated +(** did you define an int/hex Kconfig with no default? **) Signed-off-by: Simon Glass --- tools/patman/command.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'tools/patman/command.py') diff --git a/tools/patman/command.py b/tools/patman/command.py index bf8ea6c8c3c..d54b1e0efce 100644 --- a/tools/patman/command.py +++ b/tools/patman/command.py @@ -49,7 +49,8 @@ test_result = None def RunPipe(pipe_list, infile=None, outfile=None, capture=False, capture_stderr=False, oneline=False, - raise_on_error=True, cwd=None, binary=False, **kwargs): + raise_on_error=True, cwd=None, binary=False, + output_func=None, **kwargs): """ Perform a command pipeline, with optional input/output filenames. @@ -63,6 +64,8 @@ def RunPipe(pipe_list, infile=None, outfile=None, capture: True to capture output capture_stderr: True to capture stderr oneline: True to strip newline chars from output + output_func: Output function to call with each output fragment + (if it returns True the function terminates) kwargs: Additional keyword arguments to cros_subprocess.Popen() Returns: CommandResult object @@ -105,7 +108,7 @@ def RunPipe(pipe_list, infile=None, outfile=None, if capture: result.stdout, result.stderr, result.combined = ( - last_pipe.CommunicateFilter(None)) + last_pipe.CommunicateFilter(output_func)) if result.stdout and oneline: result.output = result.stdout.rstrip(b'\r\n') result.return_code = last_pipe.wait() -- cgit v1.2.3