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;
}
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_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);
}
@@ -375,17 +383,9 @@ void ptrlist_for_stdcall(ptrlist_t *list, size_t index, size_t count, void(__std
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_for_cdecl(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_for_stdcall(list, 0, list->count, f);
ptrlist_unlock(list);
}

View File

@@ -1,7 +1,8 @@
#pragma once
#pragma pack(push, 1)
typedef struct ptrlist_t_ {
typedef struct ptrlist_t_
{
void **values;
uint32_t *tags;
size_t capacity;
@@ -13,10 +14,6 @@ typedef struct ptrlist_t_ {
void ptrlist_lock(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);
bool ptrlist_create(ptrlist_t *list, size_t capacity, size_t maxCapacity);
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);
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);
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;
uint32_t *tags;
size_t count;
DWORD ret;
DWORD e;
DWORD r;
size_t index;
size_t crashes = 0;
@@ -64,33 +65,35 @@ void CALLBACK RUNDLL32_StartW(HWND hwnd,
NotifyBuffer.pfnNotifyCallback = (PFN_SC_NOTIFY_CALLBACK)cb_service_notify;
NotifyBuffer.pContext = (PVOID)&list;
while ( !Unloading && !Lagging ) {
switch ( NotifyServiceStatusChangeW(hService,
e = NotifyServiceStatusChangeW(hService,
SERVICE_NOTIFY_START_PENDING | SERVICE_NOTIFY_RUNNING,
&NotifyBuffer) ) {
&NotifyBuffer);
switch ( e ) {
case ERROR_SUCCESS:
do {
if ( !ptrlist_copy(&list, &values, &tags, &count) ) {
Unloading = true;
break;
}
ret = WaitForMultipleObjectsEx((DWORD)count,
r = WaitForMultipleObjectsEx((DWORD)count,
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
index = ret - WAIT_OBJECT_0;
if ( index == 0 ) { // Unload event
index = r - WAIT_OBJECT_0;
if ( !index ) {
// Unload event
Unloading = true;
break;
} else { // crash mutex was closed but the process didn't crash
} else {
// crash mutex was released cleanly
ptrlist_remove(&list, values[index]);
ReleaseMutex(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
// crash mutex was abandoned, process has most likely crashed.
index = ret - WAIT_ABANDONED_0;
index = r - WAIT_ABANDONED_0;
ptrlist_remove(&list, 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!");
Unloading = true;
}
} else if ( ret == WAIT_FAILED ) {
} else if ( r == WAIT_FAILED ) {
trace(L"WTF - Unexpected result from wait function!!!");
Unloading = true;
}
free(values);
free(tags);
} while ( r != WAIT_IO_COMPLETION && !Unloading );
break;
case ERROR_SERVICE_NOTIFY_CLIENT_LAGGING:
trace(L"Client lagging!");
Lagging = true;
break;
default:
trace(L"NotifyServiceStatusChange failed, return value: %lu (%08X)", e);
Unloading = true;
break;
}