rolandshacks / vs64

C64 Development Environment for Visual Studio Code
Other
88 stars 15 forks source link

Oscar64 Support #70

Open shinaka opened 1 month ago

shinaka commented 1 month ago

I saw in another issue someone had mentioned KickC support and you had said adding support for new compilers was a lot of work and hard to justify right now, time wise (which I understand). I've been writing C64 homebrew for the past couple of years and actually ended up landing on Oscar64 (https://github.com/drmortalwombat/oscar64) after using cc65 for a while. The creator is very proactive about feedback, updates, and support issues, and personally, I think it has a great user experience.

All that to say, I was talking with the creator (@drmortalwombat) last night about the state of source code debugging (which currently only consists of modern-vice-pdb-monitor). He mentioned that he'd be willing to support any kind of debug info required, as long as the format was documented. Is there an example of format you support (or would want to support?) I'd love to help however I can to make this happen - vs64 is an excellent resource, and having access to it w/ Oscar 64 would be a dream for many of us.

Would DWARF be an option?

rolandshacks commented 1 month ago

Hi, and thanks for sharing that idea.

First and foremost - I must admit that I haven't seen or used Oscar64 so far, but now it got my interest... seems like a great piece of work, actively supported and in case the developer is supportive, that'd be great. Let me drill into it a bit, read, try out and see what the possibilities are - but also please be aware that I am a bit short on time these days, ...

About the debug info format: DRARF would actually be an option -- but for many people, it would not be the prefered option due to its crazy complexity (which is absolutely valid considering all the features it has to support). But: that is not needed for a target like the C64 (at least I think).

Give me a bit of time, and feel free to share it with the author of Oscar64 - in case I'll do something, good support would be very helpful.

Cheers! Roland

rolandshacks commented 1 month ago

PS. First request for the Oscar64 author: please publish a portable ZIP for x64 platform (Win+Linux), instead of using MSI.... :-)

drmortalwombat commented 1 month ago

A .zip for Win should be no problem, I will try to include one in the next release. Linux is a different matter, I don't build on linux so it will probably remain a source only distribution there.

drmortalwombat commented 1 month ago

BTW Oscar already generates three types of debug info:

rolandshacks commented 1 month ago

Then let me look at the existing debug info format. If the format is good&simple then there's no need to go for something different.

shinaka commented 1 month ago

This is awesome! We were just playing around with it in the Discord. It seems like the only thing that's missing is seeing values during debugging. Is there anything we can do to help facilitate that?

Either way, thank you! This is already enough that I can move my workflow out of my cobbled together VSC setup!

shinaka commented 1 month ago

Also, it looks like the llvm-mos integration has source-level debugging working via DWARF - is that an avenue we should consider for Oscar?

rolandshacks commented 1 month ago

DWARF is of course a good option - you can be sure it's future proove and provides an answer for pretty much everything. But it is very complex and the spec is not an easy read...

There's one feature request: would it be possible (maybe enabled with an additional command line arg) to add a address-range to C-source file/line list to the generated dbj? That would eliminate the need to parse the rather unformatted ".asm" file. If you want, you could also group the addr-range/source map by filename to compress the data a bit.

rolandshacks commented 1 month ago

About seeing values during debug: maybe you can textually walk me through this. Starting point: the emulator hits a breakpoint address and the VS64 debugger is activated, ...

How do I fetch all info about current scope, all variables in scope, the global variables, their values, etc. ? Also, how do I re-construct the call-stack? kind of ...everything you see when using vscode to debug host C/C++ code.

If you help me to understand, and I find a bit of time, then I'll give it a try.

drmortalwombat commented 1 month ago

The .dbj has a section "functions" that has the region to line mapping for each function. The function also includes the list of variables that are visible base on line and an index into the type table.

drmortalwombat commented 1 month ago

BTW you get much more debug information if you compile without optimization (-O0) but then, as expected, the code is also longer and slower.

shinaka commented 1 month ago

How do I fetch all info about current scope, all variables in scope, the global variables, their values, etc. ?

This should be doable with the dbj info already - just matching the address

Also, how do I re-construct the call-stack? kind of ...everything you see when using vscode to debug host C/C++ code.

This is how Modern Vice PDB Monitor does it: https://github.com/MihaMarkic/modern-vice-pdb-monitor/blob/259797c6b777827790c0205ef46822764ed42f64/source/Modern.Vice.PdbMonitor/Modern.Vice.PdbMonitor.Engine/ViewModels/CallStackViewModel.cs#L96 - looks to be just unwinding the stack pointer and lining the addresses from the dbj

drmortalwombat commented 1 month ago

Oscar does not use the call stack for parameters, so you can simply follow the call chain provided by vice.

rolandshacks commented 1 month ago

Quick update: fetching addr to source/line mapping now from dbj - super easy to do, stepping through the code works quite well now. Added the data memory entries to the debugger variables view. ...will continue with more debug / stack info soon.

shinaka commented 1 month ago

This is so great! Looking forward to playing with it! Do you have a patreon or any way to donate to the project?

rolandshacks commented 1 month ago

Is there any hint or advice for my two questions from above ^ ?

Another topic (forgive my limited understanding of actual compiler code generation): where are the local variables placed in memory, how do I find out what the actual address and value of a local variable in scope is?

drmortalwombat commented 1 month ago

Local variables are mostly not present in a dedicated memory location in an optimized build. They do exist in a non optimized build "-O0". In most cases they will have an absolute address, similar to a global variable. In case of a recursion they are on a value stack. The debug info of a stack relative variable will have "base" for the zero page register base pointer and the offset to this in "start" and "end"

rolandshacks commented 1 month ago

Any clue why content of global variables doesn't change while debugging?

drmortalwombat commented 1 month ago

It does change - at least if optimization is turned off. With optimization turned on, only changes that may be visible by e.g. functions called may actually end up in memory.

rolandshacks commented 1 month ago

Testing and feedback would really be appreciated!! Roland

drmortalwombat commented 1 month ago

`struct T { int a, b; } t[10];

void fill(void) { for(char i=0; i<10; i++) { t[i].a = i; t[i].b = i * i; } }

int test(void) { int s = 0; for(char i=0; i<10; i++) { s += t[i].b; }

return s;

}

int main() {

fill();

int s = test();

return s;

} { "name": "vstest2", "description": "Project vstest2", "toolkit": "oscar64", "sources": [ "src/main.c" ], "build": "debug", "definitions": [], "includes": [], "args": ["-O0"], "compiler": "" } `

This is my test code.

rolandshacks commented 1 month ago

Thanks, using your test program now...

shinaka commented 1 month ago

I've seen similar breakpoint accuracy with Modern Vice PDB Monitor, so I have a feeling it's VICE

drmortalwombat commented 1 month ago

One thing to keep in mind is, that a single C source line can end up in several, probably non contiguous machine instructions. So a source level breakpoint may have to be translated into multiple vice breakpoints.

rolandshacks commented 1 month ago

How it actually works is that VICE supports an address range (start...end) for a breakpoint - but what I have to do to avoid repeated breaks within on line of C source is to just use the start address. At every launch of a debug session, I do the mapping from source lines --> address, and then on every break I try to do the reverse from address to line of source/file, then let the editor open that location. And for the mapping, the ground truth is the function/line information provided by the dbj.

drmortalwombat commented 1 month ago
            {"start": 2193, "end": 2198, "source": "e:/Projects/C64Repo/vstest2/src/main.c", "line": 10},
            {"start": 2198, "end": 2229, "source": "e:/Projects/C64Repo/vstest2/src/main.c", "line": 12},
            {"start": 2229, "end": 2241, "source": "e:/Projects/C64Repo/vstest2/src/main.c", "line": 13},
            {"start": 2241, "end": 2248, "source": "e:/Projects/C64Repo/vstest2/src/main.c", "line": 10},
            {"start": 2248, "end": 2249, "source": "e:/Projects/C64Repo/vstest2/src/main.c", "line": 15}], 

Just to be clear, one line of C code (e.g. line 10 here) can result in independent machine code ranges - eg. the for entry and the for increment.

rolandshacks commented 1 month ago

Oh. I am afraid that ambiguity cannot be resolved by the debugger. Which in this example would be the logical beginning of the line 10?

drmortalwombat commented 1 month ago

Modern CPU debuggers set breakpoints on the start of all potential ranges, so this might be the best option.

rolandshacks commented 1 month ago

Ok. Here's another update, pretty much complete for what I think is feasible right now - accepting restrictions for debugging and inspection:

rolandshacks commented 1 month ago

Here's the released version: https://github.com/rolandshacks/vs64/releases/tag/v2.5.7

shinaka commented 1 month ago

First, let me say how much I appreciate all of this - I honestly didn't expect anything to this degree when I made the original post, haha. What would be the biggest impediment/blocker for inspection of local vars? I could see how the way Oscar handles it maybe not fitting with VS' expected flow? Just wondering if there's anything I/we can do to help? To me that feels like the last 'missing feature' to this being... well beyond the perfect tool for my C64 dev workflow.

rolandshacks commented 1 month ago

Thanks for the feedback. Give me a bit of time, I will of course continue.