Note that generally these "leaks" are not really leaks, because we
set up the board and wire IRQs together once, and they remain
that way for the lifetime of QEMU and are freed automatically
when QEMU exits.


Unfortunately they are really leaks. As I said qemu_allocate_irqs
allocates two chunks of memory, not one. This is what happening.
qemu_allocate_irqs calls qemu_extend_irqs which starts allocating memory:
(old is NULL and n_old is 0 here)

    s = old ? g_renew(qemu_irq, old, n + n_old) : g_new(qemu_irq, n);
    p = old ? g_renew(struct IRQState, s[0], n + n_old) :
                g_new(struct IRQState, n);

We'll call the first chunk S, and the second P. I have capitalized
letters to avoid confusion with variable names. Chunk P indeed will
be wired, but chunk S will be leaked.

What happens next:

    for (i = 0; i < n + n_old; i++) {
        if (i >= n_old) {
            p->handler = handler;
            p->opaque = opaque;
            p->n = i;
        }
        s[i] = p;
        p++;
    }

Now chunk S has pointers to chunk P stored in it.

After that s (a pointer to chunk S) is returned to the caller.

    return s;

Let's have a look at the caller. Suppose it was omap2420_mpu_init.
Here is the code:

    s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];

qemu_allocate_irqs returned pointer to chunk S. It got immediately
dereferenced. Result of this dereference - a pointer to P - is written
to s->wakeup. But all pointers to chunk S are lost. We have a memory leak.

And something like this happens every time qemu_allocate_irqs is called.

--
Kirill

Reply via email to