I stumbled upon this issue, where UBSan complains about calling a member function of a derived class through a supposedly invalid pointer - yet I am unable to see why it should be invalid.
I have broken down my code to the following snippet, which you can also examine here in a live version.
struct Base {
virtual ~Base() {
for(auto& t : ts) {
t.join();
}
}
template<typename F>
void Spawn(F&& f) {
ts.emplace_back(std::forward<F>(f));
}
std::vector<std::thread> ts;
};
struct Foo : public Base {
Foo() { }
void Start() {
Spawn([this] { Member(); /* HERE */ });
}
void Member() { }
};
int main() {
Foo f;
f.Start();
}
Basically, what I am doing is the following:
- Create a lambda, which captures the
this
pointer of the current derived classFoo
- Spawn a thread which is stored in the respective base class
Base
- Call the lambda from the thread
- Call a member function from the lambda
UBSan complains as soon as a member of Foo
is accessed by the captured pointer within the lambda (output from the live example):
prog.cc:31:52: runtime error: member call on address 0x7ffc50687018 which does not point to an object of type 'Foo'
0x7ffc50687018: note: object is of type 'Base'
00 00 00 00 48 b5 44 00 00 00 00 00 e0 c6 ce 01 00 00 00 00 e8 c6 ce 01 00 00 00 00 e8 c6 ce 01
^~~~~~~~~~~~~~~~~~~~~~~
vptr for 'Base'
What am I missing here?
Aucun commentaire:
Enregistrer un commentaire