log in | register | forums
Show:
Go:
Forums
Username:

Password:

User accounts
Register new account
Forgot password
Forum stats
List of members
Search the forums

Advanced search
Recent discussions
- RISC OS London Show 2021 - Notes from the talks (News:1)
- Free Substitute Soccer game available on !Store (News:)
- Drag'n'Drop 11i1 edition reviewed (News:)
- November News round-up (News:3)
- November News round-up (News:4)
- Rougol November talk - RISC OS Pyromaniac update (News:16)
- 'The Application Tutorial ...ISC OS computers' reviewed (News:1)
- New Iris October release (News:1)
- Rougol's November talk is on Monday (News:1)
- Amcog Games Haunted Tower Hotel Released (News:1)
Related articles
- November News round-up
- New Iris October release
- Rougol's November talk is on Monday
- Cloverleaf announces new releases for RISC OS
- R-Comp preshow streaming event
- October News round-up
- RISCOSbits at London Show
- Fireworkz Pro 2.31 and Messenger Pro 8.05 released
- Angband added to Riscosports
- R-Comp preshow update
Latest postings RSS Feeds
RSS 2.0 | 1.0 | 0.9
Atom 0.3
Misc RDF | CDF
Site Search
 
Article archives
Acorn Arcade forums: News and features: Rougol November talk - RISC OS Pyromaniac update
 

Rougol November talk - RISC OS Pyromaniac update

Posted by Mark Stephens on 22:01, 15/11/2021 | ,
 
This month's talk was probably the first proper 'hybrid' Rougol meetings with 8 people in person and 25 (including the speaker) on Zoom. We were actually kicked out of our usual room into a smaller one, so 8 people worked well.

If you turned up in person, it was very sociable from 6.30pm onwards, and the food the Duke of Sussex is very good.
 
This month's talk was an update by Graph on his talk last year where he showed off RISC OS pyromanic - a Cloud based Python implementation of RISC OS classic (as he now calls RISC OS in its traditional form) which makes testing, development and a whole lot of other things much easier.
 
The short answer to what Gerph had been working on was 'quite a lot'. The original version of Pyromania was quite limited in a lot of ways. The late 2021 has a lot more polish and functionality.
 
In particular it has a lot more of the functionality you might want to use in RISC OS, including a screen display, Sprite support and fonts.
 
The screen display component involved writing a VNC server, which is available as a separate project on Github. It only took 317 lines of code to integrate into pyromaniac
 
It is a lot of work to support sprites - we had a nice overview of how RISC OS draws sprites. There was lots of explanation on colour mapping, scrapings, transformation and tiling
 
There was a nice demo of Vnc server showing riscos games running on vnc in Pyromaniac. This could be used to add unit tests
 
Much of the presentation explained how RISC OS worked. So even if you were not interested in Pyromaniac, there was a lot of RISC OS detail really clearly presented - the slides and video should hopefully be available shortly.
 
Pyromaniac has moved from interesting to really interesting, and it will be exciting to see how Gerph develops it into 2022.
 
There is no Rougol meeting in December, but normal service resumes in January.
 
It was really great to be at an in person meeting again - here are some photos to prove we were there...
 




 
  Rougol November talk - RISC OS Pyromaniac update
  gerph (23:55 15/11/2021)
  Jaffa (09:34 16/11/2021)
    gerph (13:55 16/11/2021)
      Jaffa (22:03 16/11/2021)
        gerph (23:48 16/11/2021)
          Jaffa (14:55 17/11/2021)
            gerph (18:30 17/11/2021)
              markee174 (08:28 18/11/2021)
              Jaffa (13:41 18/11/2021)
                gerph (13:49 18/11/2021)
          wpb (17:21 17/11/2021)
            gerph (20:20 17/11/2021)
              wpb (13:13 18/11/2021)
                gerph (18:02 19/11/2021)
                  wpb (19:31 19/11/2021)
  Stoppers (19:10 17/11/2021)
 
Charles Justin Ferguson Message #125238, posted by gerph at 23:55, 15/11/2021
Member
Posts: 29
Thank you to everyone came to the meeting and for the questions.

If you want to know more about Pyromaniac the resource site at https://pyromaniac.riscos.online/ has more details and examples (pictures, videos, code, and links to open source).

The full slides for the presentation together with the speaker notes are available at https://presentation.riscos.online/pyromaniac2/index.html

There is a survey about the presentation which it help me if you could complete: https://survey.gerph.org/index.php/199167?lang=en
  ^[ Log in to reply ]
 
Andrew Flegg Message #125239, posted by Jaffa at 09:34, 16/11/2021, in reply to message #125238
Member
Posts: 53
It's really impressive - unfortunately I had to leave the pub before the end (made it to the Documentation handouts - loving PRM-in-XML).

One of the questions I didn't ask after the RailPro demo was you'd mentioned performance a few times, particularly with all the ColourTrans etc. processing with sprites.

What kind of performance, on what kind of system, are you seeing?

I'd've loved to have made it through to the System Demo (any chance of a YouTube video, or similar?) and suspect it'd've answered the question!

EDIT: Videos are on the Pyromaniac example site: https://pyromaniac.riscos.online/examples.html

[Edited by Jaffa at 09:36, 16/11/2021]
  ^[ Log in to reply ]
 
Charles Justin Ferguson Message #125240, posted by gerph at 13:55, 16/11/2021, in reply to message #125239
Member
Posts: 29
It's really impressive - unfortunately I had to leave the pub before the end (made it to the Documentation handouts - loving PRM-in-XML).
Thank you smile

One of the questions I didn't ask after the RailPro demo was you'd mentioned performance a few times, particularly with all the ColourTrans etc. processing with sprites.

What kind of performance, on what kind of system, are you seeing?
I can answer the system one more easily by saying what I run and the environmental considerations.

I'm running my stuff on an 8GB 2.6GHz i7 - that's a 4 core 2013 MacBook Pro. My laptop usually has Firefox running (3 windows, ~1000 tabs), 4 additional monitors using external DisplayLink graphics driver, SublimeText with about 20 windows open (all with many files open), and Clementine, an MP3 player running a lot of the time. Do those apps matter? Possibly not to the general scheme of things, but that's the kind of environment I'm using when I'm working and developing things - those things are all contending for system use. And I don't think they make it that slow because mostly it's single core only for RISC OS Pyromaniac.

As for the kind of performance... it's hard to know how to measure it. You've seen some of the videos and they're all timed to run in real time - they shouldn't be accelerated artificially, or slowed - so you should be a bit of a feel for it.

I'd say the general feel is like ARM 2. Or possibly ARM 3 but running modern software. That said, when it sits in native code it can be fast - although those sprites are converted in the python, actually rendering them is fast once it hits Cairo. This is most obvious in the system demo when the window furniture and background are drawn really fast.

Ideally I'd run some benchmarks but they're hard because they tend to rely on things that aren't quite right or where it makes assumptions about the system.

A while back I nobbled `romark4` to make it able to run - it has some assumptions that can't be met at the moment.


charles@laputa ~/projects/RO/pyromaniac (master)> cat romark4/Pipe-mlog19422
RISCOSmark 2.06 (29-Mar-2016) by Richard Spencer 2003
Comparison with RiscPC SA 202MHz running RISC OS 4.02 800x600,256
(HD benchmarks are in kilobytes/sec)

Pre 2002 including Risc PC & VRPC RISC OS Commands provided: tested at Tue,19 Oct 2021 00:06:01
Filing system: HostFS$.romark4
Graphics Resoloution: 640x480, 16 colours

Test Benchmark
Fast/slow speed switching not supported on this hardware
Processor - Looped instructions (cache) 1 0%
Memory - Multiple register transfer 1 0%
Rectangle Copy - Graphics acceleration test 37 15%
Icon Plotting - 16 colour sprite with mask 2229 111%
Draw Path - Stroke narrow line 707 45%
Draw Fill - Plot filled shape 715 49%
Draw Render - Render draw file 172 18%
HD Read - Block load 8MB file 462320 15503%
HD Write - Block save 8MB file 96376 3169%
FS Read - Byte stream file in 2 0%
FS Write - Byte stream file out 2 1%


The processor and memory operations aren't run properly - they just return a garbage answer because of that.

Although it says it's running in 640x480x16 colours I suspect that this didn't even have the graphics implementation attached - it may have been doing nothing except going through the motions of working out what to do, because there was no graphics system to do it with.

The byte operations ('byte stream') are some of the slowest operations for files, for example, and they're only representative of the most basic of applications (eg BASIC), so they come out really poorly.


I'd've loved to have made it through to the System Demo (any chance of a YouTube video, or similar?) and suspect it'd've answered the question!

EDIT: Videos are on the Pyromaniac example site: https://pyromaniac.riscos.online/examples.html
Yeah there's a few demo videos on there that should show you a little more of how fast it works.

If you've got any specific thoughts of things to try out, let me know and I'll try to give a little more information.

[Edited by gerph at 13:56, 16/11/2021]

[Edited by gerph at 13:56, 16/11/2021]
  ^[ Log in to reply ]
 
Andrew Flegg Message #125241, posted by Jaffa at 22:03, 16/11/2021, in reply to message #125240
Member
Posts: 53
Thanks for the details. I checked the Pyromaniac site, and I think you covered it in the first presentation - but couldn't find it - how are you handling ARM code? Your own handler in Python or qemu (or something else?).

You mention updating it to Python 3 on your roadmap, IME v3 is generally quicker - so you might get a nice speed bump for free there.

In terms of BGET being slow, and RISC OS being so *cough* beautifully single threaded... could you use another thread to start doing presumptive reads of the file into a Python buffer? Then feed it to RISC OS as requested. Memory and cores are what modern systems have lots of, after all. (Notwithstanding general Python threading issues)
  ^[ Log in to reply ]
 
Charles Justin Ferguson Message #125242, posted by gerph at 23:48, 16/11/2021, in reply to message #125241
Member
Posts: 29
Thanks for the details. I checked the Pyromaniac site, and I think you covered it in the first presentation - but couldn't find it - how are you handling ARM code? Your own handler in Python or qemu (or something else?).
It's handled by Unicorn - a Python library (amongst many) that uses QEmu source underneath. See: https://github.com/unicorn-engine/unicorn

You mention updating it to Python 3 on your roadmap, IME v3 is generally quicker - so you might get a nice speed bump for free there.
My initial conversion, which was very rough, was getting a 10% slowdown, and that was before I convert all the code to use proper bytes objects - this might improve the speed. But it's a lot of work...


In terms of BGET being slow, and RISC OS being so *cough* beautifully single threaded... could you use another thread to start doing presumptive reads of the file into a Python buffer? Then feed it to RISC OS as requested. Memory and cores are what modern systems have lots of, after all. (Notwithstanding general Python threading issues)
I don't think it's really the file reading code that's slow. I think it's largely the transitioning in and out of the different systems. Don't think in terms of RISC OS - the filesystem operation itself isn't slow like it is on RISC OS, although to be fair on no other system would you ever have a system call that transferred a single byte of data (I suspect). It's the fact that it's passing through a lot more code to get there.

I stripped down part of the romark code to only run the two BGET/BPUT tests but with the timings enabled... This is the result:


charles@phonewave ~/projects/RO/pyromaniac/romark4 (compressjpeg-experiment)>
pyrodev --common --command 'romark6' --config memorymap.appspace_size=10M --load-module ../modules/Wimp,ffa \
--load-module ../modules/DrawFile,ffa
Program renumbered
==> Help on keyword 'UtilityModule' (Module)
Module is: MOS Utilities 7.29 (02 Nov 2021)

Commands provided:
GOS
LINE: [==> Help on keyword 'UtilityModule' (Module)]
LINE: [Module is: MOS Utilities 7.29 (02 Nov 2021)]
LINE: []
LINE: [Commands provided:]
LINE: [ GOS]
LINE: []
[^L/12:][^L/12:]Running test 1 (FS Read)
[^L/12:]Running test 2 (FS Write)
SWI individual timings:
&00000a : OS_BGet : 2384 calls, 0 errors, 0.252892 s, 0.000106 s/call
&00000b : OS_BPut : 2329 calls, 0 errors, 0.246452 s, 0.000106 s/call
&000042 : OS_ReadMonotonicTime : 33 calls, 0 errors, 0.002170 s, 0.000066 s/call
&000039 : OS_SWINumberFromString : 25 calls, 0 errors, 0.014738 s, 0.000590 s/call
&00006e : OS_SynchroniseCodeAreas : 8 calls, 0 errors, 0.001114 s, 0.000139 s/call
&000046 : OS_WriteN : 5 calls, 0 errors, 0.001471 s, 0.000294 s/call
&00000d : OS_Find : 4 calls, 0 errors, 0.003171 s, 0.000793 s/call
&000008 : OS_File : 3 calls, 0 errors, 0.005701 s, 0.001900 s/call
&00003b : OS_CallAfter : 2 calls, 0 errors, 0.000146 s, 0.000073 s/call
&000000 : OS_WriteC : 1 calls, 0 errors, 0.000182 s, 0.000182 s/call
&000003 : OS_NewLine : 1 calls, 0 errors, 0.000133 s, 0.000133 s/call
&00000c : OS_GBPB : 1 calls, 0 errors, 0.000204 s, 0.000204 s/call
Swi timings:
In SWI: 0.528374 s
Swi calls: 4796 calls
Average duration: 0.000110 s/call
Emulation timings:
In emulation: 0.524292 s
Emulation calls: 4799 calls
Average duration: 0.000109 s/call
Non-Emulation timings:
In non-emulation: 1.420376 s
Non-Emulation calls: 4798 calls
Average duration: 0.000296 s/call
Callback timings:
In callback: 0.018973 s
Callback calls: 4797 calls
Average duration: 0.000004 s/call
Timer timings:
In timer: 0.690908 s
Timer calls: 4715 calls
Average duration: 0.000147 s/call
Tests complete: Wrote to Pipe-mlog00038


So the OS_BGet/OS_BPut operations are around 0.000106 sec per call. Quick tests tell me that 20% of that is passing through the vector system (it reduces to 0.000084 sec per call if I take out the vector call). As you can see from the other SWIs, about the fastest you can do anything is 0.000066 sec per call (from the OS_ReadMonotonicTime - which isn't the fastest SWI you can run but it's pretty close).

The aggregate timings show that the bulk of the time taken ended up being in Pyromaniac code (1.42 seconds), compared to the emulation (0.52 seconds). Just processing the timer operations (checking whether we needed to trigger ticks) is 0.69 seconds. Now that is something that could move to another thread, since all we do is check whether a centisecond has passed and then call into the timer system. It could be triggered more easily by just setting a semaphore when we needed to handle the timer. I'm not sure quite how much that would give but it might be worthwhile.

However... looking at the code, we have a bug - those timer timings were way too high. It was essentially calling the timer code with at least every SWI - the number of timer calls and the number of SWI calls were approximately the same. They SHOULD only be triggered when the centisecond timer ticks over. It turns out that the ticker events were never catching up - they'd were always being triggered of every SWI because the check whether they were overdue was wrong.

So... that's now fixed and we have output that looks like this:


charles@phonewave ~/projects/RO/pyromaniac/romark4 (compressjpeg-experiment)>
pyrodev --common --command 'romark6' --config memorymap.appspace_size=10M --load-module ../modules/Wimp,ffa \
--load-module ../modules/DrawFile,ffa
Program renumbered
==> Help on keyword 'UtilityModule' (Module)
Module is: MOS Utilities 7.29 (02 Nov 2021)

Commands provided:
GOS
LINE: [==> Help on keyword 'UtilityModule' (Module)]
LINE: [Module is: MOS Utilities 7.29 (02 Nov 2021)]
LINE: []
LINE: [Commands provided:]
LINE: [ GOS]
LINE: []
[^L/12:][^L/12:]Running test 1 (FS Read)
[^L/12:]Running test 2 (FS Write)
SWI individual timings:
&00000b : OS_BPut : 3732 calls, 0 errors, 0.382703 s, 0.000103 s/call
&00000a : OS_BGet : 3726 calls, 0 errors, 0.380799 s, 0.000102 s/call
&000042 : OS_ReadMonotonicTime : 39 calls, 0 errors, 0.002570 s, 0.000066 s/call
&000039 : OS_SWINumberFromString : 25 calls, 0 errors, 0.013046 s, 0.000522 s/call
&00006e : OS_SynchroniseCodeAreas : 8 calls, 0 errors, 0.000839 s, 0.000105 s/call
&000046 : OS_WriteN : 5 calls, 0 errors, 0.001310 s, 0.000262 s/call
&00000d : OS_Find : 4 calls, 0 errors, 0.003342 s, 0.000836 s/call
&000008 : OS_File : 3 calls, 0 errors, 0.006083 s, 0.002028 s/call
&00003b : OS_CallAfter : 2 calls, 0 errors, 0.000158 s, 0.000079 s/call
&000000 : OS_WriteC : 1 calls, 0 errors, 0.000140 s, 0.000140 s/call
&000003 : OS_NewLine : 1 calls, 0 errors, 0.000151 s, 0.000151 s/call
&00000c : OS_GBPB : 1 calls, 0 errors, 0.000148 s, 0.000148 s/call
Swi timings:
In SWI: 0.791289 s
Swi calls: 7547 calls
Average duration: 0.000105 s/call
Emulation timings:
In emulation: 0.739288 s
Emulation calls: 7550 calls
Average duration: 0.000098 s/call
Non-Emulation timings:
In non-emulation: 1.127987 s
Non-Emulation calls: 7549 calls
Average duration: 0.000149 s/call
Callback timings:
In callback: 0.030333 s
Callback calls: 7548 calls
Average duration: 0.000004 s/call
Timer timings:
In timer: 0.055628 s
Timer calls: 315 calls
Average duration: 0.000177 s/call
Tests complete: Wrote to Pipe-mlog00035


What's happened here is that we're gettin about 50% more calls to the SWIs within the timing period - because we're not wasting time in the timer calls. The timer had been taking up about 0.69 second in the prior test. It's now only taking up about 0.06 seconds. So that's cool. I've not changed the OS_BGet/OS_BPut code's timings, but have instead improved the whole system. So ta for asking about that.

On the other hand, it's also shown off the fact that you've got access to the system's timing information just using simple SWI calls - *PyromaniacTimings on turns them on and *pyromaniactimings displays the current timings.

The other thing to remember about this is that RISC OS Pyromaniac isn't written for speed. Although I'll use methods that will be faster, I've intentionally chosen the simple or obvious way to implement things where I can. If I know that it doesn't matter I can do it as clearly as possible - and this also means that the code is littered with 'if self.debug_foo' type statements that are able to be turned on whilst the system is running. Obviously these will slow things down. That's fine with me - the purpose is to be able to give more information on problems and to be able to test and prototype things.

This is the other reason why it's so amazing (to me) that the desktop is as usable as it is. I know that it's going through a lot of code, and that it's not optimised in some cases. Yeah the rendering operations might be accelerated by going through cairo but the hoops they have to jump through to get there... and it's still usable.

[Edited by gerph at 23:54, 16/11/2021]
  ^[ Log in to reply ]
 
Andrew Flegg Message #125243, posted by Jaffa at 14:55, 17/11/2021, in reply to message #125242
Member
Posts: 53

It's now only taking up about 0.06 seconds. So that's cool. I've not changed the OS_BGet/OS_BPut code's timings, but have instead improved the whole system. So ta for asking about that.
Always happy to ask the semi-dumb question from a position of informed ignorance smile


The other thing to remember about this is that RISC OS Pyromaniac isn't written for speed. Although I'll use methods that will be faster, I've intentionally chosen the simple or obvious way to implement things where I can. If I know that it doesn't matter I can do it as clearly as possible - and this also means that the code is littered with 'if self.debug_foo' type statements that are able to be turned on whilst the system is running. Obviously these will slow things down. That's fine with me - the purpose is to be able to give more information on problems and to be able to test and prototype things.
Absolutely! I think it's one of the reasons I'm so excited by Pyromaniac: as you've mentioned in the presentation, it's in a higher level language than the underlying Assembler (or even C). This not only makes it easier to understand what's going on under the covers, and easier to change things - but also highlights the kind of things going on under any (simple) OS.

It feels to me that rebuilding an 80s OS in a higher-level language - such that it can run the Desktop! - is potentially not only a fun project to hack on, but a relatively interesting learning aid as to how these systems are put together; and how (or how not to) build these kind of APIs - without getting distracted by the representation of the code in a lower level codebase.

What are your plans for it? Obviously it's powering the cloud build service, which is of potential value to folk. But open source? Private toy? Something else?
  ^[ Log in to reply ]
 
W. P. B. Message #125244, posted by wpb at 17:21, 17/11/2021, in reply to message #125242
Member
Posts: 22
This is absolutely sterling work. Thanks for creating it, and thanks for sharing it.

I wonder if there's any potential in creating an interactive debugger using it. I'm trying to chase down a right pain of a bug in some code at the moment, and being able to single step through the code would make my life sooo much easier!
  ^[ Log in to reply ]
 
Charles Justin Ferguson Message #125245, posted by gerph at 18:30, 17/11/2021, in reply to message #125243
Member
Posts: 29
What are your plans for it? Obviously it's powering the cloud build service, which is of potential value to folk. But open source? Private toy? Something else?
At some point I intend to make it available to people, but I'll only do that if I'm confident in it. The cloud service is already available, and the shell demonstrates it to people. They're demonstrators to people to show what it can do. As I think I've said before, I'll make it available if people are interested. Nobody has shown much interest in the cloud service or Pyromaniac, and so if there's no interest, that confidence won't increase, and I won't expend the effort there.

And as I've said before, if people are interested, contact me and we can see what you can do with it.
  ^[ Log in to reply ]
 
Simon Willcocks Message #125246, posted by Stoppers at 19:10, 17/11/2021, in reply to message #125238
Member
Posts: 299
Thanks for posting the presentation. I couldn't make it on the day, but I'm reading through with interest.

Just out of interest, who brought Orac?
  ^[ Log in to reply ]
 
Charles Justin Ferguson Message #125247, posted by gerph at 20:20, 17/11/2021, in reply to message #125244
Member
Posts: 29
This is absolutely sterling work. Thanks for creating it, and thanks for sharing it.
Thank you smile

I wonder if there's any potential in creating an interactive debugger using it. I'm trying to chase down a right pain of a bug in some code at the moment, and being able to single step through the code would make my life sooo much easier!
Interactive debugger is one of my intentions, but it's not been particularly high on my list of things to do. Largely because it's so much easier to just record everything that it does and then look at the log file. Because that's essentially all you're doing when you're single stepping through the code anyhow.

I've just been looking to see if I can find an example of the trace system, but at this moment I can't find any logs.

Maybe however, I can give an example which might show a little of how you might debug (albeit I'll show it in the synthetic shell.riscos.online environment).

In this example I'm going to use the broken Freeway module that's in the shell server - it's fixed locally, I think but I've left it broken in there so that I can do this sort of demonstration.

Let's see the most basic of debug output - watchpoints. You know where it's going to write to, so you set a watchpoint to trap the access. You'd do this with the command *PyromaniacWatchpoint +address to add the watchpoint.

In our case I'm not going to do that because there are implicit watchpoints on zero page by default in the shell server, and that's what we're going to see. There is a bug in the Freeway module which causes it to read from zero page. We can see it very easily.

Connect to https://shell.riscos.online and type *Rmreinit freeway.
I'll include the output you'll see here, but you should be able to play along - you might need to scroll up if your screen doesn't show all the output.

This will show you the watchpoint on address 4 in memory being triggered - it's reported like this:


*rmreinit freeway
38456e0: <WATCH> READ [&00000004] = &00000000 (word)
r0 = &07006704, r1 = &00000004, r2 = &00000000, r3 = &00000001
r4 = &00000000, r5 = &00000000, r6 = &00000005, r7 = &03848870
r8 = &00000000, r9 = &00000000, r10 = &0410021c, r11 = &04107eb4
r12 = &037be7a8, sp = &04107e84, lr = &03842af8, pc = &038456e0
CPSR= &60000013 : SVC-32 ARM fi ae qvCZn
SPSR= &00000013 : SVC-32 ARM fi ae qvczn
Locations:
r0 -> [&00000000, &00000000, &00000000, &00000000] in DA 'Module area', module 'Freeway%Base' workspace
r7 -> [&74736f48, &00000073, &65726564, &74736967] in DA 'ROM', module 'FreewayHosts'
r10 -> [&00000000, &00000000, &00000000, &00000000] in DA 'SVC Stack'
r11 -> [&0384564c, &00000004, &00000005, &00000000] in DA 'SVC Stack'
pc is DA 'ROM', module 'Freeway': Function RegisterType+&a0
lr is DA 'ROM', module 'Freeway'
C backtrace:
38456e0 function RegisterType
Arg1: &04107eb8 68189880 [&00000004, &00000005, &00000000, &03848870]
Executing code block (pc is not exact):
38456e0: LDR r0, [r4, #4]
38456e4: TEQ r0, r6
38456e8: BEQ &03845788
38456ec: LDR r0, [sp, #4]
38456f0: TEQ r0, #0
38456f4: BEQ &03845A14
38456f8: MOV r0, #&44 ; #68 = 'D'
38456fc: BL &038478E8
3845700: MOVS r4, r0
3845704: BEQ &03845814
3845708: MOV r0, r4
384570c: MOV r2, #&44 ; #68 = 'D'
3845710: MOV r1, #0
3845714: BL &038478B4
3845718: TEQ r7, #0
384571c: STR r6, [r4, #4]


For various reasons the pc reported isn't exact (unicorn bug/'feature'). However, the code shown is indicating what's happened. There is the fact that the word was read (and the value was 0). The registers that were in place at the time are dumped, and then the locations that any of those registers which are aligned (and not 0) point to. This is then followed by the backtrace of the C call stack - we're in the RegisterType function. Because the PC is not exact, the failure is somewhere after 38456e0, and it has listed the code that was present there.

It could be many things but that first instruction looks like a good bet - it's loading from r4 with offset 4 and we can see that r4 is 0. So that's a bug - why it is doing that might be tricky without the source.

But we can do better.

Instead of just trapping the code after the event we can trace the blocks that are executed up to the failure. In this mode, every block of code that is run is remembered and when there is an exception, watchpoint, tracepoint or other event that needs reporting, we can dump that information to know more about what's going on.

So let's turn on the block tracing. Type *pyromaniacdebug traceblock.

And then we'll repeat the failing command: *rmreinit freeway


*rmreinit freeway
38456e0: <WATCH> READ [&00000004] = &00000000 (word)
r0 = &07006704, r1 = &00000004, r2 = &00000000, r3 = &00000001
r4 = &00000000, r5 = &00000000, r6 = &00000005, r7 = &03848870
r8 = &00000000, r9 = &00000000, r10 = &0410021c, r11 = &04107eb4
r12 = &037be7a8, sp = &04107e84, lr = &03842af8, pc = &038456e0
CPSR= &60000013 : SVC-32 ARM fi ae qvCZn
SPSR= &00000013 : SVC-32 ARM fi ae qvczn
Locations:
r0 -> [&00000000, &00000000, &00000000, &00000000] in DA 'Module area', module 'Freeway%Base' workspace
r7 -> [&74736f48, &00000073, &65726564, &74736967] in DA 'ROM', module 'FreewayHosts'
r10 -> [&00000000, &00000000, &00000000, &00000000] in DA 'SVC Stack'
r11 -> [&0384564c, &00000004, &00000005, &00000000] in DA 'SVC Stack'
pc is DA 'ROM', module 'Freeway': Function RegisterType+&a0
lr is DA 'ROM', module 'Freeway'
C backtrace:
38456e0 function RegisterType
Arg1: &04107eb8 68189880 [&00000004, &00000005, &00000000, &03848870]
Recently executed code:
---- Block &0382b26c, 3 instructions ----
382b26c: {DA 'ROM', module 'SharedCLibrary'}
Function: _swix
382b26c: ORR r0, r0, #&20000 ; Function: _swix ; #131072 = bit 17
382b270: TST r1, #&ff0 ; #4080
382b274: BNE &0382B2E0 ; -> Function: _swi
---- Block &0382b278, 21 instructions ----
382b278: PUSH {r2, r3}
382b27c: ADD r12, sp, #8
382b280: PUSH {r1, r4, r5, r6, r7, r8, r9, r11, r12, lr, pc}
382b284: SUB r11, r12, #&c
382b288: SUB sp, sp, #&14
382b28c: ADD lr, sp, #&40
382b290: MOV r12, r0
382b294: STR r11, [sp]
382b298: MOV r11, r1
382b29c: TST r11, #1
382b2a0: LDRNE r0, [lr], #4
382b2a4: TST r11, #2
382b2a8: LDRNE r1, [lr], #4
382b2ac: TST r11, #4
382b2b0: LDRNE r2, [lr], #4
382b2b4: TST r11, #8
382b2b8: LDRNE r3, [lr], #4
382b2bc: STR lr, [sp, #4]
382b2c0: LDR r11, [sp]
382b2c4: LDR lr, [sp, #&38]
382b2c8: SWI XOS_CallASWIR12 ; SWI number in R12
---- Block &03842ac0, 14 instructions ----
3842ac0: {DA 'ROM', module 'Freeway': Entry SWI handler}
3842ac0: PUSH {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, lr}
3842ac4: MRS r8, apsr
3842ac8: MOV r10, sp, LSR #20
3842acc: MOV r10, r10, LSL #20
3842ad0: MOV r0, r11
3842ad4: MOV r1, sp
3842ad8: LDMIA r10, {r4, r5}
3842adc: MOV r2, r12
3842ae0: LDR r12, [r12]
3842ae4: LDMIB r12, {r11, r12}
3842ae8: STMIA r10, {r11, r12}
3842aec: ADD r10, r10, #&21c
3842af0: MOV r11, #0
3842af4: BL &03843DDC
---- Block &03843ddc, 3 instructions ----
3843ddc: {DA 'ROM', module 'Freeway'}
3843ddc: CMP r0, #8
3843de0: MOVHS r0, #&e ; #14
3843de4: BHS &03843ADC ; -> Function: fw_error
---- Block &03843de8, 6 instructions ----
3843de8: LDR r2, &03843E00 ; = &03848138
3843dec: LDR r12, [r10, #-&218]
3843df0: ADD r2, r12, r2
3843df4: ADD r2, r2, r0, LSL #2
3843df8: MOV r0, r1
3843dfc: LDR pc, [r2]
---- Block &03845640, 24 instructions ----
Function: RegisterType
3845640: MOV r12, sp ; Function: RegisterType
3845644: PUSH {r0, r4, r5, r6, r7, r8, r9, r11, r12, lr, pc}
3845648: SUB r11, r12, #4
384564c: SUB sp, sp, #8
3845650: MOV r1, #0
3845654: STR r1, [sp]
3845658: LDR r1, [r0]
384565c: TST r1, #1
3845660: MOV r2, #1
3845664: MOVEQ r3, r2
3845668: MOVNE r3, #0
384566c: STR r3, [sp, #4]
3845670: TST r1, #2
3845674: MOVEQ r2, #0
3845678: MOV r9, r2
384567c: TEQ r2, #1
3845680: LDR r6, [r0, #4]
3845684: MOVNE r5, #0
3845688: LDREQ r5, [r0, #8]
384568c: TST r1, #4
3845690: MOVEQ r7, #0
3845694: LDRNE r7, [r0, #&c]!
3845698: TEQ r7, #0
384569c: BEQ &038456AC
---- Block &038456a0, 3 instructions ----
38456a0: CMP r7, #&8000 ; #32768 = bit 15
38456a4: MOVLO r0, #&11 ; #17
38456a8: BLO &03845A18
---- Block &038456ac, 6 instructions ----
38456ac: MOV r8, #0
38456b0: LDR r0, &03844A30 ; = &03847dc8
38456b4: LDR r12, [r10, #-&218]
38456b8: ADD r0, r12, r0
38456bc: LDR r4, [r0, #&194]!
38456c0: B &038456CC
---- Block &038456cc, 2 instructions ----
38456cc: TEQ r4, #0
38456d0: BEQ &038456E0
---- Block &038456e0, 3 instructions ----
38456e0: LDR r0, [r4, #4]
38456e4: TEQ r0, r6
38456e8: BEQ &03845788


This time we have the exact same information that was there before in the header of the report, but each block of code that was executed is listed explicitly, going back a reasonable number of blocks (the number is configurable). A 'block' here is essentially runs of instructions that don't change the flow of control - they run in a straight line executing every instruction until they hit a branch or control instruction of some form.

It we look at the bottom of this disassembly, again we can see that instruction LDR r0, [r4, #4] which was we thought was the problem before - and because it's in a shorter block here, we can be really sure that this was the failing instruction.

But look what's immediately before it! TEQ r4, #0 : BEQ ... - it's checked that the value is 0 and then jumped to the code that goes and uses that 0 value - you can see that it takes the branch beacuse the new execution address is the one that it asked to branch to. Doh! The bug is that it's failing to protect one of the accesses inside the conditional check that the value was NULL.

If you look at the code looking up from the bottom of the trace you'll see that some instructions have comments describing the constant values that were being referenced. Further up still you can see named functions listed as we enter the functions, and a BHS instruction which has a named function as the destination. Further up still you can see where the SWI call was entered - 3842ac0: {DA 'ROM', module 'Freeway': Entry SWI handler}.

Let us assume that we'd not found the bug, but we knew that it was around there. There are a number of things that we could do. But I'm going to demonstrate the trace disassembly that outputs each instruction as it happens. And I'm going to forcibly trigger a crash.

I know that address &38456e0 is where things are bad. So I'm going to make the code crash there.

Type *MemoryA 38456e0 e3a0f000.

This changes that instruction to be a MOV pc, #0. Just ignore the fact that ROM is writeable here - Pyromaniac plays a little loose with memory protection (which is itself a problem, but here it's helping).

If you want to confirm that it really has changed the instruction, use *memoryi 38456e0-10+20 to disassemble some memory around that address.

This time we want more debug, but if we debug all the freeway initialisation it'll be very tedious. We could do that with: *Pyromaniacdebug trace

But I don't want to do that here. Instead I'm going to use the fact that we saw it was entering the SWI handler to only trace the SWI code. We can do that with a variant of the SWI trapping configuration. If you configure the SWI Trap with an action of 'trace' it will turn on tracing for the duration of that SWI.

Type: *Pyromaniacconfig trace.switraps=Freeway_Register:trace

You should see something like this:


*rmreinit freeway
382b2cc: <SWIin> &67a80 (Freeway_Register) : enable tracing in SWI
S[ : 3842ac0: PUSH {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, lr}
S[| : 3842ac4: MRS r8, apsr
S[| : 3842ac8: MOV r10, sp, LSR #20 ; R13 = &04107eb8
S[| : 3842acc: MOV r10, r10, LSL #20 ; R10 = &00000041
S[| : 3842ad0: MOV r0, r11 ; R11 = &00000000
S[| : 3842ad4: MOV r1, sp ; R13 = &04107eb8
S[| : 3842ad8: LDMIA r10, {r4, r5} ; R10 = &04100000
S[| : 3842adc: MOV r2, r12 ; R12 = &07003a5c
S[| : 3842ae0: LDR r12, [r12] ; R12 = &07003a5c
S[| : 3842ae4: LDMIB r12, {r11, r12} ; R12 = &07006564
S[| : 3842ae8: STMIA r10, {r11, r12} ; R10 = &04100000
S[| : 3842aec: ADD r10, r10, #&21c ; R10 = &04100000
S[| : 3842af0: MOV r11, #0
S[| : 3842af4: BL &03843DDC
S[| : 3843ddc: CMP r0, #8 ; R0 = &00000000
S[| : 3843de0: MOVHS r0, #&e ; #14
S[| : 3843de4: BHS &03843ADC ; -> Function: fw_error
S[| : 3843de8: LDR r2, &03843E00 ; = &03848138
S[| : 3843dec: LDR r12, [r10, #-&218] ; R10 = &0410021c
S[| : 3843df0: ADD r2, r12, r2 ; R12 = &037be7a8, R2 = &03848138
S[| : 3843df4: ADD r2, r2, r0, LSL #2 ; R2 = &070068e0, R0 = &00000000
S[| : 3843df8: MOV r0, r1 ; R1 = &04107eb8
S[| : 3843dfc: LDR pc, [r2] ; R2 = &070068e0
S[| : Function: RegisterType
S[| : r0 = &04107eb8, r1 = &04107eb8, r2 = &070068e0, r3 = &03848870
S[| : r4 = &037d318c, r5 = &037bb210, r6 = &60000013, r7 = &04107fbc
S[| : r8 = &00000013, r9 = &00000000, r10 = &0410021c, r11 = &00000000
S[| : r12 = &037be7a8, sp = &04107eb8, lr = &03842af8, pc = &03845640
S[| : CPSR= &80000013 : SVC-32 ARM fi ae qvczN
S[| : SPSR= &00000013 : SVC-32 ARM fi ae qvczn
S[| : 3845640: MOV r12, sp ; Function: RegisterType ; R13 = &04107eb8
S[| : 3845644: PUSH {r0, r4, r5, r6, r7, r8, r9, r11, r12, lr, pc}
S[|| : 3845648: SUB r11, r12, #4 ; R12 = &04107eb8
S[|| : 384564c: SUB sp, sp, #8 ; R13 = &04107e8c
S[||| : 3845650: MOV r1, #0
S[||| : 3845654: STR r1, [sp] ; R1 = &00000000, R13 = &04107e84
S[||| : 3845658: LDR r1, [r0] ; R0 = &04107eb8
S[||| : 384565c: TST r1, #1 ; R1 = &00000004
S[||| : 3845660: MOV r2, #1
S[||| : 3845664: MOVEQ r3, r2 ; R2 = &00000001
S[||| : 3845668: MOVNE r3, #0
S[||| : 384566c: STR r3, [sp, #4] ; R3 = &00000001, R13 = &04107e84
S[||| : 3845670: TST r1, #2 ; R1 = &00000004
S[||| : 3845674: MOVEQ r2, #0
S[||| : 3845678: MOV r9, r2 ; R2 = &00000000
S[||| : 384567c: TEQ r2, #1 ; R2 = &00000000
S[||| : 3845680: LDR r6, [r0, #4] ; R0 = &04107eb8
S[||| : 3845684: MOVNE r5, #0
S[||| : 3845688: LDREQ r5, [r0, #8] ; R0 = &04107eb8
S[||| : 384568c: TST r1, #4 ; R1 = &00000004
S[||| : 3845690: MOVEQ r7, #0
S[||| : 3845694: LDRNE r7, [r0, #&c]! ; R0 = &04107eb8
S[||| : 3845698: TEQ r7, #0 ; R7 = &03848870
S[||| : 384569c: BEQ &038456AC
S[||| : 38456a0: CMP r7, #&8000 ; R7 = &03848870, #32768 = bit 15
S[||| : 38456a4: MOVLO r0, #&11 ; #17
S[||| : 38456a8: BLO &03845A18
S[||| : 38456ac: MOV r8, #0
S[||| : 38456b0: LDR r0, &03844A30 ; = &03847dc8
S[||| : 38456b4: LDR r12, [r10, #-&218] ; R10 = &0410021c
S[||| : 38456b8: ADD r0, r12, r0 ; R12 = &037be7a8, R0 = &03847dc8
S[||| : 38456bc: LDR r4, [r0, #&194]! ; R0 = &07006570
S[||| : 38456c0: B &038456CC
S[||| : 38456cc: TEQ r4, #0 ; R4 = &00000000
S[||| : 38456d0: BEQ &038456E0
S[||| : 38456e0: MOV pc, #0
S[|||| : 3800074: SWI &FEED07 ; Kernel: Default BranchThrough0Handler
Exception: Branch through zero
r0 = &07006704, r1 = &00000004, r2 = &00000000, r3 = &00000001
r4 = &00000000, r5 = &00000000, r6 = &00000005, r7 = &03848870
r8 = &00000000, r9 = &00000000, r10 = &0410021c, r11 = &04107eb4
r12 = &037be7a8, sp = &04107e84, lr = &00000000, pc = &00000000
CPSR= &60000013 : SVC-32 ARM fi ae qvCZn
[ : 380dce4: SWI &FEED07 ; Internal call to env_error

Error: Internal error: Branch through zero (Error number &80000005)
Entering: Ticker event &03842b74/&07003a5c {DA 'ROM', module 'Freeway'}
S[ : 3842b74: PUSH {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, lr}
S[| : 3842b78: MOV r9, #1
S[| : 3842b7c: B &03842B94
S[| : 3842b94: MOV r0, sp ; R13 = &04107f74
S[| : 3842b98: TEQ pc, pc ; R15 = &03842b98, R15 = &03842b98
S[| : 3842b9c: MOVNE r8, pc ; R15 = &03842b9c
S[| : 3842ba0: ORRNE r3, r8, #3 ; R8 = &00000000
S[| : 3842ba4: TEQNEP r3, #0 ; R3 = &00000001
S[| : 3842ba8: MRSEQ r6, apsr
S[| : 3842bac: ORREQ r3, r6, #3 ; R6 = &60000093
S[| : 3842bb0: MSREQ cpsr_c, r3 ; R3 = &60000093
S[| : 3842bb4: MOV r1, r12 ; R12 = &07003a5c
S[| : 3842bb8: MOV r7, lr ; R14 = &04107fa8
S[| : 3842bbc: MOV r10, sp, LSR #20 ; R13 = &04107f74
S[| : 3842bc0: MOV r10, r10, LSL #20 ; R10 = &00000041
S[| : 3842bc4: LDMIA r10, {r4, r5} ; R10 = &04100000
S[| : 3842bc8: LDR r12, [r12] ; R12 = &07003a5c
S[| : 3842bcc: LDMIB r12, {r11, r12} ; R12 = &07006564
S[| : 3842bd0: STMIA r10, {r11, r12} ; R10 = &04100000
S[| : 3842bd4: ADD r10, r10, #&21c ; R10 = &04100000
S[| : 3842bd8: MOV r11, #0
S[| : 3842bdc: ADR lr, &03842BF8 ; -> [&e24aaf87, &e88a0030, &e1a0e007, &e13f000f
]
S[| : 3842be0: ADD pc, pc, r9, LSL #2 ; Table dispatch index #1
S[| : 3842bec: B &03843FA8 ; -> Function: tick_handler
S[| : Function: tick_handler
S[| : r0 = &04107f74, r1 = &07003a5c, r2 = &00000000, r3 = &60000093
S[| : r4 = &037d4c20, r5 = &037be7a8, r6 = &60000093, r7 = &04107fa8
S[| : r8 = &00000000, r9 = &00000001, r10 = &0410021c, r11 = &00000000
S[| : r12 = &037be7a8, sp = &04107f74, lr = &03842bf8, pc = &03843fa8
S[| : CPSR= &60000093 : SVC-32 ARM fI ae qvCZn
S[| : SPSR= &60000092 : IRQ-32 ARM fI ae qvCZn
S[| : 3843fa8: MOV r12, sp ; Function: tick_handler ; R13 = &04107f74
S[| : 3843fac: PUSH {r0, r1, r4, r11, r12, lr, pc}
S[|| : 3843fb0: SUB r11, r12, #4 ; R12 = &04107f74
S[|| : 3843fb4: LDR r0, &03843034 ; = &03847dc8
S[|| : 3843fb8: LDR r12, [r10, #-&218] ; R10 = &0410021c
S[|| : 3843fbc: ADD r0, r12, r0 ; R12 = &037be7a8, R0 = &03847dc8
S[|| : 3843fc0: LDR r4, [r0, #&194]! ; R0 = &07006570
S[|| : 3843fc4: TEQ r4, #0 ; R4 = &00000000
S[|| : 3843fc8: BEQ &03843FE0
S[|| : 3843fe0: MOV r0, #1
S[|| : 3843fe4: LDMDB r11, {r4, r11, sp, pc} ; R11 = &04107f70
S[| : 3842bf8: SUB r10, r10, #&21c ; R10 = &0410021c
S[| : 3842bfc: STMIA r10, {r4, r5} ; R10 = &04100000
S[| : 3842c00: MOV lr, r7 ; R7 = &04107fa8
S[| : 3842c04: TEQ pc, pc ; R15 = &03842c04, R15 = &03842c04
S[| : 3842c08: BEQ &03842C1C
S[| : 3842c1c: MOV r12, r6 ; R6 = &60000093
S[| : 3842c20: MSR cpsr_c, r6 ; R6 = &60000093
S[| : 3842c24: TEQ r0, #0 ; R0 = &00000001
S[| : 3842c28: POP {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, lr}
S[ : 3842c2c: POPEQ {lr}
S[ : 3842c30: MSR apsr_nzcvq, r12 ; R12 = &60000093
S[ : 3842c34: MOV pc, lr ; R14 = &04107fa8
S[ : 4107fa8: SWI &FEED05
Leaving: Ticker event &03842b74/&07003a5c {DA 'ROM', module 'Freeway'}


Let's quickly cover the irrelevant bit of this trace. Because the SWI didn't return normally, the tracing was left enabled, and so after the error is reported we return to the supervisor prompt. At that point the ticker is triggered and we can see the code that Freeway executes on its tick handler. This code is bracketed by 'Entering: Tick event' and 'Leaving: Tick event'. We can ignore this because it's just an artifact of the module running.

Ok, so starting from the top we reinitialise the Freeway module. It then reports that the SWI was entered SWIin, and that it's enabling the tracing of code. Then we see the disassembly of the code as it executes it.

It's a configuration option (one that I enabled in the server configuration) that the left of each line shows an indication of the processor mode and the stack 'level'. The 'S' indicates that we are executing in SVC mode. After the the '[' is an indication of how deeply on the stack we have progressed. Every instruction that increases the stack depth adds a '|' to the stack, and each that reduces it returns the stack to its previous position. This helps see when you were going in and out of subroutines.

The first block of instructions are the module veneers to enter the C code. If you look beside each instruction you'll see that there are comments describing the state of each register which is referenced by the instruction at that time. Eventually we get to the RegisterType function. Each time that a function is entered we display the full register list to make it easier to see the state of the system.

There's a bunch of code in the function before we get to the 'MOV pc, #0' which we injected. However, the important bit is on that TEQ r4, #0. The comment tells us that the value of R4 at that point is actually 0. Which is what we'd inferred from the earlier dump, but now we're actually seeing that this is the value that is being used.

Ok, this example may not be like the problems you'll encounter in the wild, but it's not synthetic. This was a real bug in Freeway. It's preserved here to make it easier to give examples of how you can see what's going on.

When running RISC OS Pyromaniac locally, I would normally only enable limited tracing like the block tracing and redirect all its output to a file. This then allows me to look through the logs in a text editor. It's not uncommon to have 10s or 100s of megabytes of the trace output written out, and to just use the editors search functions to find the interesting bits - although usually it's at the end.

Being able to do this sort of debugging interactively wouldn't be all that hard, but as I hope I've shown, for simple problems it's not necessary.

Sorry, that was rather longwinded, but I hope it gives you a little more of a feel for how you can diagnose problems.

If you want to know a little more about how the tracing can be used, there's some more information in the documentation on the Pyromaniac site - see https://pyromaniac.riscos.online/pyromaniac/TRACE.html for details of the trace system. And see https://pyromaniac.riscos.online/pyromaniac/CONFIGOPTIONS.html#configuration-group-trace for details on the trace configuration.

[Edited by gerph at 20:21, 17/11/2021]
  ^[ Log in to reply ]
 
Mark Stephens Message #125248, posted by markee174 at 08:28, 18/11/2021, in reply to message #125245
Does all the
work around here

Posts: 102
It's Chris Hall's Pi tracking his every move.
  ^[ Log in to reply ]
 
W. P. B. Message #125249, posted by wpb at 13:13, 18/11/2021, in reply to message #125247
Member
Posts: 22
Haha! I ran through that on the shell as you described and it worked perfectly. Wow, that's very impressive and very useful.

My personal interest would be in a debugger for applications running under the Wimp. Like the issue I'm trying to debug at the moment is something to do with my app polling and processing events, so I'd need to thread in and out of task switching code to follow it through exactly, which is probably beyond Pyromaniac at the moment, but nevertheless...I can see how extremely useful this would be as a debugging tool.

Thanks very much for the detailed example above. It was really instructive and quite fascinating!
  ^[ Log in to reply ]
 
Andrew Flegg Message #125250, posted by Jaffa at 13:41, 18/11/2021, in reply to message #125245
Member
Posts: 53

As I think I've said before, I'll make it available if people are interested. Nobody has shown much interest in the cloud service or Pyromaniac, and so if there's no interest, that confidence won't increase, and I won't expend the effort there.
Definitely interested - I've had a brief play with the shell, but it's so good it basically appears like a Supervisor prompt in a browser. I'm more interested in poking around at the underlying code, how it's put together, the boundaries of the kernel & APIs.

The brief snippets of code in the presentation were too tantalising!
  ^[ Log in to reply ]
 
Charles Justin Ferguson Message #125251, posted by gerph at 13:49, 18/11/2021, in reply to message #125250
Member
Posts: 29

As I think I've said before, I'll make it available if people are interested. Nobody has shown much interest in the cloud service or Pyromaniac, and so if there's no interest, that confidence won't increase, and I won't expend the effort there.
Definitely interested - I've had a brief play with the shell, but it's so good it basically appears like a Supervisor prompt in a browser. I'm more interested in poking around at the underlying code, how it's put together, the boundaries of the kernel & APIs.

The brief snippets of code in the presentation were too tantalising!
Drop me a mail and we can talk about how you can access it, if you're interested. There's a number of different mechanisms for using it - and obviously different platforms that it can be used on - depending on the level of interest and expected use. Once we've worked out what will work well for you, I can give you a copy and we can try working through things.
  ^[ Log in to reply ]
 
Charles Justin Ferguson Message #125254, posted by gerph at 18:02, 19/11/2021, in reply to message #125249
Member
Posts: 29
Haha! I ran through that on the shell as you described and it worked perfectly. Wow, that's very impressive and very useful.
Thank you; I'm glad it worked big smile

My personal interest would be in a debugger for applications running under the Wimp. Like the issue I'm trying to debug at the moment is something to do with my app polling and processing events, so I'd need to thread in and out of task switching code to follow it through exactly, which is probably beyond Pyromaniac at the moment, but nevertheless...I can see how extremely useful this would be as a debugging tool.
I think I'll reiterate some of what I said previously in my presentation about software testing, about splitting the application so that you can run the functional bits outside the desktop. Then it's only the application events that you need to worry about translating to the rest of the application. If, as you suggest, the problem is the application events, then it may be possible to record those events and inject them into your application later as part of a test. Then you make the operation reproducible, and you can add debugging output that writes to the file or whatever more easily.

As for Pyromaniac, there'd be quite a bit of work to make it easier to work through a single application. Your comments have given me some ideas but they'll take a bit of time to get the infrastructure in place to make it possible to trace just single applications and the operation in one area easily.

Thanks very much for the detailed example above. It was really instructive and quite fascinating!
Not a problem. I'm glad I could find something that would demonstrate what I'm doing and how it can be used.
  ^[ Log in to reply ]
 
W. P. B. Message #125255, posted by wpb at 19:31, 19/11/2021, in reply to message #125254
Member
Posts: 22
Yeah, it's clear to me that Pyromaniac could be really super useful to both system developers and application developers. The app I'm debugging at the moment isn't (much of) my own code, but I totally take your point about splitting development into functional and UI parts as a bare minimum.

Keep up the great work. I feel this could be a game-changer for RISC OS development in the long run.
  ^[ Log in to reply ]
 

Acorn Arcade forums: News and features: Rougol November talk - RISC OS Pyromaniac update