Commit Graph
26 Commits
Author SHA1 Message Date
Henrik RydgårdandClaude Opus 5 a8933099b7 Make the deferred-request acknowledgement opt-in, and distinct
The acknowledgement added in "Reply to every debugger request" broke two cases
Nemoumbra pointed out, both of which come down to it reusing the request's own
event name.

A ticketless request is the bad one. {"event":"cpu.resume"} with no ticket drew
an immediate {"event":"cpu.resume"} - byte-identical to the broadcast that fires
when the game actually resumes. A client waiting for that broadcast concluded
the game was running while it was still stopped. Before, it correctly got
nothing until the resume really happened.

input.buttons.press is broken even with a ticket: it answers with the request's
own event name *and* ticket once the button has been held for the requested
frames, so the acknowledgement was indistinguishable from the real completion
and a client resolved on the first of the two. The claim in that commit that
the two are easy to tell apart was simply wrong for this handler.

So the acknowledgement is now off by default - the wire behaviour for every
existing client is exactly what it was - and a client that wants it asks, with
client.config.set {"acknowledgeDeferred": true}. It then arrives as its own
event rather than an echo:

  -> {"event":"cpu.resume","ticket":7}
  <- {"event":"deferred","for":"cpu.resume","ticket":7}
  <- {"event":"cpu.resume"}

which is unambiguous in both cases above. That still gets the original goal -
correlating any request to a reply without hardcoding which events answer
immediately, including ones added later - just without imposing it on clients
that never asked.

Also documents the ticket convention this rests on: send one when you care
about the answer, leave it off to say you aren't waiting. wsdbg followed that
convention badly, silently inserting a ticket into a raw JSON line that
deliberately omitted one; it now sends raw lines exactly as written and simply
doesn't wait on those. It opts into acknowledgements at connect, so --sync
keeps working.

pspautotests 314/314, UnitTest 55/55.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GZq8ZtJmFY7bkX5FVkr3P9
2026-08-18 09:32:04 +02:00
Henrik RydgårdandClaude Opus 5 8120338530 Add cpu.runUntilTime: run to a point in emulated time and break there
Lining a scripted repro up with a bug report ("about five seconds in, press
X") had no support at all. The only way to do it was to poll cpu.status in a
loop from the client, which is slow - a process spawn per poll, minutes for a
single run - and lands somewhere different every time, so the repro isn't one.

cpu.runUntilTime takes either an absolute `us` (as reported by cpu.status) or
`relativeUs` from now, resumes, and breaks when emulated time gets there. It
answers immediately with the target, and the usual cpu.stepping event follows
when it arrives. Anything else that stops the CPU first - a breakpoint, an
exception - cancels the deadline, the same way it cancels a pending step.

The deadline is held in microseconds, not ticks, and recomputed whenever
SetClockFrequencyHz() runs. Converting to a tick count once up front looks
right and isn't: games change the CPU clock while running, and CrossCraft
Classic goes 222 -> 333MHz during startup, which made a request for 3.0s stop
at 2.24s. With the recompute it stops at exactly 3000000us. Advance() also
shortens its slice to land on the deadline instead of up to a slice past it,
so repeated runs stop at the same instruction rather than somewhere in the
following frame.

Nothing is added to CoreTiming's event list, so savestates are unaffected -
the deadline is debugger session state and isn't serialized.

Also adds DebuggerRequest::ParamF64, since microseconds outgrow 32 bits after
about 71 minutes. Like the other Param* helpers it fails loudly on a missing
or unparseable value rather than defaulting.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GZq8ZtJmFY7bkX5FVkr3P9
2026-08-18 09:32:04 +02:00
Henrik Rydgård 18ccef1bd4 Just some minor code modernization 2025-08-25 10:45:12 +02:00
Henrik Rydgård 1025bbcf89 Log level/type: Use enum class instead of the awkward namespace trick.
Just a small cleanup I've wanted to do for a long time.
2023-08-25 11:48:59 +02:00
Nemoumbra 27a5482a46 Code cleanup, copyright typo fixed 2023-06-16 17:13:10 +03:00
Nemoumbra 3fbaea3b9a Allowed -> disallowed, at -> [], code cleanup 2023-06-05 21:51:13 +03:00
Nemoumbra af8480683a Config initialization moved to HandleDebuggerRequest 2023-06-01 17:12:22 +03:00
Nemoumbra 311687a673 ClientConfigSubscriber added 2023-05-31 19:17:43 +03:00
Nemoumbra 7f0828c659 Added WebsocketClientInfo 2023-05-27 17:59:45 +03:00
Unknown W. Brackets 5904900d37 Debugger: Add APIs to set/list/search mem tags. 2021-04-06 12:09:39 -07:00
Henrik Rydgård 4f43cff5ca Move fileutil, net, image loaders, ui to Common. (#13506)
* Move and rename file_util/fd_util to Common/File/FileUtil and DirListing

Let's also move net while we're at it.

Move the ZIM/PNG loaders over to Common.

Move the UI framework into Common

iOS buildfix

* Buildfix

* Buildfixes

* Apple buildfix

* This typo again..

* UWP buildfix

* Fix build of PPSSPPQt, such as it is (it's not in good condition...)

* Guess what? Another buildfix.
2020-10-04 20:48:47 +02:00
Henrik Rydgård 989e353482 Common.h shouldn't include Log.h.
Buildfixes

More buildfixes. Move JSON code to common.
2020-10-04 11:42:14 +02:00
Henrik Rydgård 5d64fc5ff1 Switch to PPSSPP's assert functions (don't use the system's) 2020-08-16 10:01:10 +02:00
Henrik Rydgård b22083e7a6 Even more base/logging.h removal and fixes 2020-08-15 19:09:01 +02:00
Henrik Rydgård 5117ded378 Remove ELOG/ILOG/WLOG from the Android C++ code (mostly) 2020-08-15 19:08:39 +02:00
Henrik Rydgård ab407a4a21 TWo warning fixes 2018-12-17 21:07:52 +01:00
pent0 4a53853f79 Update UWP port 2018-12-10 20:55:07 +07:00
Unknown W. Brackets 4ce2b64ef7 Debugger: Refactor to allow simpler broadcasting.
It's okay to mix a bit for simple ones, I think.
2018-09-01 10:15:22 -07:00
Henrik Rydgård eddaf97938 Add submodules, namespace json to prepare for the addition of rapidjson (sigh) 2018-08-13 00:18:54 +02:00
Unknown W. Brackets 29d93c56c7 Debugger: Initial breakpoint APIs. 2018-06-08 06:59:18 -07:00
Unknown W. Brackets 2f3b6c19d0 Debugger: Poll frequently after stepping.
This will make us listen for events slightly less often, so we don't want
to sustain it.
2018-06-08 06:59:17 -07:00
Unknown W. Brackets ccea863f00 Debugger: Use fragments for long chunks.
Gets it on the wire faster.  More importantly, this allows us to usually
avoid rampant memory allocation even for large responses.
2018-06-08 06:59:17 -07:00
Unknown W. Brackets f66738eac7 Debugger: Add cpu.evaluate method.
Probably useful for a bunch of things, really.
2018-06-08 06:59:17 -07:00
Unknown W. Brackets 944948a5f4 Debugger: Initial disasm API. 2018-06-08 06:59:17 -07:00
Unknown W. Brackets a4044fd6a0 Debugger: Reorganize state handling.
Looking like this will be needed for disasm caches, etc.
2018-06-08 06:59:16 -07:00
Unknown W. Brackets 1f987bf1c1 Debugger: Initial register get/set APIs. 2018-06-08 06:59:16 -07:00