863 if exctb is not None: |
864 if exctb is not None: |
864 self.stop_everywhere = False |
865 self.stop_everywhere = False |
865 |
866 |
866 self.isBroken = True |
867 self.isBroken = True |
867 |
868 |
|
869 disassembly = None |
868 stack = [] |
870 stack = [] |
869 if exctb: |
871 if exctb: |
870 frlist = self.__extract_stack(exctb) |
872 frlist = self.__extract_stack(exctb) |
871 frlist.reverse() |
873 frlist.reverse() |
|
874 disassembly = self.__disassemble(frlist[0][0]) |
872 |
875 |
873 self.currentFrame = frlist[0][0] |
876 self.currentFrame = frlist[0][0] |
874 stack = self.getStack(frlist[self.skipFrames:]) |
877 stack = self.getStack(frlist[self.skipFrames:]) |
875 |
878 |
876 self._dbgClient.lockClient() |
879 self._dbgClient.lockClient() |
877 self._dbgClient.currentThread = self |
880 self._dbgClient.currentThread = self |
878 self._dbgClient.currentThreadExec = self |
881 self._dbgClient.currentThreadExec = self |
879 self._dbgClient.sendException(exctypetxt, excvaltxt, stack) |
882 self._dbgClient.sendException(exctypetxt, excvaltxt, stack) |
|
883 self._dbgClient.setDisassembly(disassembly) |
880 self._dbgClient.dumpThreadList() |
884 self._dbgClient.dumpThreadList() |
881 |
885 |
882 if exctb is not None: |
886 if exctb is not None: |
883 # When polling kept enabled, it isn't possible to resume after an |
887 # When polling kept enabled, it isn't possible to resume after an |
884 # unhandled exception without further user interaction. |
888 # unhandled exception without further user interaction. |
916 stack.append((tb.tb_frame, tb.tb_lineno)) |
920 stack.append((tb.tb_frame, tb.tb_lineno)) |
917 tb = tb.tb_next |
921 tb = tb.tb_next |
918 tb = None |
922 tb = None |
919 return stack |
923 return stack |
920 |
924 |
|
925 def __disassemble(self, frame): |
|
926 """ |
|
927 Private method to generate a disassembly of the given code object. |
|
928 |
|
929 @param frame frame object to be disassembled |
|
930 @type code |
|
931 @return dictionary containing the disassembly information |
|
932 @rtype dict |
|
933 """ |
|
934 disDict = { |
|
935 "lasti": frame.f_lasti, |
|
936 "firstlineno": frame.f_code.co_firstlineno, |
|
937 "instructions": [], |
|
938 } |
|
939 for instr in dis.get_instructions(frame.f_code): |
|
940 instrDict = { |
|
941 "lineno": |
|
942 0 if instr.starts_line is None else instr.starts_line, |
|
943 "isJumpTarget": instr.is_jump_target, |
|
944 "offset": instr.offset, |
|
945 "opname": instr.opname, |
|
946 "arg": instr.arg, |
|
947 "argrepr": instr.argrepr, |
|
948 } |
|
949 disDict["instructions"].append(instrDict) |
|
950 |
|
951 return disDict |
|
952 |
921 def __extractSystemExitMessage(self, excinfo): |
953 def __extractSystemExitMessage(self, excinfo): |
922 """ |
954 """ |
923 Private method to get the SystemExit code and message. |
955 Private method to get the SystemExit code and message. |
924 |
956 |
925 @param excinfo details about the SystemExit exception |
957 @param excinfo details about the SystemExit exception |