x64dbg/GleeBug

Can not use target<> to check if two std::function are equal

czs108 opened this issue · 3 comments

void Thread::StepInto(const StepCallback & cbStep)
{
StepInto();
auto target = cbStep.target<void()>();
for (const auto & cb : stepCallbacks)
{
if (target == cb.target<void()>())
{
puts("duplicate StepInto callback detected!");
return;
}
}
stepCallbacks.push_back(cbStep);
}

I run a test with following code, taget<void()> always return nullptr. So I can't use this to check if two std::function are equal.

#include <vector>
#include <functional>

typedef std::function<void()> StepCallback;

std::vector<StepCallback> stepCallbacks;

void StepInto(const StepCallback& cbStep)
{
	auto target = cbStep.target<void()>();
	for (const auto& cb : stepCallbacks)
	{
                // always get null
		if (target == cb.target<void()>())
		{
			puts("duplicate StepInto callback detected!");
			return;
		}
	}
	stepCallbacks.push_back(cbStep);
}

void fun1() {}

void fun2() {}

int main()
{
	StepInto(fun1);
	StepInto(fun1);
	StepInto(fun2);
	StepInto([]() {});
	StepInto(std::bind([]() {}));
	return 0;
}

output:

duplicate StepInto callback detected!
duplicate StepInto callback detected!
duplicate StepInto callback detected!
duplicate StepInto callback detected!

According to cppreference, the template type of target<> seems very strict. Or there is something wrong with my test?

But if target<> always return nullptr, how can if (target == cb.target<void()>()) check if I push_back the same callback function twice? It is if (nullptr == nullptr) actually.

Probably when this was written for Visual Studio 2013 the standard wasn't followed and everything was working... If you know some other way to check if two std::functions call the same function it would be appreciated.