finished implementing crash detection

This commit is contained in:
zeffy
2018-03-08 17:51:23 -08:00
parent 093a4f8dc5
commit a6a79e03dc
3 changed files with 60 additions and 54 deletions

View File

@@ -360,10 +360,18 @@ leave:
return result; return result;
} }
void ptrlist_for_each_stdcall(ptrlist_t *list, void(__stdcall *f)(void *)) void ptrlist_for(ptrlist_t *list, size_t index, size_t count, void(__cdecl *f)(void *))
{ {
ptrlist_lock(list); ptrlist_lock(list);
ptrlist_for_stdcall(list, 0, list->count, f); for ( size_t i = index; i < count; i++ )
f(list->values[i]);
ptrlist_unlock(list);
}
void ptrlist_for_each(ptrlist_t *list, void(__cdecl *f)(void *))
{
ptrlist_lock(list);
ptrlist_for(list, 0, list->count, f);
ptrlist_unlock(list); ptrlist_unlock(list);
} }
@@ -375,17 +383,9 @@ void ptrlist_for_stdcall(ptrlist_t *list, size_t index, size_t count, void(__std
ptrlist_unlock(list); ptrlist_unlock(list);
} }
void ptrlist_for_each_cdecl(ptrlist_t *list, void(__cdecl *f)(void *)) void ptrlist_for_each_stdcall(ptrlist_t *list, void(__stdcall *f)(void *))
{ {
ptrlist_lock(list); ptrlist_lock(list);
ptrlist_for_cdecl(list, 0, list->count, f); ptrlist_for_stdcall(list, 0, list->count, f);
ptrlist_unlock(list);
}
void ptrlist_for_cdecl(ptrlist_t *list, size_t index, size_t count, void(__cdecl *f)(void *))
{
ptrlist_lock(list);
for ( size_t i = index; i < count; i++ )
f(list->values[i]);
ptrlist_unlock(list); ptrlist_unlock(list);
} }

View File

@@ -1,7 +1,8 @@
#pragma once #pragma once
#pragma pack(push, 1) #pragma pack(push, 1)
typedef struct ptrlist_t_ { typedef struct ptrlist_t_
{
void **values; void **values;
uint32_t *tags; uint32_t *tags;
size_t capacity; size_t capacity;
@@ -13,10 +14,6 @@ typedef struct ptrlist_t_ {
void ptrlist_lock(ptrlist_t *list); void ptrlist_lock(ptrlist_t *list);
void ptrlist_unlock(ptrlist_t *list); void ptrlist_unlock(ptrlist_t *list);
void ptrlist_for_each_stdcall(ptrlist_t *list, void(__stdcall *f)(void *));
void ptrlist_for_stdcall(ptrlist_t *list, size_t index, size_t count, void(__stdcall *f)(void *));
void ptrlist_for_each_cdecl(ptrlist_t *list, void(__cdecl *f)(void *));
void ptrlist_for_cdecl(ptrlist_t *list, size_t index, size_t count, void(__cdecl *f)(void *));
void *ptrlist_at(ptrlist_t *list, size_t index, uint32_t *pTag); void *ptrlist_at(ptrlist_t *list, size_t index, uint32_t *pTag);
bool ptrlist_create(ptrlist_t *list, size_t capacity, size_t maxCapacity); bool ptrlist_create(ptrlist_t *list, size_t capacity, size_t maxCapacity);
void ptrlist_destroy(ptrlist_t *list); void ptrlist_destroy(ptrlist_t *list);
@@ -34,3 +31,7 @@ bool ptrlist_contains(ptrlist_t *list, void *value);
void **ptrlist_copy_values(ptrlist_t *list, size_t *count); void **ptrlist_copy_values(ptrlist_t *list, size_t *count);
uint32_t *ptrlist_copy_tags(ptrlist_t *list, size_t *count); uint32_t *ptrlist_copy_tags(ptrlist_t *list, size_t *count);
bool ptrlist_copy(ptrlist_t *list, void ***values, uint32_t **tags, size_t *count); bool ptrlist_copy(ptrlist_t *list, void ***values, uint32_t **tags, size_t *count);
void ptrlist_for(ptrlist_t *list, size_t index, size_t count, void(__cdecl *f)(void *));
void ptrlist_for_each(ptrlist_t *list, void(__cdecl *f)(void *));
void ptrlist_for_stdcall(ptrlist_t *list, size_t index, size_t count, void(__stdcall *f)(void *));
void ptrlist_for_each_stdcall(ptrlist_t *list, void(__stdcall *f)(void *));

View File

@@ -28,7 +28,8 @@ void CALLBACK RUNDLL32_StartW(HWND hwnd,
void **values; void **values;
uint32_t *tags; uint32_t *tags;
size_t count; size_t count;
DWORD ret; DWORD e;
DWORD r;
size_t index; size_t index;
size_t crashes = 0; size_t crashes = 0;
@@ -64,33 +65,35 @@ void CALLBACK RUNDLL32_StartW(HWND hwnd,
NotifyBuffer.pfnNotifyCallback = (PFN_SC_NOTIFY_CALLBACK)cb_service_notify; NotifyBuffer.pfnNotifyCallback = (PFN_SC_NOTIFY_CALLBACK)cb_service_notify;
NotifyBuffer.pContext = (PVOID)&list; NotifyBuffer.pContext = (PVOID)&list;
while ( !Unloading && !Lagging ) { while ( !Unloading && !Lagging ) {
switch ( NotifyServiceStatusChangeW(hService, e = NotifyServiceStatusChangeW(hService,
SERVICE_NOTIFY_START_PENDING | SERVICE_NOTIFY_RUNNING, SERVICE_NOTIFY_START_PENDING | SERVICE_NOTIFY_RUNNING,
&NotifyBuffer) ) { &NotifyBuffer);
switch ( e ) {
case ERROR_SUCCESS: case ERROR_SUCCESS:
do {
if ( !ptrlist_copy(&list, &values, &tags, &count) ) { if ( !ptrlist_copy(&list, &values, &tags, &count) ) {
Unloading = true; Unloading = true;
break; break;
} }
ret = WaitForMultipleObjectsEx((DWORD)count, r = WaitForMultipleObjectsEx((DWORD)count,
values, FALSE, INFINITE, TRUE); values, FALSE, INFINITE, TRUE);
if ( ret >= WAIT_OBJECT_0 && ret < WAIT_OBJECT_0 + count ) { if ( r >= WAIT_OBJECT_0 && r < WAIT_OBJECT_0 + count ) {
// object signaled // object signaled
index = ret - WAIT_OBJECT_0; index = r - WAIT_OBJECT_0;
if ( !index ) {
if ( index == 0 ) { // Unload event // Unload event
Unloading = true; Unloading = true;
break; } else {
} else { // crash mutex was closed but the process didn't crash // crash mutex was released cleanly
ptrlist_remove(&list, values[index]); ptrlist_remove(&list, values[index]);
ReleaseMutex(values[index]); ReleaseMutex(values[index]);
CloseHandle(values[index]); CloseHandle(values[index]);
} }
} else if ( ret >= WAIT_ABANDONED_0 && ret < WAIT_ABANDONED_0 + count ) { } else if ( r >= WAIT_ABANDONED_0 && r < WAIT_ABANDONED_0 + count ) {
// object abandoned // object abandoned
// crash mutex was abandoned, process has most likely crashed. // crash mutex was abandoned, process has most likely crashed.
index = ret - WAIT_ABANDONED_0; index = r - WAIT_ABANDONED_0;
ptrlist_remove(&list, values[index]); ptrlist_remove(&list, values[index]);
ReleaseMutex(values[index]); ReleaseMutex(values[index]);
@@ -104,18 +107,20 @@ void CALLBACK RUNDLL32_StartW(HWND hwnd,
trace(L"Crash threshold has been reached, disabling wufuc until next reboot!"); trace(L"Crash threshold has been reached, disabling wufuc until next reboot!");
Unloading = true; Unloading = true;
} }
} else if ( ret == WAIT_FAILED ) { } else if ( r == WAIT_FAILED ) {
trace(L"WTF - Unexpected result from wait function!!!"); trace(L"WTF - Unexpected result from wait function!!!");
Unloading = true; Unloading = true;
} }
free(values); free(values);
free(tags); free(tags);
} while ( r != WAIT_IO_COMPLETION && !Unloading );
break; break;
case ERROR_SERVICE_NOTIFY_CLIENT_LAGGING: case ERROR_SERVICE_NOTIFY_CLIENT_LAGGING:
trace(L"Client lagging!"); trace(L"Client lagging!");
Lagging = true; Lagging = true;
break; break;
default: default:
trace(L"NotifyServiceStatusChange failed, return value: %lu (%08X)", e);
Unloading = true; Unloading = true;
break; break;
} }