Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use lua debugger with emscripten? #3649

Open
sehugg opened this issue Jun 11, 2018 · 11 comments
Open

use lua debugger with emscripten? #3649

sehugg opened this issue Jun 11, 2018 · 11 comments

Comments

@sehugg
Copy link

sehugg commented Jun 11, 2018

I'm trying to use the Lua debugger interface in Emscripten, but this statement returns nil, even though I'm passing -debug to MAME:

debugger = manager:machine().debugger()

I'd like to be able to drive the debugger from my own JS-based IDE (http://8bitworkshop.com/) and don't need a MAME-provided debugger UI, just the Lua interface. I'm able to read/write memory and such via Lua, but the debugger interface seems unavailable in Emscripten. (I know there are issues with using the none debugger in Lua from #2451)

@cracyc
Copy link
Member

cracyc commented Jun 11, 2018

Using the none debugger should be okay as long as you don't expect to use the console. As for the debugger in enscripten, I don't know if it's disabled or what.

@sehugg
Copy link
Author

sehugg commented Jun 14, 2018

I should have used this format instead:

manager:machine():debugger().command("hardreset")

But this segfaults on OS X (build from http://sdlmame.lngn.net/) so I wonder if there are other problems, maybe related to #3006

Command line is ./mame64 -console -debug -debugger none -window

The debugger object is there it seems:

print(manager:machine():debugger())
sol.debugger_manager *: 0x7fdc66d37328

@cracyc
Copy link
Member

cracyc commented Jun 14, 2018

manager:machine():debugger().command("hardreset")

You need a colon after debugger() too. The colon is shorthand for manager:machine():debugger().command(manager:machine():debugger(), "hardreset").

@sehugg
Copy link
Author

sehugg commented Jun 14, 2018

Gotcha ... guess I was chasing a null pointer and Emscripten was silent about it. Looks like it works. Thanks!

@sehugg sehugg closed this as completed Jun 14, 2018
@sehugg
Copy link
Author

sehugg commented Jun 15, 2018

I don't seem to be able to get things working further though. I tried this:

dbg = manager:machine():debugger()
dbg:command('step 1')

Doesn't stop the CPU. Neither does this:

dbg.execution_state = 'stop'

This just shows a message:

dbg:command('gv')
>>>Stopped at VBLANK

'softreset' and 'hardreset' work though.

Seems the same on OS X and Emscripten (-debugger none)

@cracyc
Copy link
Member

cracyc commented Jun 15, 2018

You can't stop the cpu when using -debugger none (unless you remove from https://github.com/mamedev/mame/blob/master/src/osd/modules/debugger/none.cpp line 45). The only thing that happens is that there'll be a message in the console and if you have a register_periodic callback in lua you can check for the message and do something.

@sehugg
Copy link
Author

sehugg commented Jun 15, 2018

Hmm, can't remove that line without hanging the browser as Emscripten needs you to return from the main loop callback.

I wonder if wait_for_debugger could call a Lua callback, then a debugger could be implemented in Lua (and thus in JS). But that main loop in debugcpu.cpp would need to return while the CPU is paused otherwise the browser will hang.

@sehugg sehugg reopened this Jun 15, 2018
@cracyc
Copy link
Member

cracyc commented Jun 15, 2018

You can pause the emulation from a periodic callback but although the callback will be called immediately after a break/watchpoint the pause may be delayed until the emulation gets to a point where stopping is safe.

@sehugg
Copy link
Author

sehugg commented Jun 16, 2018

Thanks -- looks like a single breakpoint works. As you say the emulation wants to complete a scanline or portion thereof before pausing, so single-stepping seems difficult without being able to return control from wait_for_debugger to JS.

There is probably some way to emulate single-stepping by loading machine state at the beginning of a frame then stepping for N cycles. I'll have to experiment and see if this is practical.

@cracyc
Copy link
Member

cracyc commented Jun 16, 2018

I haven't tried it but since bgfx works in enscripten it might be possible to use the imgui debugger.

@vadosnaprimer
Copy link
Contributor

vadosnaprimer commented May 10, 2019

It's possible to do this in diexec.h:

	void debugger_instruction_hook(offs_t curpc)
	{
		emulator_info::lua_instruction_hook();
		if (device().machine().debug_flags & DEBUG_FLAG_CALL_HOOK)
			device().debug()->instruction_hook(curpc);
	}

Then an external debugger using lua to talk to mame could start a loop waiting for user action to exit the hook. MAME will be frozen during that time, but lua should still be able to inspect the device without having to launch the entire MAME debugger. Also this would be especially useful for non-interactive hooks since it avoids the overhead of debugger-side hooking. Read/write hooks could be done by injecting into emumem's read/write_native() I think?

I just can't figure out how to store hooks by device tag in sol. Maybe the hook should pass the device tag letting the script check if it's the needed device? Thoughts and advises appreciated!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants