diff options
Diffstat (limited to 'bitbake/lib')
| -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 | ||
