mailto: blog -at- heyrick -dot- eu

Anxiety/Panic/Heart attack!

Started work an hour early. Got up at six, went and fed kitty, then took my car key and turned the car on to make sure that I had charged it on Friday. I was sure I had, but, you know... better to check and be able to put 1¼ hours of electrons into it than discover "well, I can get there, but..." and today being the day of an important client visit I couldn't say "I'll be in late once my car is ready". Unnecessary anxiety, but anxiety none the less.

Made breakfast, tea, went back to bed (because for some reason out of nowhere it was like -2°C).

Got up again at seven, got my backpack sorted with what I plan to eat, tea (thermos, for break), more tea (travel mug, I drink it when I get there), everything all ready.

Oh, and since it's Monday on an odd week it's rubbish day. I didn't have anything to put into the bin (the kitchen bin is only half full and I didn't feel like tidying anything over the weekend) so it was only two bags of recycling.

Got everything into the car, sat down and...

Key?

Where the hell is the key?

Looked in the car. Looked by the car. Looked on the kitchen table. Checked pockets of clothes I wasn't even wearing.

I then had to go into crisis mode. That meant dumping the recycling bags into the back hallway, just in case, trying to move as little as possible, and then going to work using the spare that I have on my house-keys-set. I was already "Rick-late", that meant I'd arrive at about ten to, which wasn't late but it didn't leave any time for tea. I drank that on the way.

Oh, and all the way to work while I was desperately trying to remember the last place I saw the key fob, and I was certain I picked it up as I was going out the door, my stupid neurodivergent brain was humming Kylie Minogue's "I Should Be So Lucky" to itself. Humming, because it didn't remember any of the words other than the title (I never cared for that song anyway) but the message was clear and doesn't bear repeating here where I at least attempt to aim for a "Parental Guidance" rating.

 

Got home.

Not on, in, under, or near the kitchen table. Or anywhere around the car or where the car sleeps at night. I walked to Anna and back examining the grass. Then had to do it again because she made such a fuss about her distracted human not paying any attention to her that a pack of Felix and a surreptitious stroke when she was eating was necessary.

Where?

Okay, last ditch. I'm going to have to go through the recycling bags just to be sure. I mean, by this point even outlandish ideas were starting to make sense. Even if it would have taken a minor miracle for me to drop my keys without noticing in such a way that it neatly slides down into the yellow bag. The yellow bag that is pulled tight at the top.
But since I'm lazy, I first picked up the bags and looked at them.

My car key, in the yellow recycling bag!
Dumb fucking luck - h..h..how🙻

PG-13 allows for exactly one utterance of the F word, and that seemed like exactly the right place to put it. ☺

So, despite the ridiculous improbability of it all, my key fob ended up in the recycling bag.

I'm so pleased that even at that early time of the morning I had sufficient tea in my brain to think to hold back the recycling and not put the bags out for collection.
But, then again, maybe if I had slightly less noise in my brain, this wouldn't have happened at all.

 

Tea v0.27

Every once in a blue moon, Tea would crash. I never had time to look into this in the past, because when I built the code with the debugging stuff embedded, it wouldn't crash. Problems like that are a pain, but today I didn't go shopping like I had planned (because car keys) so I had a little extra time. And Thursday was really making Tea blow up.

tea_0-27.zip (4553KiB)
This software is for for RISC OS.

 

What follows next is a deep dive into what was going wrong. If you aren't interested in the nerdy stuff, you can stop reading now...

 

Debugging deep dive

The backtrace was telling me that it was prog_extractday() blowing up.

Because all of the data is all mixed together nowadays, the routine just skips through the file looking for channel IDs until it finds the one we're interested in.

Once it has found that channel, it will begin extracting. Now not all programmes have all the fields - so what I must do first is to work out the boundary so I am only looking at whatever data exists for the current programme.

      // Work out where out boundary is and terminate it
      nextprog = strstr((base + 8), "{\"program_id");
      nextchnl = strstr(base, "{\"service_id");

This looks for "the next programme marker" and "the next channel marker" and whichever one is closest is set as the boundary, and a temporary null terminator is placed at that location.
This allows me to do a simple string search in the data, but won't overshoot to a different programme if the string I'm looking at doesn't exist in this programme.

Aside: I finally worked out where highlight stored its data files to copy the "freya" theme that I had been using to one that looks more like Zap. It isn't perfectly like Zap, maybe needs some tweaks, but it'll do for now. The code looks a lot more like I'm used to seeing it.
So, as long as I remember and I'm writing this on Linux, code snippets in the future will look like these examples.

I dropped a few printfs here, wrapped in calls to VDU4 before and VDU5 after to see what was going on.
It turns out that partway through scanning the data, base (that's the start of the wodge of data we're currently looking at - i.e. "this programme is between base and boundary") suddenly becomes zero, and Tea blows up because it is trying to read from address &00000008. That actually works, my machine doesn't raise a fault, so I was able to see the "ýýýýýýýýýýýý!!!!NULL.POINTER.DEREFERENCE!!!!" message, but things fell apart afterwards because what's in page zero (mostly nulls) isn't what Tea's parser is expecting and so it sulked.

There is nothing in the function that would lead to there being a likely cause of why base was being set to zero. But I do know that function-local variables get placed on the stack and overshooting a string can have peculiar effects.

At the top of the function is some storage for the temporary values read from that wodge of data as it gets parsed into the programme array.

   char progname[64];
   char progdesc[128];
   char progimage[128];
   char progtime[32];
   char progdura[16];

This was the most likely culprit. Something here was overrunning and corrupting something else.

So I added a '1' before each number to give 164, 1128, 1128, 132, and 116 respectively.

And, what do you know, the programme worked.

I removed the '1's, and it crashed. As expected.

I set progname back to 164, and it worked. Well, that was simple and it has given me exactly what I need to track down the problem.

And the problem was this line:

         pullstring(progname, here, 127);

But wait, if this allowing 127 bytes to be written to a bit of memory half that size, why didn't it blow up all the time?

This is because, as far as I can determine, there are no programme names longer than about sixty characters.

Unfortunately, this is only part of the story, because escaping can make the titles be sufficiently short, but actually require more data.

The title that broke Tea on Thursday was "Sleuths, Spies & Sorcerers: Andrew Marr's Paperback Heroes" (early hours, BBC FOUR), which is fifty eight characters (if I remember correctly).
The data, however, was "Sleuths, Spies \u0026 Sorcerers: Andrew Marr\u0027s Paperback Heroes" which is sixty eight bytes, four longer than we have space for. Well, five because of the null terminator, but that's neither here nor there really as too big is too big whatever the reason.

I changed the line to:

         pullstring(progname, here, 63);

Now it works correctly. ☺

 

Of course, this problem is exacerbated by C's lack of bounds checking. If this was a slightly smarter language, it would have said "String too long" or something. Actually, it's maybe also due to C's complete lack of understanding of strings. What we're using is a character array of a defined size that we are pretending is a string. That's why the null at the end, we need to have some way of saying "this is the end of this string". You could, if you wanted, pick something else like 0xFF as the string terminator. Just rewrite all the library string routines to use 0xFF instead and the job is done. Because C doesn't care, it's just a sequence of bytes as far as C is concerned, could be anything in there.

And, of course, this problem is also exacerbated by RISC OS' lack of debugging options. Maybe if I built my program with debugging tables and ran it in DDT it would have shown me the problem. Unfortunately DDT is rather crash prone (just what you need in a debugger), a monumental arse to actually use, and it complains about far too many legitimate things while not offering some useful things. It's just... let's just say it looks and feels and behaves much like it did in the early days of RISC OS 3 (so circa 1992ish). It is its own weird little timewarp, only these days it has the stability of a fancy bone china plate floating atop whipped cream that is perched on top of a jelly (or Jell-O to Americans) that is sitting on a washing machine full of towels about to hit spin cycle. As you might be able to tell, I'm not a fan.

So, for me, it was just quicker - having experience of how memory overshoots corrupt the stack frame and make things go kablooey in interesting ways - wittle down to see what was actually going wrong (the null pointer) and then try various things to work out where it was being triggered, each test narrowing down until there was one line of code I could look at and say "no, that's wrong".

For what it is worth, the bits of code above and below both use 127 (correctly). This was probably just a cutty-pasty oversight that didn't have any observable side effect until it did.

 

 

Your comments:

Please note that while I check this page every so often, I am not able to control what users write; therefore I disclaim all liability for unpleasant and/or infringing and/or defamatory material. Undesired content will be removed as soon as it is noticed. By leaving a comment, you agree not to post material that is illegal or in bad taste, and you should be aware that the time and your IP address are both recorded, should it be necessary to find out who you are. Oh, and don't bother trying to inline HTML. I'm not that stupid! ☺
As of February 2025, commenting is no longer available to UK residents, following the implementation of the vague and overly broad Online Safety Act. You must tick the box below to verify that you are not a UK resident, and you expressly agree if you are in fact a UK resident that you will indemnify me (Richard Murray), as well as the person maintaining my site (Rob O'Donnell), the hosting providers, and so on. It's a shitty law, complain to your MP.
It's not that I don't want to hear from my British friends, it's because your country makes stupid laws.

 
You can now follow comment additions with the comment RSS feed. This is distinct from the b.log RSS feed, so you can subscribe to one or both as you wish.

jgh, 27th January 2026, 04:58
It is reeeeeeeaaallllyyy annoying that work demands that I operate a half-ton death machine hours before I am awake enough to do so in order to remain employed. And if *I* complain, they refuse to employ me and I starve. 
JAD, 27th January 2026, 08:57
sizeof(progname)-1 Needed

Add a comment (v0.12) [help?] . . . try the comment feed!
Your name
Your email (optional)
Validation Are you real? Please type 83774 backwards.
UK resident
Your comment
French flagSpanish flagJapanese flag
Calendar
«   January 2026   »
MonTueWedThuFriSatSun
   23
79
13141517
19202223
282930 

(Felicity? Marte? Find out!)

Last 5 entries

List all b.log entries

Return to the site index

Geekery
 
Alphabetical:

Search

Search Rick's b.log!

PS: Don't try to be clever.
It's a simple substring match.

Etc...

Last read at 06:31 on 2026/02/07.

QR code


Valid HTML 4.01 Transitional
Valid CSS
Valid RSS 2.0

 

© 2026 Rick Murray
This web page is licenced for your personal, private, non-commercial use only. No automated processing by advertising systems is permitted.
RIPA notice: No consent is given for interception of page transmission.

 

Have you noticed the watermarks on pictures?
Next entry - 2026/01/27
Return to top of page