Hi, I found some dubious looking HTAB cleanup code for replication streams (see file:worker.c, function:stream_cleanup_files).
viz. ---------- static void stream_cleanup_files(Oid subid, TransactionId xid) { char path[MAXPGPATH]; StreamXidHash *ent; /* Remove the xid entry from the stream xid hash */ ent = (StreamXidHash *) hash_search(xidhash, (void *) &xid, HASH_REMOVE, NULL); /* By this time we must have created the transaction entry */ Assert(ent != NULL); /* Delete the change file and release the stream fileset memory */ changes_filename(path, subid, xid); SharedFileSetDeleteAll(ent->stream_fileset); pfree(ent->stream_fileset); ent->stream_fileset = NULL; /* Delete the subxact file and release the memory, if it exist */ if (ent->subxact_fileset) { subxact_filename(path, subid, xid); SharedFileSetDeleteAll(ent->subxact_fileset); pfree(ent->subxact_fileset); ent->subxact_fileset = NULL; } } ---------- Notice how the code calls hash_search(... HASH_REMOVE ...), but then it deferences the same ent that was returned from that function. IIUC that is a violation of the hash_search API, whose function comment (dynahash.c) clearly says not to use the return value in such a way: ---------- * Return value is a pointer to the element found/entered/removed if any, * or NULL if no match was found. (NB: in the case of the REMOVE action, * the result is a dangling pointer that shouldn't be dereferenced!) ---------- ~~ PSA my patch to correct this by firstly doing a HASH_FIND, then only HASH_REMOVE after we've finished using the ent. ---- Kind Regards, Peter Smith. Fujitsu Australia
v1-0001-Fix-for-stream_cleanup_files-HASH_REMOVE.patch
Description: Binary data