~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/commands.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2009-03-10 03:35:20 UTC
  • mfrom: (4084.6.3 integration)
  • Revision ID: pqm@pqm.ubuntu.com-20090310033520-f2ynw0fprjw433m2
(robertc) Refactor profiling exception handling support to clear
        layers up and provide the same support for coverage and
        non-lsprof profiling. (Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
672
672
    tracer = trace.Trace(count=1, trace=0)
673
673
    sys.settrace(tracer.globaltrace)
674
674
 
675
 
    ret = the_callable(*args, **kwargs)
676
 
 
677
 
    sys.settrace(None)
678
 
    results = tracer.results()
679
 
    results.write_results(show_missing=1, summary=False,
680
 
                          coverdir=dirname)
 
675
    try:
 
676
        return exception_to_return_code(the_callable, *args, **kwargs)
 
677
    finally:
 
678
        sys.settrace(None)
 
679
        results = tracer.results()
 
680
        results.write_results(show_missing=1, summary=False,
 
681
                              coverdir=dirname)
681
682
 
682
683
 
683
684
def apply_profiled(the_callable, *args, **kwargs):
688
689
    try:
689
690
        prof = hotshot.Profile(pfname)
690
691
        try:
691
 
            ret = prof.runcall(the_callable, *args, **kwargs) or 0
 
692
            ret = prof.runcall(exception_to_return_code, the_callable, *args,
 
693
                **kwargs) or 0
692
694
        finally:
693
695
            prof.close()
694
696
        stats = hotshot.stats.load(pfname)
703
705
        os.remove(pfname)
704
706
 
705
707
 
 
708
def exception_to_return_code(the_callable, *args, **kwargs):
 
709
    """UI level helper for profiling and coverage.
 
710
 
 
711
    This transforms exceptions into a return value of 3. As such its only
 
712
    relevant to the UI layer, and should never be called where catching
 
713
    exceptions may be desirable.
 
714
    """
 
715
    try:
 
716
        return the_callable(*args, **kwargs)
 
717
    except (KeyboardInterrupt, Exception), e:
 
718
        # used to handle AssertionError and KeyboardInterrupt
 
719
        # specially here, but hopefully they're handled ok by the logger now
 
720
        exc_info = sys.exc_info()
 
721
        exitcode = trace.report_exception(exc_info, sys.stderr)
 
722
        if os.environ.get('BZR_PDB'):
 
723
            print '**** entering debugger'
 
724
            tb = exc_info[2]
 
725
            import pdb
 
726
            if sys.version_info[:2] < (2, 6):
 
727
                # XXX: we want to do
 
728
                #    pdb.post_mortem(tb)
 
729
                # but because pdb.post_mortem gives bad results for tracebacks
 
730
                # from inside generators, we do it manually.
 
731
                # (http://bugs.python.org/issue4150, fixed in Python 2.6)
 
732
 
 
733
                # Setup pdb on the traceback
 
734
                p = pdb.Pdb()
 
735
                p.reset()
 
736
                p.setup(tb.tb_frame, tb)
 
737
                # Point the debugger at the deepest frame of the stack
 
738
                p.curindex = len(p.stack) - 1
 
739
                p.curframe = p.stack[p.curindex][0]
 
740
                # Start the pdb prompt.
 
741
                p.print_stack_entry(p.stack[p.curindex])
 
742
                p.execRcLines()
 
743
                p.cmdloop()
 
744
            else:
 
745
                pdb.post_mortem(tb)
 
746
        return exitcode
 
747
 
 
748
 
706
749
def apply_lsprofiled(filename, the_callable, *args, **kwargs):
707
750
    from bzrlib.lsprof import profile
708
 
    ret, stats = profile(the_callable, *args, **kwargs)
 
751
    ret, stats = profile(exception_to_return_code, the_callable, *args, **kwargs)
709
752
    stats.sort()
710
753
    if filename is None:
711
754
        stats.pprint()
917
960
 
918
961
 
919
962
def run_bzr_catch_errors(argv):
920
 
    # Note: The except clause logic below should be kept in sync with the
921
 
    # profile() routine in lsprof.py.
922
 
    try:
923
 
        return run_bzr(argv)
924
 
    except (KeyboardInterrupt, Exception), e:
925
 
        # used to handle AssertionError and KeyboardInterrupt
926
 
        # specially here, but hopefully they're handled ok by the logger now
927
 
        exc_info = sys.exc_info()
928
 
        exitcode = trace.report_exception(exc_info, sys.stderr)
929
 
        if os.environ.get('BZR_PDB'):
930
 
            print '**** entering debugger'
931
 
            tb = exc_info[2]
932
 
            import pdb
933
 
            if sys.version_info[:2] < (2, 6):
934
 
                # XXX: we want to do
935
 
                #    pdb.post_mortem(tb)
936
 
                # but because pdb.post_mortem gives bad results for tracebacks
937
 
                # from inside generators, we do it manually.
938
 
                # (http://bugs.python.org/issue4150, fixed in Python 2.6)
 
963
    """Run a bzr command with parameters as described by argv.
939
964
 
940
 
                # Setup pdb on the traceback
941
 
                p = pdb.Pdb()
942
 
                p.reset()
943
 
                p.setup(tb.tb_frame, tb)
944
 
                # Point the debugger at the deepest frame of the stack
945
 
                p.curindex = len(p.stack) - 1
946
 
                p.curframe = p.stack[p.curindex][0]
947
 
                # Start the pdb prompt.
948
 
                p.print_stack_entry(p.stack[p.curindex])
949
 
                p.execRcLines()
950
 
                p.cmdloop()
951
 
            else:
952
 
                pdb.post_mortem(tb)
953
 
        return exitcode
 
965
    This function assumed that that UI layer is setup, that symbol deprecations
 
966
    are already applied, and that unicode decoding has already been performed on argv.
 
967
    """
 
968
    return exception_to_return_code(run_bzr, argv)
954
969
 
955
970
 
956
971
def run_bzr_catch_user_errors(argv):