"
I already made a post with this but maybe it's better to put it here too. I hope GGG will fix this issue because it''s pretty annoying :(
I was able to generate a crashdump and this is much how the stacktrace looks like right before the exception occurs:
"
# 27 Id: 1ac.395c Suspend: 1 Teb: 000000c9`ed546000 Unfrozen
# Child-SP RetAddr Call Site
00 000000c9`fd5fbd08 00007ff6`622ac207 PathOfExileSteam+0xd7636
01 000000c9`fd5fbd10 00007ff6`622a27e0 PathOfExileSteam+0x235c207
02 000000c9`fd5fbd80 00007ff6`6237cfb8 PathOfExileSteam+0x23527e0
03 000000c9`fd5fbdb0 00007ff6`622a2740 PathOfExileSteam+0x242cfb8
04 000000c9`fd5fbde0 00007ff6`6229965e PathOfExileSteam+0x2352740
05 000000c9`fd5fbe10 00007ffb`8ca03846 PathOfExileSteam+0x234965e
06 000000c9`fd5fbee0 00007ff6`60bade19 ntdll!RcConsolidateFrames+0x6
07 000000c9`fd5ffaf0 00007ffb`8be1e8d7 PathOfExileSteam+0xc5de19
08 000000c9`fd5ffb50 00007ffb`8c9bfbcc KERNEL32!BaseThreadInitThunk+0x17
09 000000c9`fd5ffb80 00000000`00000000 ntdll!RtlUserThreadStart+0x2c
this is pretty much the code that generates the thread that produces the hang:
"
text:0000000140C5B723 mov rax, gs:58h
.text:0000000140C5B72C mov ecx, 13Ch
.text:0000000140C5B731 mov rax, [rax]
.text:0000000140C5B734 mov byte ptr [rsp+0A8h+dwCreationFlags], 1
.text:0000000140C5B739 xor r9d, r9d
.text:0000000140C5B73C mov edx, 28h ; '('
.text:0000000140C5B741 mov r8d, 10h
.text:0000000140C5B747 movzx ecx, word ptr [rcx+rax]
.text:0000000140C5B74B call sub_140C5F1A0
.text:0000000140C5B750 mov rbx, rax
.text:0000000140C5B753 mov [rsp+0A8h+arg_0], rax
.text:0000000140C5B75B test rax, rax
.text:0000000140C5B75E jz short loc_140C5B7AC
.text:0000000140C5B760 mov byte ptr [rax], 0
.text:0000000140C5B763 mov [rax+8], r14
.text:0000000140C5B767 lea rax, sub_140C5B580
.text:0000000140C5B76E mov [rbx+10h], rax
.text:0000000140C5B772 mov [rbx+18h], rdi
.text:0000000140C5B776 mov dword ptr [rbx+20h], 80000h
.text:0000000140C5B77D mov eax, r14d
.text:0000000140C5B780 xchg al, [rbx]
.text:0000000140C5B782 mov edx, [rbx+20h] ; dwStackSize
.text:0000000140C5B785 mov [rsp+0A8h+lpThreadId], r14 ; lpThreadId
.text:0000000140C5B78A mov [rsp+0A8h+dwCreationFlags], r14d ; dwCreationFlags
.text:0000000140C5B78F mov r9, rbx ; lpParameter
.text:0000000140C5B792 lea r8, sub_140C5DE10 ; lpStartAddress
.text:0000000140C5B799 xor ecx, ecx ; lpThreadAttributes
.text:0000000140C5B79B call cs:CreateThread
.text:0000000140C5B7A1 mov [rbx+8], rax
.text:0000000140C5B7A5 test rax, rax
.text:0000000140C5B7A8 jz short loc_140C5B806
.text:0000000140C5B7AA jmp short loc_140C5B7AF
Judging by
text:0000000140C5B723 mov rax, gs:58h
it seems that is something about TLS data. Since on x64 [gs:58h] holds the Linear address of the thread-local storage array.
Judging by this code:
"
.text:0000000140C5B701 loc_140C5B701: ; CODE XREF: sub_140C5B690+5E↑j
.text:0000000140C5B701 cmp dword ptr [rdi+20h], 0
.text:0000000140C5B705 jnz short loc_140C5B723
.text:0000000140C5B707 cmp dword ptr [rdi+28h], 0
.text:0000000140C5B70B jnz short loc_140C5B723
.text:0000000140C5B70D call cs:GetCurrentThread
.text:0000000140C5B713 xor edx, edx ; nPriority
.text:0000000140C5B715 mov rcx, rax ; hThread
.text:0000000140C5B718 call cs:SetThreadPriority
.text:0000000140C5B71E jmp loc_140C5B7D5
.text:0000000140C5B723 ; ---------------------------------------------------------------------------
.text:0000000140C5B723
.text:0000000140C5B723 loc_140C5B723: ; CODE XREF: sub_140C5B690+75↑j
.text:0000000140C5B723 ; sub_140C5B690+7B↑j
.text:0000000140C5B723 mov rax, gs:58h
.text:0000000140C5B72C mov ecx, 13Ch
.text:0000000140C5B731 mov rax, [rax]
the code that generates the hang it's happening only if [rdi+0x20] or [rdi+0x28] is not 0. Since rdi comes from rcx, it means that rdi is the first parameter passed to this function.
the C code for this function looks something like this:
"
int __fastcall sub_140C5B690(__int64 a1, __int64 a2, __int64 a3)
{
__int64 (__fastcall ***v5)(_QWORD, _BYTE *); // rcx
_BYTE *v6; // rdx
HANDLE CurrentThread; // rax
_QWORD *Thread; // rax
__int64 v9; // rdx
_QWORD *v10; // rbx
__int64 v11; // rbp
void *v12; // rcx
__int64 v13; // rcx
_BYTE pExceptionObject[24]; // [rsp+30h] [rbp-78h] BYREF
_BYTE v16[56]; // [rsp+48h] [rbp-60h] BYREF
_BYTE *v17; // [rsp+80h] [rbp-28h]
*(_QWORD *)(a1 + 56) = a2;
v17 = 0LL;
v5 = *(__int64 (__fastcall ****)(_QWORD, _BYTE *))(a3 + 56);
if ( v5 )
v17 = (_BYTE *)(**v5)(v5, v16);
sub_140103A40(v16, a1 + 64);
if ( v17 )
{
v6 = v16;
LOBYTE(v6) = v17 != v16;
(*(void (__fastcall **)(_BYTE *, _BYTE *))(*(_QWORD *)v17 + 32LL))(v17, v6);
}
if ( *(_DWORD *)(a1 + 32) || *(_DWORD *)(a1 + 40) )
{
Thread = (_QWORD *)sub_140C5F1A0(
*(unsigned __int16 *)(*(_QWORD *)NtCurrentTeb()->ThreadLocalStoragePointer + 0x13CLL),
40,
16,
0,
1);
v10 = Thread;
if ( Thread )
{
*(_BYTE *)Thread = 0;
......... snip ...........
I found only one call to this function in the main executable and the assembly code looks like this (sub_140C5BA30) :
"
.text:0000000140C5BE16 mov rdx, r12
.text:0000000140C5BE19 mov rcx, rbx
.text:0000000140C5BE19 ; } // starts at 140C5BD78
.text:0000000140C5BE1C call sub_140C5B690 <------ this is the call
.text:0000000140C5BE21 sub rbx, 0FFFFFFFFFFFFFF80h
.text:0000000140C5BE25 cmp rbx, rsi
.text:0000000140C5BE28 jnz short loc_140C5BDE0
and the function making this call is a function that has a variable numbers of arguments.
This is just a snippet in C just to help you identify the code:
"
v12 = "IDLE";
if ( a2 )
{
switch ( a2 )
{
case 1:
v13 = "MEDIUM";
break;
case 2:
v13 = "LOW";
break;
case 3:
v13 = "IDLE";
break;
default:
sub_1400CF8A0(&pExceptionObject, "Invalid job type");
CxxThrowException(&pExceptionObject, (_ThrowInfo *)&stru_142E85530);
}
Seems to be a problem with the first parameter. Also seems that in the main executable there is only one call to sub_140C5BA30
"
.text:0000000140C5C62D call sub_140C5BA30
.text:0000000140C5C632 add r14d, ebx
.text:0000000140C5C635 inc edi
.text:0000000140C5C637 cmp edi, 4
.text:0000000140C5C63A jb loc_140C5C580
.text:0000000140C5C640 mov byte ptr [rsi+48Ch], 1
.text:0000000140C5C647 lea r11, [rsp+170h+var_10]
.text:0000000140C5C64F mov rbx, [r11+20h]
.text:0000000140C5C653 mov rsi, [r11+30h]
.text:0000000140C5C657 mov rsp, r11
.text:0000000140C5C65A pop r14
.text:0000000140C5C65C pop rdi
.text:0000000140C5C65D pop rbp
.text:0000000140C5C65E retn
and this looks like a catch block. Also judging by the strings looks like a function that creates some kind of jobs
"
sub_14010ABD0(&v15, L"[JOB] Start");
and if i go in frame further on the calling stack i saw some more strings like :
"
v9 = sub_14010ABD0(&v236, L"[ENGINE] Cache directory: ");
v12 = sub_14010ABD0(&v236, L"[ENGINE] Download directory: ");
v16 = sub_14010ABD0(&v236, L"[ENGINE] Settings directory: ");
and after that there is a call to the functions i've posted above:
"
if ( *(_BYTE *)(a2 + 489) )
{
v23 = sub_140C5CA20();
sub_140C5C430(*(_QWORD *)(v23 + 8));
}
I hope it helps you investigate the issue. I will try to analyze further when i have some time
+1, thanks for taking the time to do this! Hopefully devs actually read their forum and see this, in either case, appreciate you putting in the work for the rest of us.
|
Posted bybigc00p#4350on Jan 27, 2025, 5:27:26 PM
|
"
It would be great if GGG could implement an automatic enable/disable function for Engine Multithreading in the options or as a startup command. This would disable CPU multithreading before the loading screen and re-enable it afterward, eliminating the need for manual intervention.
While manually doing it works fine, it's easy to forget, and when that happens, the game freezes, even with tools like poeuncrasher.
Sorry, best we can do is beg for players to enable logs 30 days after launch.
|
Posted byDremeru#4955on Jan 27, 2025, 5:31:32 PM
|
I hope so too. Unfortunately I just had like half an hour to investigate it. I'll try to investigate it further in a couple of days when i might have some time.
I'll leave a link to my post just to keep it cleaner in case some dev wants to see all the details without that many replies.
If i will have more info i will post it there but also here.
My post: https://www.pathofexile.com/forum/view-thread/3708527
|
Posted byIceCool10#6669on Jan 27, 2025, 5:33:58 PM
|
"
"
.text:0000000140C5B782 mov edx, [rbx+20h] ; dwStackSize
.text:0000000140C5B785 mov [rsp+0A8h+lpThreadId], r14 ; lpThreadId
.text:0000000140C5B78A mov [rsp+0A8h+dwCreationFlags], r14d ; dwCreationFlags
.text:0000000140C5B78F mov r9, rbx ; lpParameter
.text:0000000140C5B792 lea r8, sub_140C5DE10 ; lpStartAddress
.text:0000000140C5B799 xor ecx, ecx ; lpThreadAttributes
.text:0000000140C5B79B call cs:CreateThread
Interesting what's happening there at sub_140C5DE10.
Also I suggest to replace some parts of the code with NOPs (it's 90h) to disable functionality. Sure it will break the normal flow but at least we could try to detect the exact procedure that generates the freeze.
PS Does the freeze occur before CreateThread() call?
No. The freeze occur in that thread that is created. But most of the code is just code that tries to unwind and treat the exception. I was thinking about replacing some code with NOPs but when the exception occurs you mostly see the code that generates the exception. Some ideas came to my mind but it's a time consuming process to "guesstimate" with nops.
I will try some of the ideas in a couple of days and if I find anything I will post it here
My intuition tells me that replacing some code with NOPs it will generate some nasty crashes or bugs until you find the exact code that generates the hang.
Last edited by IceCool10#6669 on Jan 27, 2025, 5:49:18 PM
|
Posted byIceCool10#6669on Jan 27, 2025, 5:47:12 PM
|
"
"
"
.text:0000000140C5B782 mov edx, [rbx+20h] ; dwStackSize
.text:0000000140C5B785 mov [rsp+0A8h+lpThreadId], r14 ; lpThreadId
.text:0000000140C5B78A mov [rsp+0A8h+dwCreationFlags], r14d ; dwCreationFlags
.text:0000000140C5B78F mov r9, rbx ; lpParameter
.text:0000000140C5B792 lea r8, sub_140C5DE10 ; lpStartAddress
.text:0000000140C5B799 xor ecx, ecx ; lpThreadAttributes
.text:0000000140C5B79B call cs:CreateThread
Interesting what's happening there at sub_140C5DE10.
Also I suggest to replace some parts of the code with NOPs (it's 90h) to disable functionality. Sure it will break the normal flow but at least we could try to detect the exact procedure that generates the freeze.
PS Does the freeze occur before CreateThread() call?
No. The freeze occur in that thread that is created. But most of the code is just code that tries to unwind and treat the exception. I was thinking about replacing some code with NOPs but when the exception occurs you mostly see the code that generates the exception. Some ideas came to my mind but it's a time consuming process to "guesstimate" with nops.
I will try some of the ideas in a couple of days and if I find anything I will post it here
I'd recommend against that. You're now in the territory of modifying game client code, and in a trivially detectable way if there is an anti-cheat that looks for it. I don't know whether you actually _would_ get banned for it, but it's certainly a bannable thing.
|
Posted byKapps#5390on Jan 27, 2025, 5:49:35 PM
|
Hi.
Same issue as guys above. Win 11. Ryzen 9800x3d, 4070 TI Super.
Not able to play the game as loading screens freeze randomly. Only way to go foward is to restart PC. I understand that there might be issues with game in its current state but for gods sake GGG give us some details.
|
Posted bySramzes#2778on Jan 27, 2025, 5:52:03 PM
|
"
I'd recommend against that. You're now in the territory of modifying game client code, and in a trivially detectable way if there is an anti-cheat that looks for it. I don't know whether you actually _would_ get banned for it, but it's certainly a bannable thing.
I know. I will think about it. Tbh, my post should give some leads for the devs. I just hope they read this forum and work on a fix.
|
Posted byIceCool10#6669on Jan 27, 2025, 5:57:15 PM
|
Just spit-balling here. I'm not a developer, but I work in architecture.
Isn't this the type of thing you'd see if the marriage between the local code and a needed insert from a remote resource were backed up and there was no specific wait condition present on the local side?
I noticed each time I crash a specific API call is made. To what exactly, i don't know, but... lets say its a webserver (apache maybe).
1. API call is made when the attempt to load a new zone (or something similar) goes off.
2. Local running client tries to insert the needed info but can't because either the webserver call timed out or took too long and the insert doesn't happen (or happens improperly)
3. Race condition on the local machine causing it to ramp the resource requirements up.
4. Local host locks up.
GGG, maybe check your webserver logs and see if you can correlate the crashes to timeouts. From a client code perspective, I wouldn't know exactly what to do, but maybe a resource throttle or kick-out if the response is bad/missing/timed out instead of just constantly retrying.
|
Posted bylemcmurr#2699on Jan 27, 2025, 6:12:05 PM
|
Currently cant play the game anymore due to the game constantly completely freezing my PC in load screens and then having to force turn off my PC.
I also just constantly crash when playing the game.
Not coming back until this is fixed.
IGN: Elem_Mental
Lets all drink red bull jump out of a plane and hope for the best.
|
Posted byThe_Rain_Man#2616on Jan 27, 2025, 6:54:45 PM
|
bruh this has been going on for too long. You would think this many pages in 2 posts would get their attention but no. They really think minor hotfixes is the way to go
|
Posted bydoodbropls#5097on Jan 27, 2025, 7:31:31 PM
|