bareos: master 549531e7

Author Committer Branch Timestamp Parent
Sebastian Sura Bareos Bot master 2024-07-11 07:58 master eeb105c6 Pending
Changeset python-fd: fix python crash

Python uses a (Type, Name) -> Object cache for member lookups inside
of types. This cache was shared globally by all interpreters up until
3.10, where it was made to be per-interpreter instead:

```
// typeobject.c
static struct method_cache_entry method_cache[1 << MCACHE_SIZE_EXP];
```

The cache does sanity checking to make sure to only return the correct
answers:
```
        if (method_cache[h].version == type->tp_version_tag &&
            method_cache[h].name == name) {
            method_cache_hits++;
            return method_cache[h].value;
        }
```

but the problem is that this does not correctly work with static
types: Their type id (type->tp_version_tag) is the same for all
interpreters since they all reuse the same type. This means that if
you ask for the same members in two different interpreters and those
member names are allocated *at the same address*, then you will get
the same object pointer back. This object pointer may not belong to
one of those interpreters though and in fact can be a dangling pointer
if the other interpreter was already killed.

This actually happened at a customer when accessing
`datetime.datetime.max` where the `Lookup(datetime, max)` call
actually returned a cached result from a previous interpreter. This
may have to do with string interning (which caused the 'max' name to
have the same address), but it could also have been a pure
coincidence.

Thankfully python offers a (stable api) call to clear the cache. This
bug can be worked around by just calling that function everytime we
destroy an interpreter so that the map never contains dangling
pointers. This obviously does not fix the problem completely but it
should at least fix it for cases where there are no concurrent python
jobs running.

Its possible that there are more suprises like this in the python code
base.
mod - core/src/plugins/filed/python/python-fd.cc Diff File