InjectionPointRun() acquires InjectionPointLock, looks up the hash entry, and releases the lock:

        LWLockAcquire(InjectionPointLock, LW_SHARED);
        entry_by_name = (InjectionPointEntry *)
                hash_search(InjectionPointHash, name,
                                        HASH_FIND, &found);
        LWLockRelease(InjectionPointLock);

Later, it reads fields from the entry it looked up:

                /* not found in local cache, so load and register */
                snprintf(path, MAXPGPATH, "%s/%s%s", pkglib_path,
                                 entry_by_name->library, DLSUFFIX);

Isn't that a straightforward race condition, if the injection point is detached in between?


Another thing:

I wanted use injection points to inject an error early at backend startup, to write a test case for the scenarios that Jacob point out at https://www.postgresql.org/message-id/CAOYmi%2Bnwvu21mJ4DYKUa98HdfM_KZJi7B1MhyXtnsyOO-PB6Ww%40mail.gmail.com. But I can't do that, because InjectionPointRun() requires a PGPROC entry, because it uses an LWLock. That also makes it impossible to use injection points in the postmaster. Any chance we could allow injection points to be triggered without a PGPROC entry? Could we use a simple spinlock instead? With a fast path for the case that no injection points are attached or something?

--
Heikki Linnakangas
Neon (https://neon.tech)


Reply via email to