68k Any sampling profilers for Mac 68k?

Relating to a 68k application

bribri

New Tinkerer
Jun 28, 2024
18
8
3
I'm been exploring profiling the code I'm writing, and I'm wondering what options are available. I've gotten CodeWarrior Pro 4's profile working, and while it certainly provides some useful information, it only provides timing on a per-function basis. I'm wondering if anyone made a sampling profile that can get down to the granularity of individual lines of code, like most modern profilers?

Also, this is mainly for my game project that I've got compiling with both Retro68 and CodeWarrior, so I'm curious about whether it's possible to profile the Retro68 build. Unfortunately using gcc's profiling features / gprof doesn't seem to work, since I don't think they support 68k.

I suppose if I wanted to get crazy, I could roll my own. In theory I could create a timer that fires every X microseconds, take note of what code was being executed before the interrupt, and then somehow figure out which lines of code it was using debugging data generated by gcc. But that's a wheel I'd rather not reinvent!
 

cy384

New Tinkerer
Nov 18, 2021
19
18
3
USA
www.cy384.com
I'd be really surprised if you find anything like that, but if you do, please share. I've been considering writing something that hooks up to QEMU's gdb interface; I think that would open up a lot more options compared to attempting something native.
 

bribri

New Tinkerer
Jun 28, 2024
18
8
3
I said I didn't want to reinvent that wheel... but I gave it a shot! I had the sense of what was the difficult part reversed, though. Correlating an instruction address with a line of code is fairly easy -- that's what building with debugging information is for.

But I haven't figured out how to catch what was last being executed at interrupt time. I thought it'd be straight forward, because according to Inside Macintosh, when an interrupt occurs, the Program Counter gets pushed on to the stack. And so I used Time Manager to write a function that would fire regularly and inspect the stack to see what was being called.

The trouble is, at least for Time Manager and VBL interrupts, the OS is doing a bunch of stuff behind the scenes to make it possible for a normal C or Pascal function to be called at interrupt time, and then restoring the previous state after that function finishes. So the stack is in a totally unpredictable state when my timer function is called, and there's no clear way to figure out where execution is eventually going to return to. Or at least, none that I've found so far.

Is it actually possible to figure out what the Program Counter was at interrupt time in a Time Manager task?
 

David Cook

Tinkerer
Jul 20, 2023
57
52
18
Here's a possible approach.

1. Run a test program that shows an alert with it's address range when it starts up. Then have it do some heavy looping with occasional calls to WaitNextEvent/GetNextEvent.
2. Add a debug breakpoint in your Time Manager program.
3. Each time it breaks, dump the stack in Macsbug until you find an address in the range of your test program. I assume a pattern will emerge of where the return address is located.
 

bribri

New Tinkerer
Jun 28, 2024
18
8
3
Here's a possible approach.

1. Run a test program that shows an alert with it's address range when it starts up. Then have it do some heavy looping with occasional calls to WaitNextEvent/GetNextEvent.
2. Add a debug breakpoint in your Time Manager program.
3. Each time it breaks, dump the stack in Macsbug until you find an address in the range of your test program. I assume a pattern will emerge of where the return address is located.
I did something that I think is basically equivalent to that:

Each time my Time Manager task fired, I had it get the address of the stack, and then scan through it looking for anything that could be an address of my program (looking for specific address ranges). I then had it print all of those -- possible because I'm running in an emulator and the printing happened on the host system -- and look for a pattern.

Unfortunately what I found is that the return address was not in a consistent position, and sometimes it wasn't there at all.

That said, your idea might be the better one, because naturally my Time Manager task is probably changing the stack by virtue of running compiled code -- the old "changing the result by measuring it" issue.

I'm still learning to use MacsBug though. How do I set a breakpoint when my task fires?
 

David Cook

Tinkerer
Jul 20, 2023
57
52
18
BTW, it looks like Apple's Time Manager source code is available. It might help you understand what the stack (and registers) should like like when your routine is called. The exact Time Manager code will depend on your ROM / System. But, this might help.

 
  • Like
Reactions: bribri

bribri

New Tinkerer
Jun 28, 2024
18
8
3
Checking with the debugger, I'm still seeing inconsistent layout of the stack at interrupt time. I'll take a look at the Time Manager source code and see if anything can be gleamed from that.
 

bribri

New Tinkerer
Jun 28, 2024
18
8
3