code: def make_get_thread_stack_message(self, py_db, seq, thread_id, topmost_frame, fmt, must_be_suspended=False, start_frame=0, levels=0):
          
          try:
              # If frame is None, the return is an empty frame list.
              cmd_text = ['<xml><thread id="%s">' % (thread_id,)]
  
              if topmost_frame is not None:
                  frame_id_to_lineno = {}
                  try:
                      # : :type suspended_frames_manager: SuspendedFramesManager
                      suspended_frames_manager = py_db.suspended_frames_manager
                      info = suspended_frames_manager.get_topmost_frame_and_frame_id_to_line(thread_id)
                      if info is None:
                          # Could not find stack of suspended frame...
                          if must_be_suspended:
                              return None
                      else:
                          # Note: we have to use the topmost frame where it was suspended (it may
                          # be different if it was an exception).
                          topmost_frame, frame_id_to_lineno = info
  
                      cmd_text.append(self.make_thread_stack_str(topmost_frame, frame_id_to_lineno))
                  finally:
                      topmost_frame = None
              cmd_text.append('</thread></xml>')
              return NetCommand(CMD_GET_THREAD_STACK, seq, ''.join(cmd_text))
          except:
              return self.make_error_message(seq, get_exception_traceback_str())
docs: Returns thread stack as XML.
  
          :param must_be_suspended: If True and the thread is not suspended, returns None.