flak rss random

async dns

curl experimented with using pthread_cancel to timeout async DNS requests and it blew up. What else can we do?

more...

Posted 25 Sep 2025 18:33 by tedu Updated: 25 Sep 2025 18:33
Tagged: c programming

slice tails don't grow forever

In a garbage collected language, one needs to be cautious about leaks caused by errant references, but caution can turn to paranoia. In go, I like to make little fifo queues by appending to the tail of a slice. But does this grow forever?

s = append(s[1:], n)

One theory is that this will eventually consume all memory, as somehow the slice grows and grows. The garbage collector is unable to reduce its size because the head of the slice is still out there somewhere.

Another theory is no, the slice gets reallocated when it needs to expand, but only the referenced section gets copied.

We can test this!

package main

import (
    "fmt"
    "math/rand"
)

func main() {
    var s []int

    grow := false
    for i := 0; i < 10000000000; i++ {
        n := rand.Int()
        if grow || len(s) < 100 {
            s = append(s, n)
        } else {
            s = append(s[1:], n)
        }
    }
    fmt.Printf("%v\n", s)
}

This runs basically forever, but uses very little memory. Changing grow to true, it reliably explodes.

I knew this, and was already relying on it, but also in most cases a slow leak may take weeks to develop and go unnoticed. Thirty seconds to check.

Posted 23 Sep 2025 19:44 by tedu Updated: 23 Sep 2025 19:44
Tagged: go programming

stylish bugs

Whenever a bug is discovered, it’s immediately apparent that three things have gone wrong. They used the wrong language, and this never would have happened if they’d written it in the bugfree language. They used the wrong development methodology, and this never would have happened if they’d used the prevent this bug technique. And finally, they ignored best practice and didn’t use the proper coding style. The bug would have been extremely obvious if only they’d replaced all v_w_ls with underscores in variable names. Just look at the word v_w_ls. It pops right out.

more...

Posted 12 Aug 2025 08:13 by tedu Updated: 12 Aug 2025 08:13
Tagged: programming thoughts

regexp/o

Perl has a regex option /o, which pretends to optimize your code, but actually introduces bugs. Go has been missing out. Until now.

We need regexp of course, but also text/template for interpolation. Add in runtime to get the pc, and we have all the elements for a cache of only once regex.

func Compile(s string, vals any) (*regexp.Regexp, error) {
        cacheMtx.Lock()
        defer cacheMtx.Unlock()
        pc, _, _, _ := runtime.Caller(1)
        k := key{s: s, pc: pc}
        re := cache[k]
        if re != nil {
                return re, nil
        }
        t := template.New("regex")
        t, err := t.Parse(s)
        if err != nil {
                return nil, err
        }
        var sb strings.Builder
        err = t.Execute(&sb, vals)
        if err != nil {
                return nil, err
        }
        re, err = regexp.Compile(sb.String())
        if err != nil {
                return nil, err
        }
        cache[k] = re
        return re, nil
}

type key struct {
        s  string
        pc uintptr
}

var cacheMtx sync.Mutex
var cache = make(map[key]*regexp.Regexp)

And a test program.

func main() {
        fmt.Printf("starting\n")
        inputs := []string{"Apple", "bananas", "42"}
        for i := 0; i < 3; i++ {
                re, err := regexpo.Compile("{{ call .Letters }}", map[string]any{
                        "Letters": func() string {
                                time.Sleep(1 * time.Second)
                                fmt.Printf("substitute\n")
                                return "[a-z]"
                        },
                })
                if err != nil {
                        fmt.Printf("failure: %s\n", err)
                        return
                }
                ok := re.MatchString(inputs[i])
                fmt.Printf("match: %v\n", ok)
        }
        fmt.Printf("done.\n")
}

The substitution is only done once.

Posted 04 Aug 2025 20:18 by tedu Updated: 04 Aug 2025 20:18
Tagged: go programming

writing a little gosh

I had the idea to write a little shell in go. Called gosh, of course. There’s a few people playing with the same theme, but nothing exactly the same.

more...

Posted 30 Jun 2025 16:33 by tedu Updated: 30 Jun 2025 16:33
Tagged: go programming

forbidden secrets of ancient X11 scaling technology revealed

People keep telling me that X11 doesn’t support DPI scaling, or fractional scaling, or multiple monitors, or something. There’s nothing you can do to make it work. I find this surprising. Why doesn’t it work? I figure the best way to find out is try the impossible and see how far we get.

more...

Posted 24 Jun 2025 17:59 by tedu Updated: 24 Jun 2025 17:59
Tagged: programming x11

vulgar gestures

I like to go on the internet and click on links, but some of the links are bad, so then I swipe right to make it go away. The problem is that when I’m running chrome on OpenBSD, the swipe gesture doesn’t seem to work like it does on other platforms. We’re not going to fix it, but we are going to make it work. (Although, I hear the younglings say they swipe right when they like something. Explains a lot, actually.)

more...

Posted 20 Jun 2025 15:37 by tedu Updated: 20 Jun 2025 15:37
Tagged: openbsd programming

slog is aptly named

I used to use the go log package, then I switched to the slog package, and it’s been a bumpy ride.

more...

Posted 13 Jun 2025 08:10 by tedu Updated: 13 Jun 2025 08:10
Tagged: go programming

sometimes the dependencies are useful

I ripped out a dependency and then I found out what it did. I wrote an RSS parser for a very simple project, and then figured, how hard could it be to use in a real feed reader? Well, not very hard, but it was somewhat time consuming, and offers another perspective on using other people’s code.

more...

Posted 26 May 2025 19:47 by tedu Updated: 26 May 2025 19:47
Tagged: programming project

another tale of go.mod bloat

It’s been one year since our previous adventure, so it’s time for another round of guess why that dependency shows up in the tarball. This time we’re looking at honk, an ActivityPub server that’s supposed to be idiosyncratic with minimal dependencies, so you can keep all your attention focused where it’s needed.

more...

Posted 22 May 2025 07:27 by tedu Updated: 22 May 2025 07:27
Tagged: go programming
V
V