사용자 클라이언트 응용 프로그램이 실행되고 있지 않을 때 사용자 클라이언트 클래스 인스턴스가있는 경우 사용자 클라이언트 인스턴스를 해제하는 것보다 더 자주 사용자 클라이언트 인스턴스를 유지해야합니다. 예를 들어 주 드라이버 클래스의 클라이언트 인스턴스에 대한 참조를 유지할 수 있습니다. 사용자 클라이언트 클래스의 stop()
메소드에서 해당 클라이언트 인스턴스를 드라이버에서 제거하십시오.
주의해야 할 또 다른 사항 : stop()
, free()
등의 내장 IOService 메소드의 재정의 된 버전에서 수퍼 클래스 구현을 호출해야합니다. 그렇게하지 않으면 일반적으로 IO Kit가 일관성없는 상태가됩니다. 정의이 코드에서
void MyClass::taggedRetain(const void* tag) const
{
OSReportWithBacktrace(
"MyClass" CLASS_OBJECT_FORMAT_STRING "::taggedRetain(tag=%p)\n", CLASS_OBJECT_FORMAT(this), tag);
IOService::taggedRetain(tag);
}
void MyClass::taggedRelease(const void * tag) const
{
OSReportWithBacktrace(
"MyClass" CLASS_OBJECT_FORMAT_STRING "::taggedRelease(tag=%p)\n", CLASS_OBJECT_FORMAT(this), tag);
int count = getRetainCount();
IOService::taggedRelease(tag);
if (count == 1)
printf(
"MyClass::taggedRelease(tag=%p) final done\n", tag);
else
printf(
"MyClass" CLASS_OBJECT_FORMAT_STRING "::taggedRelease(tag=%p) done\n", CLASS_OBJECT_FORMAT(this), tag);
}
매크로 :
마지막으로, 디버깅을위한 유용한 기술은 I/O 키트 드라이버의 누수를 유지, 실제로는 유지 해제 로깅 버전과 방법을 재정 의하여 기록하는 것입니다 헤더에 다음과 같이
#define CLASS_OBJECT_FORMAT_STRING "[%[email protected]%p:%dx]"
#define CLASS_OBJECT_FORMAT(obj) myClassName(obj), obj, myRefCount(obj)
inline int myRefCount(const OSObject* obj)
{
return obj ? obj->getRetainCount() : 0;
}
inline const char* myClassName(const OSObject* obj)
{
if (!obj) return "(null)";
return obj->getMetaClass()->getClassName();
}
#endif
나는 taggedRetain()
과 taggedRelease()
이 retain()
및 release()
의 실제 기본이되는 구현 있음을 설명해야 - 당신이를 오버라이드 (override)하는 경우 위도 그렇지 않으면 태그가없는 버전 (null이 아닌 태그 포함)을 사용하기 때문에 OSCollection에서 유지 및 릴리스가 표시되지 않습니다.
OSReportWithBacktrace()
에 의해 생성 된 백 트레이스는 불행히도 16 진수 포인터의 무리이지만, gdb를 사용하여 볼 수 있습니다.
어떤 경우에도 개체의 보관 및 릴리스를 로깅하여 모든 보관 항목을 검토하고 올바른 위치의 릴리스와 일치하는지 확인할 수 있습니다. 사이클을주의하십시오!
이와 같은 자세한 답변을 보내 주셔서 감사합니다. 사용자 클라이언트의 누출을 발견했을 수도 있습니다 (IOService가 애플리케이션에 의해 해제되지 않음). 그러나, 나는 여전히'detach()'이후에'free()'에 대한 호출을 얻지 못했기 때문에 발생하는 것으로 보이는 드라이버 클래스 자체의 누출을 얻고 있습니다. 장치를 연결하고 userspace 응용 프로그램을 열지 않고 다시 제거하면 무료로 전화를 받지만 사용자 클라이언트가 열리면 결국에는 무료로 전화를받지 않습니다. 무엇이 그 원인이 될 수 있습니까? – Inductiveload
예,'free()'가 호출되지 않고 항상'release()'가 누락되어 있기 때문에 그 원인은 분명하지 않습니다. 사용자 클라이언트 객체가 공급자를 제공하는 경우 공급자가 해당 공급자를 해제해야합니다. 그게 문제가 아니라면,'terminate()'이 주 객체에서 호출되는 것입니까? 'registerService()'는'terminate()'에 의해서만 해제 된 참조를 추가하는 것처럼 보입니다. – pmdj
'terminate()'는 잘못되었을 때 호출되는 것처럼 보이지 않습니다 - 일반적으로이 함수는 무엇을 호출할까요? 그리고 다른 함수가 호출하지 않았던 이유를 알아야합니까? 어딘가에? – Inductiveload