Skip to content

Commit 07d5e8a

Browse files
committed
Fix exception breakpoints not carrying over into new debuggers (close #10)
1 parent 3e3710c commit 07d5e8a

File tree

5 files changed

+33
-22
lines changed

5 files changed

+33
-22
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
1313
### Fixed
1414

1515
- Fixed a crash when closing the Splicing Table with Hexical 1.5.0 installed ([#62](https://github.com/object-Object/HexDebug/issues/62)).
16+
- Fixed exceptions not being caught by exception breakpoints after the first hex in a debug session.
1617

1718
## `0.7.0+1.20.1` - 2025-10-02
1819

Common/src/main/kotlin/gay/object/hexdebug/adapter/DebugAdapter.kt

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ import java.util.concurrent.CompletionException
3939
class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
4040
private var state: DebugAdapterState = NotDebugging()
4141

42+
private val exceptionBreakpoints = mutableSetOf<ExceptionBreakpointType>()
43+
4244
private val debuggers get() = (state as? Debugging)?.debuggers
4345

4446
val launcher: IHexDebugLauncher by lazy {
@@ -85,12 +87,12 @@ class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
8587
val debugger = when (val state = state) {
8688
is Debugging -> {
8789
state.restartArgs[threadId] = args
88-
HexDebugger(threadId, state.initArgs, state.launchArgs, args).also {
90+
HexDebugger(threadId, exceptionBreakpoints, state.initArgs, state.launchArgs, args).also {
8991
state.debuggers[threadId] = it
9092
}
9193
}
9294
is NotDebugging -> {
93-
val newState = Debugging(state, args, threadId)
95+
val newState = Debugging(threadId, exceptionBreakpoints, state, args)
9496
this.state = newState
9597
newState.debuggers[threadId]!!
9698
}
@@ -293,14 +295,21 @@ class DebugAdapter(val player: ServerPlayer) : IDebugProtocolServer {
293295
}
294296

295297
override fun setExceptionBreakpoints(args: SetExceptionBreakpointsArguments): CompletableFuture<SetExceptionBreakpointsResponse> {
296-
return SetExceptionBreakpointsResponse().apply {
297-
// FIXME: we need to save this somewhere and pass it to the debuggers on creation
298-
debuggers?.values?.forEach {
299-
it.setExceptionBreakpoints(args.filters)
300-
}
301-
breakpoints = Array(args.filters.size) {
302-
Breakpoint().apply { isVerified = true }
298+
exceptionBreakpoints.clear()
299+
val responseBreakpoints = mutableListOf<Breakpoint>()
300+
301+
for (name in args.filters) {
302+
val verified = try {
303+
exceptionBreakpoints.add(ExceptionBreakpointType.valueOf(name))
304+
true
305+
} catch (_: IllegalArgumentException) {
306+
false
303307
}
308+
responseBreakpoints.add(Breakpoint().apply { isVerified = verified })
309+
}
310+
311+
return SetExceptionBreakpointsResponse().apply {
312+
breakpoints = responseBreakpoints.toTypedArray()
304313
}.toFuture()
305314
}
306315

Common/src/main/kotlin/gay/object/hexdebug/adapter/DebugAdapterState.kt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package gay.`object`.hexdebug.adapter
22

33
import gay.`object`.hexdebug.debugger.CastArgs
4+
import gay.`object`.hexdebug.debugger.ExceptionBreakpointType
45
import gay.`object`.hexdebug.debugger.HexDebugger
56
import org.eclipse.lsp4j.debug.InitializeRequestArguments
67

@@ -26,12 +27,17 @@ sealed interface DebugAdapterState {
2627
override val restartArgs: MutableMap<Int, CastArgs>,
2728
val debuggers: MutableMap<Int, HexDebugger>,
2829
) : DebugAdapterState {
29-
constructor(state: DebugAdapterState, castArgs: CastArgs, threadId: Int = 0) : this(
30+
constructor(
31+
threadId: Int,
32+
exceptionBreakpoints: Set<ExceptionBreakpointType>,
33+
state: DebugAdapterState,
34+
castArgs: CastArgs,
35+
) : this(
3036
state.isConnected,
3137
state.initArgs,
3238
state.launchArgs,
3339
mutableMapOf(threadId to castArgs),
34-
mutableMapOf(threadId to HexDebugger(threadId, state.initArgs, state.launchArgs, castArgs)),
40+
mutableMapOf(threadId to HexDebugger(threadId, exceptionBreakpoints, state.initArgs, state.launchArgs, castArgs)),
3541
)
3642
}
3743
}

Common/src/main/kotlin/gay/object/hexdebug/debugger/CastArgs.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ data class CastArgs(
88
val iotas: List<Iota>,
99
val env: CastingEnvironment,
1010
val world: ServerLevel,
11-
val onExecute: ((Iota) -> Unit)? = null
12-
)
11+
val onExecute: ((Iota) -> Unit)? = null,
12+
13+
)

Common/src/main/kotlin/gay/object/hexdebug/debugger/HexDebugger.kt

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import org.eclipse.lsp4j.debug.LoadedSourceEventArgumentsReason as LoadedSourceR
3232

3333
class HexDebugger(
3434
threadId: Int,
35+
private val exceptionBreakpoints: Set<ExceptionBreakpointType>,
3536
var initArgs: InitializeRequestArguments,
3637
var launchArgs: LaunchArgs,
3738
private val defaultEnv: CastingEnvironment,
@@ -42,11 +43,12 @@ class HexDebugger(
4243
) {
4344
constructor(
4445
threadId: Int,
46+
exceptionBreakpoints: Set<ExceptionBreakpointType>,
4547
initArgs: InitializeRequestArguments,
4648
launchArgs: LaunchArgs,
4749
castArgs: CastArgs,
4850
image: CastingImage = CastingImage(),
49-
) : this(threadId, initArgs, launchArgs, castArgs.env, castArgs.world, castArgs.onExecute, castArgs.iotas, image)
51+
) : this(threadId, exceptionBreakpoints, initArgs, launchArgs, castArgs.env, castArgs.world, castArgs.onExecute, castArgs.iotas, image)
5052

5153
var lastEvaluatedMetadata: IotaMetadata? = null
5254
private set
@@ -70,7 +72,6 @@ class HexDebugger(
7072
private val virtualFrames = IdentityHashMap<SpellContinuation, MutableList<StackFrame>>()
7173

7274
private val breakpoints = mutableMapOf<Int, MutableMap<Int, SourceBreakpointMode>>() // source id -> line number
73-
private val exceptionBreakpoints = mutableSetOf<ExceptionBreakpointType>()
7475

7576
// this gets set to true by registerNewSource if a frame is loaded that contains a cognitohazard iota
7677
private var isPoisoned = false
@@ -359,13 +360,6 @@ class HexDebugger(
359360
}
360361
}
361362

362-
fun setExceptionBreakpoints(typeNames: Array<String>) {
363-
exceptionBreakpoints.clear()
364-
for (typeName in typeNames) {
365-
exceptionBreakpoints.add(ExceptionBreakpointType.valueOf(typeName))
366-
}
367-
}
368-
369363
private fun isAtBreakpoint(): Boolean {
370364
val nextIota = when (val frame = nextFrame) {
371365
// why is this empty sometimes??????

0 commit comments

Comments
 (0)