~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/commands.py

  • Committer: Robert Collins
  • Date: 2009-03-08 06:18:06 UTC
  • mto: This revision was merged to the branch mainline in revision 4102.
  • Revision ID: robertc@robertcollins.net-20090308061806-uvu37ccjrrzuspei
Refactor profiling exception handling to restore clear layers - command handling in commands.py, profiling in lsprof.py.

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]
 
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()
915
958
 
916
959
 
917
960
def run_bzr_catch_errors(argv):
918
 
    # Note: The except clause logic below should be kept in sync with the
919
 
    # profile() routine in lsprof.py.
920
 
    try:
921
 
        return run_bzr(argv)
922
 
    except (KeyboardInterrupt, Exception), e:
923
 
        # used to handle AssertionError and KeyboardInterrupt
924
 
        # specially here, but hopefully they're handled ok by the logger now
925
 
        exc_info = sys.exc_info()
926
 
        exitcode = trace.report_exception(exc_info, sys.stderr)
927
 
        if os.environ.get('BZR_PDB'):
928
 
            print '**** entering debugger'
929
 
            tb = exc_info[2]
930
 
            import pdb
931
 
            if sys.version_info[:2] < (2, 6):
932
 
                # XXX: we want to do
933
 
                #    pdb.post_mortem(tb)
934
 
                # but because pdb.post_mortem gives bad results for tracebacks
935
 
                # from inside generators, we do it manually.
936
 
                # (http://bugs.python.org/issue4150, fixed in Python 2.6)
937
 
 
938
 
                # Setup pdb on the traceback
939
 
                p = pdb.Pdb()
940
 
                p.reset()
941
 
                p.setup(tb.tb_frame, tb)
942
 
                # Point the debugger at the deepest frame of the stack
943
 
                p.curindex = len(p.stack) - 1
944
 
                p.curframe = p.stack[p.curindex]
945
 
                # Start the pdb prompt.
946
 
                p.print_stack_entry(p.stack[p.curindex])
947
 
                p.execRcLines()
948
 
                p.cmdloop()
949
 
            else:
950
 
                pdb.post_mortem(tb)
951
 
        return exitcode
 
961
    """Run a bzr command with parameters as described by argv.
 
962
    
 
963
    This function assumed that that UI layer is setup, that symbol deprecations
 
964
    are already applied, and that unicode decoding has already been performed on argv.
 
965
    """
 
966
    return exception_to_return_code(run_bzr, argv)
952
967
 
953
968
 
954
969
def run_bzr_catch_user_errors(argv):