diff options
Diffstat (limited to 'bitbake/lib/bb/utils.py')
-rw-r--r-- | bitbake/lib/bb/utils.py | 96 |
1 files changed, 57 insertions, 39 deletions
diff --git a/bitbake/lib/bb/utils.py b/bitbake/lib/bb/utils.py index d671f56b50..9d7a32fb25 100644 --- a/bitbake/lib/bb/utils.py +++ b/bitbake/lib/bb/utils.py | |||
@@ -236,14 +236,16 @@ def _print_trace(body, line): | |||
236 | """ | 236 | """ |
237 | Print the Environment of a Text Body | 237 | Print the Environment of a Text Body |
238 | """ | 238 | """ |
239 | error = [] | ||
239 | # print the environment of the method | 240 | # print the environment of the method |
240 | min_line = max(1, line-4) | 241 | min_line = max(1, line-4) |
241 | max_line = min(line + 4, len(body)) | 242 | max_line = min(line + 4, len(body)) |
242 | for i in xrange(min_line, max_line + 1): | 243 | for i in range(min_line, max_line + 1): |
243 | if line == i: | 244 | if line == i: |
244 | logger.error(' *** %.4d:%s', i, body[i-1]) | 245 | error.append(' *** %.4d:%s' % (i, body[i-1].rstrip())) |
245 | else: | 246 | else: |
246 | logger.error(' %.4d:%s', i, body[i-1]) | 247 | error.append(' %.4d:%s' % (i, body[i-1].rstrip())) |
248 | return error | ||
247 | 249 | ||
248 | def better_compile(text, file, realfile, mode = "exec"): | 250 | def better_compile(text, file, realfile, mode = "exec"): |
249 | """ | 251 | """ |
@@ -260,7 +262,7 @@ def better_compile(text, file, realfile, mode = "exec"): | |||
260 | if e.lineno: | 262 | if e.lineno: |
261 | logger.error("The lines leading to this error were:") | 263 | logger.error("The lines leading to this error were:") |
262 | logger.error("\t%d:%s:'%s'", e.lineno, e.__class__.__name__, body[e.lineno-1]) | 264 | logger.error("\t%d:%s:'%s'", e.lineno, e.__class__.__name__, body[e.lineno-1]) |
263 | _print_trace(body, e.lineno) | 265 | logger.error("\n".join(_print_trace(body, e.lineno))) |
264 | else: | 266 | else: |
265 | logger.error("The function causing this error was:") | 267 | logger.error("The function causing this error was:") |
266 | for line in body: | 268 | for line in body: |
@@ -269,68 +271,84 @@ def better_compile(text, file, realfile, mode = "exec"): | |||
269 | e = bb.BBHandledException(e) | 271 | e = bb.BBHandledException(e) |
270 | raise e | 272 | raise e |
271 | 273 | ||
272 | def better_exec(code, context, text = None, realfile = "<code>"): | 274 | def _print_exception(t, value, tb, realfile, text, context): |
273 | """ | 275 | error = [] |
274 | Similiar to better_compile, better_exec will | ||
275 | print the lines that are responsible for the | ||
276 | error. | ||
277 | """ | ||
278 | import bb.parse | ||
279 | if not text: | ||
280 | text = code | ||
281 | if not hasattr(code, "co_filename"): | ||
282 | code = better_compile(code, realfile, realfile) | ||
283 | try: | 276 | try: |
284 | exec(code, _context, context) | ||
285 | except Exception as e: | ||
286 | (t, value, tb) = sys.exc_info() | ||
287 | |||
288 | if t in [bb.parse.SkipPackage, bb.build.FuncFailed]: | ||
289 | raise | ||
290 | |||
291 | import traceback | 277 | import traceback |
292 | exception = traceback.format_exception_only(t, value) | 278 | exception = traceback.format_exception_only(t, value) |
293 | logger.error('Error executing a python function in %s:\n%s', | 279 | error.append('Error executing a python function in %s:\n' % realfile) |
294 | realfile, ''.join(exception)) | ||
295 | 280 | ||
296 | # Strip 'us' from the stack (better_exec call) | 281 | # Strip 'us' from the stack (better_exec call) |
297 | tb = tb.tb_next | 282 | tb = tb.tb_next |
298 | 283 | ||
299 | textarray = text.split('\n') | 284 | textarray = text.split('\n') |
300 | linefailed = traceback.tb_lineno(tb) | ||
301 | 285 | ||
302 | tbextract = traceback.extract_tb(tb) | 286 | linefailed = tb.tb_lineno |
303 | tbformat = "\n".join(traceback.format_list(tbextract)) | ||
304 | logger.error("The stack trace of python calls that resulted in this exception/failure was:") | ||
305 | for line in tbformat.split('\n'): | ||
306 | logger.error(line) | ||
307 | 287 | ||
308 | logger.error("The code that was being executed was:") | 288 | tbextract = traceback.extract_tb(tb) |
309 | _print_trace(textarray, linefailed) | 289 | tbformat = traceback.format_list(tbextract) |
310 | logger.error("[From file: '%s', lineno: %s, function: %s]", tbextract[0][0], tbextract[0][1], tbextract[0][2]) | 290 | error.append("The stack trace of python calls that resulted in this exception/failure was:") |
291 | error.append("File: '%s', lineno: %s, function: %s" % (tbextract[0][0], tbextract[0][1], tbextract[0][2])) | ||
292 | error.extend(_print_trace(textarray, linefailed)) | ||
311 | 293 | ||
312 | # See if this is a function we constructed and has calls back into other functions in | 294 | # See if this is a function we constructed and has calls back into other functions in |
313 | # "text". If so, try and improve the context of the error by diving down the trace | 295 | # "text". If so, try and improve the context of the error by diving down the trace |
314 | level = 0 | 296 | level = 0 |
315 | nexttb = tb.tb_next | 297 | nexttb = tb.tb_next |
316 | while nexttb is not None and (level+1) < len(tbextract): | 298 | while nexttb is not None and (level+1) < len(tbextract): |
299 | error.append("File: '%s', lineno: %s, function: %s" % (tbextract[level+1][0], tbextract[level+1][1], tbextract[level+1][2])) | ||
317 | if tbextract[level][0] == tbextract[level+1][0] and tbextract[level+1][2] == tbextract[level][0]: | 300 | if tbextract[level][0] == tbextract[level+1][0] and tbextract[level+1][2] == tbextract[level][0]: |
318 | _print_trace(textarray, tbextract[level+1][1]) | 301 | # The code was possibly in the string we compiled ourselves |
319 | logger.error("[From file: '%s', lineno: %s, function: %s]", tbextract[level+1][0], tbextract[level+1][1], tbextract[level+1][2]) | 302 | error.extend(_print_trace(textarray, tbextract[level+1][1])) |
303 | elif tbextract[level+1][0].startswith("/"): | ||
304 | # The code looks like it might be in a file, try and load it | ||
305 | try: | ||
306 | with open(tbextract[level+1][0], "r") as f: | ||
307 | text = f.readlines() | ||
308 | error.extend(_print_trace(text, tbextract[level+1][1])) | ||
309 | except: | ||
310 | error.append(tbformat[level+1]) | ||
320 | elif "d" in context and tbextract[level+1][2]: | 311 | elif "d" in context and tbextract[level+1][2]: |
312 | # Try and find the code in the datastore based on the functionname | ||
321 | d = context["d"] | 313 | d = context["d"] |
322 | functionname = tbextract[level+1][2] | 314 | functionname = tbextract[level+1][2] |
323 | text = d.getVar(functionname, True) | 315 | text = d.getVar(functionname, True) |
324 | if text: | 316 | if text: |
325 | _print_trace(text.split('\n'), tbextract[level+1][1]) | 317 | error.extend(_print_trace(text.split('\n'), tbextract[level+1][1])) |
326 | logger.error("[From file: '%s', lineno: %s, function: %s]", tbextract[level+1][0], tbextract[level+1][1], tbextract[level+1][2]) | ||
327 | else: | 318 | else: |
328 | break | 319 | error.append(tbformat[level+1]) |
329 | else: | 320 | else: |
330 | break | 321 | error.append(tbformat[level+1]) |
331 | nexttb = tb.tb_next | 322 | nexttb = tb.tb_next |
332 | level = level + 1 | 323 | level = level + 1 |
333 | 324 | ||
325 | error.append("Exception: %s" % ''.join(exception)) | ||
326 | finally: | ||
327 | logger.error("\n".join(error)) | ||
328 | |||
329 | def better_exec(code, context, text = None, realfile = "<code>"): | ||
330 | """ | ||
331 | Similiar to better_compile, better_exec will | ||
332 | print the lines that are responsible for the | ||
333 | error. | ||
334 | """ | ||
335 | import bb.parse | ||
336 | if not text: | ||
337 | text = code | ||
338 | if not hasattr(code, "co_filename"): | ||
339 | code = better_compile(code, realfile, realfile) | ||
340 | try: | ||
341 | exec(code, _context, context) | ||
342 | except Exception as e: | ||
343 | (t, value, tb) = sys.exc_info() | ||
344 | |||
345 | if t in [bb.parse.SkipPackage, bb.build.FuncFailed]: | ||
346 | raise | ||
347 | try: | ||
348 | _print_exception(t, value, tb, realfile, text, context) | ||
349 | except Exception as e: | ||
350 | logger.error("Exception handler error: %s" % str(e)) | ||
351 | |||
334 | e = bb.BBHandledException(e) | 352 | e = bb.BBHandledException(e) |
335 | raise e | 353 | raise e |
336 | 354 | ||