* TinkerDifferent *
Retro Computing Community
Home | Forums | What's New | Search | Settings
68kAny sampling profilers for Mac 68k?

Forums > Vintage Apple > Software & Operating Systems > Software | Development

bribri
New Tinkerer
--------
Joined: Jun 28, 2024
Posts: 22
Likes: 9
Apr 12, 2025 - #1
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
USA
--------
Joined: Nov 18, 2021
Posts: 20
Likes: 18
Apr 13, 2025 - #2
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
--------
Joined: Jun 28, 2024
Posts: 22
Likes: 9
Apr 14, 2025 - #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
--------
Joined: Jul 20, 2023
Posts: 130
Likes: 172
Apr 14, 2025 - #4
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
--------
Joined: Jun 28, 2024
Posts: 22
Likes: 9
Apr 14, 2025 - #5
>> David Cook said:
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. Click to expand...
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
--------
Joined: Jul 20, 2023
Posts: 130
Likes: 172
Apr 14, 2025 - #6
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.

sys71src/OS/TimeMgr at main - laniku/sys71src

Apple Macintosh System Software 7.1 source leak (m68k + basic PPC) - laniku/sys71src
[Image: github.com] github.com
Attachments:
github.com [View]
github.com [View]

Liked by bribri

bribri
New Tinkerer
--------
Joined: Jun 28, 2024
Posts: 22
Likes: 9
Apr 14, 2025 - #7
Awesome, thanks! Also, I figured out how to trigger MacsBug in my code. As simple as Debugger() ;)

Liked by David Cook

David Cook
Tinkerer
--------
Joined: Jul 20, 2023
Posts: 130
Likes: 172
Apr 14, 2025 - #8
Hold the phone! What is this?

sys71src/Interfaces/CIncludes/Perf.h at main - laniku/sys71src

Apple Macintosh System Software 7.1 source leak (m68k + basic PPC) - laniku/sys71src
[Image: github.com] github.com

Did Apple already create a performance library? You may just need to call this and then convert the report file into routine names via the debug data file.
Attachments:
github.com [View]
github.com [View]

Liked by eric

bribri
New Tinkerer
--------
Joined: Jun 28, 2024
Posts: 22
Likes: 9
Apr 14, 2025 - #9
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
--------
Joined: Jun 28, 2024
Posts: 22
Likes: 9
Apr 14, 2025 - #10
>> David Cook said:
Hold the phone! What is this? sys71src/Interfaces/CIncludes/Perf.h at main - laniku/sys71src Apple Macintosh System Software 7.1 source leak (m68k + basic PPC) - laniku/sys71src github.com Did Apple already create a performance library? You may just need to call this and then convert the report file into routine names via the debug data file. Click to expand...
Whaaat! I'm definitely going to take a look at that!
Attachments:
github.com [View]
github.com [View]

joevt
Tinkerer
--------
Joined: Mar 5, 2023
Posts: 218
Likes: 85
Apr 15, 2025 - #11

bribri
New Tinkerer
--------
Joined: Jun 28, 2024
Posts: 22
Likes: 9
Apr 21, 2025 - #12
For anyone following here, I did actually figure out how to do this, and have made a 68k sampling profiler for Retro68 projects. Repo here: https://github.com/briankendall/Profiler68

Liked by eric

cy384
New Tinkerer
USA
--------
Joined: Nov 18, 2021
Posts: 20
Likes: 18
Apr 25, 2025 - #13
Nice work! When I have a few hours I'll see if I can get it running with my project (ssheven). I've been wanting to see what the ratio of CPU usage for encryption vs UI operations is.

bribri
New Tinkerer
--------
Joined: Jun 28, 2024
Posts: 22
Likes: 9
Apr 26, 2025 - #14
>> cy384 said:
Nice work! When I have a few hours I'll see if I can get it running with my project (ssheven). I've been wanting to see what the ratio of CPU usage for encryption vs UI operations is. Click to expand...

Let me know how it goes! I added a bit more instructions to the repo's read me.

bribri
New Tinkerer
--------
Joined: Jun 28, 2024
Posts: 22
Likes: 9
Apr 28, 2025 - #15
Do feel free to use the profiler, though I now realize that there's some things in it that need to be fixed. Currently it discards samples where it can't do a stack crawl, which means it might discard legitimate samples from functions that make use of register A6.

Edit: the fix for this is now described in the repo's read me

lauland
Tinkerer
--------
Joined: Dec 12, 2023
Posts: 39
Likes: 28
May 14, 2025 - #16
This is some impressive and very cool work you've done!

I've been doing a lot of m68k Retro68 lately, and have moved my primary building and testing of my SDL2 port for MacOS 7/8/9 to it from CodeWarrior. Being able to use Makefiles makes things SO much simpler, cleaner, and easier to see what code is actually being included in the build, to say the least.

I'm eager to try your profiler on it, just to see what is going on under the hood.

Even if your profiler is still being worked on, it is very far along, and it will be quite interesting to try it on such a large project.

bribri
New Tinkerer
--------
Joined: Jun 28, 2024
Posts: 22
Likes: 9
May 14, 2025 - #17
Thanks! I think at this point the profiler is basically done. The one change I'm thinking about making is improving how the samples it takes are stored in memory. Right now they're all just stuffed into a buffer one after the other, until the buffer runs out of room, and then it can't take any samples any longer. I want to replace that with some kind of hashmap so that it can keep a count of unique samples and use the memory more efficiently, but that requires getting a C hashmap implementation that works without mallocing anything. For the time being I just give it a whole megabyte to use when profiling.

Page 1 of 1

Home | Forums | What's New | Search | Bookmarks | RSS | Original | Settings
XenForo Retro Proxy by TinkerDifferent.com