kernel32: Add a special case to EnumProcessModules for the local process.
LLVM's libunwind uses EnumProcessModules for locating .eh_frame sections when unwinding dwarf exceptions (used on i686). When running wine in docker (without adding custom additional permissions), EnumProcessModules currently fails as it uses ReadProcessMemory, which requires the SYS_PTRACE capability. The current implementation also is slower than necessary (by a couple orders of magnituide), for accessing the current process. Currently, unwinding 10000 exception throws with libunwind on i686 takes 24 seconds when run in wine, while it runs in less than 0.1 second with this patch. Signed-off-by: Martin Storsjo <martin@martin.st> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
fef1d403c5
commit
fbda8db334
|
@ -555,6 +555,40 @@ BOOL WINAPI K32EnumProcessModules(HANDLE process, HMODULE *lphModule,
|
||||||
DWORD size = 0;
|
DWORD size = 0;
|
||||||
INT ret;
|
INT ret;
|
||||||
|
|
||||||
|
if (process == GetCurrentProcess())
|
||||||
|
{
|
||||||
|
PPEB_LDR_DATA ldr_data = NtCurrentTeb()->Peb->LdrData;
|
||||||
|
PLIST_ENTRY head = &ldr_data->InLoadOrderModuleList;
|
||||||
|
PLIST_ENTRY entry = head->Flink;
|
||||||
|
|
||||||
|
if (cb && !lphModule)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_NOACCESS);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
while (entry != head)
|
||||||
|
{
|
||||||
|
PLDR_MODULE table_entry = (PLDR_MODULE)
|
||||||
|
((PBYTE)entry - offsetof(LDR_MODULE, InLoadOrderModuleList));
|
||||||
|
if (cb >= sizeof(HMODULE))
|
||||||
|
{
|
||||||
|
*lphModule++ = table_entry->BaseAddress;
|
||||||
|
cb -= sizeof(HMODULE);
|
||||||
|
}
|
||||||
|
size += sizeof(HMODULE);
|
||||||
|
entry = entry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!needed)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_NOACCESS);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
*needed = size;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (!init_module_iterator(&iter, process))
|
if (!init_module_iterator(&iter, process))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue