summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/bb/utils.py')
-rw-r--r--bitbake/lib/bb/utils.py96
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
248def better_compile(text, file, realfile, mode = "exec"): 250def 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
272def better_exec(code, context, text = None, realfile = "<code>"): 274def _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
329def 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