Skip to content

get_type_overload may encounter false cache hits if derived instances are GC'd #1922

Closed
@EricCousineau-TRI

Description

@EricCousineau-TRI

Issue description

This is the upstream form of RobotLocomotion/drake#11424 that @BetsyMcPhail root-caused in this discussion: RobotLocomotion/drake#11424 (comment)

High-level overview and proposed solution

Pybind11 caches functions that aren't overloaded in Python to avoid costly Python dictionary lookups.

The non-overload cache is a set which uses (type.ptr, function name) as a key. Once an item is added to the cache, it is never removed.

The bug occurs when a type that has been added to the cache (e.g type = <class 'custom_test.TestCustom.test_deprecated_protected_aliases..OldSystem'>
type.ptr() = 0x2746c58) is destroyed and a new type is created with the exact same pointer (e.g. type = <class 'custom_test.TestCustom.test_leaf_system_overrides..TrivialSystem'>, type.ptr() = 0x2746c58) that should not be in the cache.

The first attempt at fixing the issue was to use self.ptr instead of type.ptr in the cache key. Testing demonstrated that this was not enough to solve the issue.

In the end, removing all associated cached items when an instance is deregistered seems to fix the issue.

She submitted a potential fix for it in our fork here:
RobotLocomotion#32

Reproducible example code

I've done a quick minimal repro based on master @ 12e8774 here:
EricCousineau-TRI@9726086

Extra keyword: garbage collect virtual inheritance polymorphism

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions