Skip to content

Usage of static data in empty_default_table causes issues across modules #43

Description

@amzeratul

These two pieces of code cause issues when the flat_hash_map is used across modules (e.g. being shared between a DLL and the executable, which is a common use case for me):

    static sherwood_v3_entry * empty_default_table()
    {
        static sherwood_v3_entry result[min_lookups] = { {}, {}, {}, {special_end_value} };
        return result;
    }
    void deallocate_data(EntryPointer begin, size_t num_slots_minus_one, int8_t max_lookups)
    {
        if (begin != Entry::empty_default_table())
        {
            AllocatorTraits::deallocate(*this, begin, num_slots_minus_one + max_lookups + 1);
        }
    }

This is because each module will have its own static empty default table, which will cause an issue with deallocation, corrupting the heap.

I assume there are other pathological cases, e.g. two threads could initialize that static at the same time, resulting in two hashtables with different defaults and eventually leading to a heap corruption.

I have successfully worked around the issue by tagging the first sherwood_v3_entry with a flag indicating its the default table, and checking for that instead, however this will cost one byte if T has alignment of 1 byte (otherwise it should occupy the padding space anyway). There might be a better solution, but I'm not familiar enough with the code to find it!

Here's a link to my changes on my own repo if they're of any use.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions