Skip to content

Commit 5055763

Browse files
committed
fix(debugger): use 32-bit thread IDs for improved compatibility with some LSP clients
1 parent 4007481 commit 5055763

File tree

3 files changed

+49
-38
lines changed

3 files changed

+49
-38
lines changed

intellij-client/src/main/kotlin/dev/robotcode/robotcode4ij/debugging/RobotCodeDebugProcess.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ class RobotCodeDebugProcess(
9090
}
9191
}
9292

93-
"exception" -> { // TODO session.exceptionCaught()
93+
"exception" -> {
9494
if (!session.breakpointReached(
9595
exceptionBreakpoints.first().breakpoint,
9696
null,

intellij-client/src/main/kotlin/dev/robotcode/robotcode4ij/execution/RobotCodeRunProfileState.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ class RobotCodeRunProfileState(private val config: RobotCodeRunConfiguration, en
103103
*connection.toTypedArray(),
104104
*(if (!debug) arrayOf("--no-debug") else arrayOf()),
105105
*(included.toTypedArray())
106-
), noColor = false ,extraArgs = arrayOf("-v", "--log", "--log-level", "TRACE")
106+
), noColor = false // ,extraArgs = arrayOf("-v", "--log", "--log-level", "TRACE")
107107

108108
)
109109

packages/debugger/src/robotcode/debugger/debugger.py

+47-36
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,11 @@ class StackTraceResult(NamedTuple):
162162

163163

164164
class InvalidThreadIdError(Exception):
165-
def __init__(self, thread_id: Any) -> None:
166-
super().__init__(f"Invalid thread id {thread_id}")
165+
def __init__(self, current_thread_id: Any, expected_thread_id: Any = None) -> None:
166+
super().__init__(
167+
f"Invalid thread id {current_thread_id}"
168+
+ (f", expected {expected_thread_id}" if expected_thread_id is not None else "")
169+
)
167170

168171

169172
class MarkerObject:
@@ -429,44 +432,45 @@ def stop(self) -> None:
429432
with self.condition:
430433
self.state = State.Stopped
431434

432-
if self.main_thread is not None and self.main_thread.ident:
435+
if self.main_thread_is_alive:
433436
self.send_event(
434437
self,
435438
ContinuedEvent(
436439
body=ContinuedEventBody(
437-
thread_id=self.main_thread.ident,
440+
thread_id=self.main_thread_id,
438441
all_threads_continued=True,
439442
)
440443
),
441444
)
442445

443446
self.condition.notify_all()
444447

448+
def check_thread_id(self, thread_id: int) -> None:
449+
if not self.main_thread_is_alive and thread_id != self.main_thread_id:
450+
raise InvalidThreadIdError(thread_id, self.main_thread_id)
451+
445452
def continue_all(self) -> None:
446-
if self.main_thread is not None and self.main_thread.ident is not None:
447-
self.continue_thread(self.main_thread.ident)
453+
if self.main_thread_is_alive:
454+
self.continue_thread(self.main_thread_id)
448455

449456
def continue_thread(self, thread_id: int) -> None:
450-
if self.main_thread is None or thread_id != self.main_thread.ident:
451-
raise InvalidThreadIdError(thread_id)
457+
self.check_thread_id(thread_id)
452458

453459
with self.condition:
454460
self.requested_state = RequestedState.Running
455461
self.condition.notify_all()
456462

457463
def pause_thread(self, thread_id: int) -> None:
458-
# thread_id 0 means all threads
459-
if self.main_thread is None or (thread_id != 0 and thread_id != self.main_thread.ident):
460-
raise InvalidThreadIdError(thread_id)
464+
if thread_id != 0:
465+
self.check_thread_id(thread_id)
461466

462467
with self.condition:
463468
self.requested_state = RequestedState.Pause
464469

465470
self.condition.notify_all()
466471

467472
def next(self, thread_id: int, granularity: Optional[SteppingGranularity] = None) -> None:
468-
if self.main_thread is None or thread_id != self.main_thread.ident:
469-
raise InvalidThreadIdError(thread_id)
473+
self.check_thread_id(thread_id)
470474

471475
with self.condition:
472476
if self.full_stack_frames and self.full_stack_frames[0].type in [
@@ -500,17 +504,15 @@ def step_in(
500504
target_id: Optional[int] = None,
501505
granularity: Optional[SteppingGranularity] = None,
502506
) -> None:
503-
if self.main_thread is None or thread_id != self.main_thread.ident:
504-
raise InvalidThreadIdError(thread_id)
507+
self.check_thread_id(thread_id)
505508

506509
with self.condition:
507510
self.requested_state = RequestedState.StepIn
508511

509512
self.condition.notify_all()
510513

511514
def step_out(self, thread_id: int, granularity: Optional[SteppingGranularity] = None) -> None:
512-
if self.main_thread is None or thread_id != self.main_thread.ident:
513-
raise InvalidThreadIdError(thread_id)
515+
self.check_thread_id(thread_id)
514516

515517
with self.condition:
516518
self.requested_state = RequestedState.StepOut
@@ -589,7 +591,7 @@ def process_start_state(self, source: str, line_no: int, type: str, status: str)
589591
body=StoppedEventBody(
590592
description="Paused",
591593
reason=StoppedReason.PAUSE,
592-
thread_id=threading.current_thread().ident,
594+
thread_id=self.main_thread_id,
593595
)
594596
),
595597
)
@@ -605,7 +607,7 @@ def process_start_state(self, source: str, line_no: int, type: str, status: str)
605607
body=StoppedEventBody(
606608
description="Next step",
607609
reason=StoppedReason.STEP,
608-
thread_id=threading.current_thread().ident,
610+
thread_id=self.main_thread_id,
609611
)
610612
),
611613
)
@@ -620,7 +622,7 @@ def process_start_state(self, source: str, line_no: int, type: str, status: str)
620622
body=StoppedEventBody(
621623
description="Step in",
622624
reason=StoppedReason.STEP,
623-
thread_id=threading.current_thread().ident,
625+
thread_id=self.main_thread_id,
624626
)
625627
),
626628
)
@@ -635,7 +637,7 @@ def process_start_state(self, source: str, line_no: int, type: str, status: str)
635637
body=StoppedEventBody(
636638
description="Step out",
637639
reason=StoppedReason.STEP,
638-
thread_id=threading.current_thread().ident,
640+
thread_id=self.main_thread_id,
639641
)
640642
),
641643
)
@@ -708,7 +710,7 @@ def process_start_state(self, source: str, line_no: int, type: str, status: str)
708710
body=StoppedEventBody(
709711
description="Breakpoint hit",
710712
reason=StoppedReason.BREAKPOINT,
711-
thread_id=threading.current_thread().ident,
713+
thread_id=self.main_thread_id,
712714
hit_breakpoint_ids=[breakpoint_id_manager.get_id(v) for v in breakpoints],
713715
)
714716
),
@@ -747,7 +749,7 @@ def process_end_state(
747749
StoppedEvent(
748750
body=StoppedEventBody(
749751
reason=reason,
750-
thread_id=threading.current_thread().ident,
752+
thread_id=self.main_thread_id,
751753
description=description,
752754
text=text,
753755
)
@@ -782,12 +784,12 @@ def wait_for_running(self) -> None:
782784
if self.requested_state == RequestedState.Running:
783785
self.requested_state = RequestedState.Nothing
784786
self.state = State.Running
785-
if self.main_thread is not None and self.main_thread.ident is not None:
787+
if self.main_thread_is_alive:
786788
self.send_event(
787789
self,
788790
ContinuedEvent(
789791
body=ContinuedEventBody(
790-
thread_id=self.main_thread.ident,
792+
thread_id=self.main_thread_id,
791793
all_threads_continued=True,
792794
)
793795
),
@@ -947,7 +949,7 @@ def start_suite(self, name: str, attributes: Dict[str, Any]) -> None:
947949
StoppedEvent(
948950
body=StoppedEventBody(
949951
reason=StoppedReason.ENTRY,
950-
thread_id=threading.current_thread().ident,
952+
thread_id=self.main_thread_id,
951953
)
952954
),
953955
)
@@ -1221,15 +1223,25 @@ def end_keyword(self, name: str, attributes: Dict[str, Any]) -> None:
12211223
def set_main_thread(self, thread: threading.Thread) -> None:
12221224
self.main_thread = thread
12231225

1224-
def get_threads(self) -> List[Thread]:
1225-
main_thread = self.main_thread or threading.main_thread()
1226+
@property
1227+
def main_thread_id(self) -> int:
1228+
return 1 if self.main_thread_is_alive else 0
12261229

1227-
return [
1228-
Thread(
1229-
id=main_thread.ident if main_thread.ident else 0,
1230-
name=main_thread.name or "",
1231-
)
1232-
]
1230+
@property
1231+
def main_thread_is_alive(self) -> bool:
1232+
return self.main_thread is not None and self.main_thread.is_alive()
1233+
1234+
def get_threads(self) -> List[Thread]:
1235+
return (
1236+
[
1237+
Thread(
1238+
id=self.main_thread_id,
1239+
name="RobotMain",
1240+
)
1241+
]
1242+
if self.main_thread_is_alive
1243+
else []
1244+
)
12331245

12341246
WINDOW_PATH_REGEX: ClassVar = re.compile(r"^(([a-z]:[\\/])|(\\\\)).*$", re.RegexFlag.IGNORECASE)
12351247

@@ -1281,8 +1293,7 @@ def get_stack_trace(
12811293
levels: Optional[int] = None,
12821294
format: Optional[StackFrameFormat] = None,
12831295
) -> StackTraceResult:
1284-
if self.main_thread is None or thread_id != self.main_thread.ident:
1285-
raise InvalidThreadIdError(thread_id)
1296+
self.check_thread_id(thread_id)
12861297

12871298
start_frame = start_frame or 0
12881299
levels = start_frame + (levels or len(self.stack_frames))

0 commit comments

Comments
 (0)