mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-04-24 21:56:10 +03:00
[GH-ISSUE #3854] Tony Hawk's Underground 2 Remix - randomly crash ingame (previously also gfx issues) #1581
Labels
No labels
Atrac3+
Audio
CPU emulation
D3D11
D3D9 (removed)
Depth / Z
Feature Request
Font Atlas
GE emulation
Guardband / Range Culling
HLE/Kernel
I/O
Input/Controller
MP3
Multithreading
Needs hardware testing
Networking/adhoc/infrastructure
No Feedback / Outdated?
OpenGL
PGF / sceFont
PSMF / MPEG
Platform-specific (Android)
Platform-specific (Windows)
Platform-specific (iOS)
PowerVR GPU
SDL2
Saving issue
User Interface
Vulkan
arm64jit
armjit
armv6
x86jit
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/ppsspp#1581
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @Superearth958 on GitHub (Sep 20, 2013).
Original GitHub issue: https://github.com/hrydgard/ppsspp/issues/3854
It never worked well.
Intros stopped working since v0.8.1-997.
Game randomy crashes ingame.
Graphic issue in menu :

And ingame :

I tested it again with v0.9.1-1073 it's still the same.
Log : http://pastebin.com/rqwabL2H
@dbz400 commented on GitHub (Sep 21, 2013):
Humm , just view on youtube for actual PSP rendering .

@dbz400 commented on GitHub (Sep 21, 2013):
Funny thing .If i save state , the background appear again ?
@unknownbrackets commented on GitHub (Sep 21, 2013):
So that means that we have a framebuffer but a block transfer or memory write wrote to it, probably.
-[Unknown]
@dbz400 commented on GitHub (Sep 21, 2013):
Humm yes , it is block transfer
43:27:309 idle0 I[HLE]: GLES\GLES_GPU.cpp:985 Block Transfer
43:27:343 idle0 I[HLE]: GLES\GLES_GPU.cpp:985 Block Transfer
43:27:376 idle0 I[HLE]: GLES\GLES_GPU.cpp:985 Block Transfer
43:27:409 idle0 I[HLE]: GLES\GLES_GPU.cpp:985 Block Transfer
@unknownbrackets commented on GitHub (Sep 21, 2013):
So then this is probably similar to #3515, unless the block transfer is from outside a framebuffer but that's basically the same class of issue.
-[Unknown]
@dbz400 commented on GitHub (Sep 21, 2013):
I see. I did try to comment out the blocktransfer and savestate to see what happen , looks like the block transfer is used for the character only but not the background
@dbz400 commented on GitHub (Sep 22, 2013):
Just for record .The intro CG has been fixed .However in-game still bit mess up in graphics
@dbz400 commented on GitHub (Oct 11, 2013):
Just tried to savestate in latest build here , the background now cannot reproduce now .
@unknownbrackets commented on GitHub (Oct 28, 2013):
How are the graphics now?
-[Unknown]
@dbz400 commented on GitHub (Oct 28, 2013):
Confirmed it is still same issue as previous.
@hrydgard commented on GitHub (Dec 10, 2013):
Graphics fixed (well, still has polygon cracks which appear to be from a slight mismatch between s16 and float coordinates and some flickering textures which I think have a similar cause).
However, still pretty unstable.
@dbz400 commented on GitHub (Dec 10, 2013):
Thanks .It is pretty unstable indeed. It sometimes foce to close it.
@dbz400 commented on GitHub (Dec 10, 2013):
Flickering texture is caused by HW T&L
@hrydgard commented on GitHub (Dec 10, 2013):
Yeah, I think there's a difference between how the PSP and OpenGL interprets s16 format coordinates. On software T&L we convert them to float ourselves, avoiding the problem. Should be reasonably simple to compensate for the difference.
@dbz400 commented on GitHub (Dec 10, 2013):
That's good .I think would also fix multiple similar issue observer in many other games that i observed with same behaviour
@hrydgard commented on GitHub (Dec 10, 2013):
Seems stable with interpreter though.
@unknownbrackets commented on GitHub (Dec 10, 2013):
You mean the vertex issue / hw transform is fine in the interpreter but not the jit? I have not tried that for FF3/4/etc.
Could just be rounding errors then...
-[Unknown]
@hrydgard commented on GitHub (Dec 10, 2013):
No, the intermittent crashing (segfault). Sorry for being unclear, I was referring to the title of the issue. Crashing is the main issue remaining.
@unknownbrackets commented on GitHub (Dec 10, 2013):
Maybe we are crashing when it modifies a jit emuhack to a valid address we have not written code to?
-[Unknown]
@hrydgard commented on GitHub (Dec 10, 2013):
The only code modification it does is to rewrite a large chunk of vhdp.q instructions, that are not at the start of a block, with a set of slightly different vhdp instructions. I think it hardwires a culling function for the current camera position, which seems ridiculous but whatever.
@unknownbrackets commented on GitHub (Dec 10, 2013):
Right, but if it's doing those modifications with bit-twiddling it could corrupt an emuhack. Though, it's probably not that.
Does it still crash sometimes with everything disabled?
-[Unknown]
@hrydgard commented on GitHub (Dec 10, 2013):
Still crashes, but seems to take longer to repro, somehow. Don't have a consistent repro method.
@unknownbrackets commented on GitHub (Jun 17, 2014):
You added some safeties recently, does this still crash? Maybe it gives interesting log messages now?
Does multithreaded impact whether it crashes?
-[Unknown]
@ppmeis commented on GitHub (Jan 20, 2015):
Tested with latest build. Graphincs and in-game look good, but there are still random crashes while playing:
Debuglog (change .jpg to .7z)

@unknownbrackets commented on GitHub (Jan 20, 2015):
It crashes even with fast mem off right? What does the stack trace look like?
It probably crashes in jit. When it does, you can try viewing the Disassembly (Debug -> Windows iirc in MSVC.) It might be interesting tos ee what jit code it's crashing at.
-[Unknown]
@hrydgard commented on GitHub (Jan 20, 2015):
The game has broken audio for some reason, I have a feeling it might be related..
@ppmeis commented on GitHub (Jan 20, 2015):
@hrydgard I think the same. During characters selection audio change every time I change my character.
@unknownbrackets I'm installing MSVC Express. I'm looking for a guide, do you know how to use it? Because I have strange error while compiling...
@unknownbrackets commented on GitHub (Jan 20, 2015):
Can you copy/paste the error?
http://forums.ppsspp.org/showthread.php?tid=5231
The better version is actually now 2013 Community, but they're both fine.
-[Unknown]
@unknownbrackets commented on GitHub (Jan 20, 2015):
Is the audio broken even in interp, by the way?
-[Unknown]
@ppmeis commented on GitHub (Jan 21, 2015):
@unknownbrackets I have a few strange errors while compiling or building:
Error 2 error LNK1181: cannot open input file 'ÿþ/.obj' C:\programming\ppsspp\ext\zlib\LINK zlib
Warning 3 warning D4024: unrecognized source file type ' ■/', object file assumed C:\programming\ppsspp\native\CL native
@unknownbrackets commented on GitHub (Jan 21, 2015):
I would try a brand new clone of ppsspp. It seems like something in the sln file got corrupted, maybe? Not really sure, never seen something like that...
-[Unknown]
@ppmeis commented on GitHub (Jan 21, 2015):
@unknownbrackets I found the error, is because c1.dll and other dll on my SysWOW64 folder are very old. Now it works fine I'll try it now.
@ppmeis commented on GitHub (Jan 21, 2015):
@unknownbrackets is this image usefull for you?

@Bigpet commented on GitHub (Jan 21, 2015):
@ppmeis try to set it to "Debug" instead of "Release" (the combo box next to the green arrow) and also put the Disassembly in the view like suggested by unknown https://github.com/hrydgard/ppsspp/issues/3854#issuecomment-70701385
@ppmeis commented on GitHub (Jan 21, 2015):
@Bigpet @unknownbrackets better now? :)

@Bigpet commented on GitHub (Jan 21, 2015):
@unknownbrackets
Do I read this right and the
enterCodepointer (which is 0xbb197778) is invalid? Or what is thethis+271referring to@unknownbrackets commented on GitHub (Jan 21, 2015):
Well, that's 0x271C. But, sorry, the code I want to see is inside the jit. I forgot that it automatically navigated to the top stack frame...
In the screenshot, you see the call stack with 04b6008f()? If you double click that, you should see the disassembly near where the jit actually is. It may not be exactly the same number when it crashes again, but that's fine.
I'm assuming that enterCode is fine.
-[Unknown]
@Bigpet commented on GitHub (Jan 21, 2015):
Oh yeah I didn't see that it's not the top-most actual frame but the top-most frame with debug symbols
@Bigpet commented on GitHub (Jan 21, 2015):
@unknownbrackets Hm, seems to crash on multiple different addresses, this is one of them
@unknownbrackets commented on GitHub (Jan 21, 2015):
Hmm, what about with fastmem disabled? That just looks like an invalid address. Still a problem, but nearly impossible to debug from the jit disassembly.
If jit is somehow causing the invalid addresses, that's interesting. But keep in mind interpreter always has fast memory off.
-[Unknown]
@ppmeis commented on GitHub (Jan 21, 2015):
@unknownbrackets as you want:

@unknownbrackets commented on GitHub (Jan 21, 2015):
Hmm, that is also an invalid address (EAX is 0.) That also should not crash with fastmem off.
-[Unknown]
@Bigpet commented on GitHub (Jan 21, 2015):
yeah, forgot to turn that off without I just get a game crash

also this:
@ppmeis also doesn't seem to happen for me If I start the game without dynarec and let the levels load without it and only enable it once actually in a level, that may just be a fluke though
@ppmeis commented on GitHub (Jan 21, 2015):
Turning off fastmem, same as @Bigpet:

@Bigpet commented on GitHub (Jan 21, 2015):
here's one of the game crashing logs in full https://gist.github.com/Bigpet/447d0b1f13f8ad1fb9f9
and here's the same actions with the interpreter working fine https://gist.github.com/Bigpet/945bd47d26f4e23a5c6b
@unknownbrackets commented on GitHub (Jan 21, 2015):
Interesting that it breaks different ways. I think the most likely thing is that we're failing to invalidate some block that we should. What we can try is in Core/MIPS/MIPSInt.cpp, find:
Does it change anything if you add after that
case 20:? I think that's not an icache func, though, just a thought.If that doesn't help, you can try changing these lines, right below that:
To:
This should make it a lot slower, but if we're incorrectly invalidating a subrange, this might catch it. If that fixes it, it could still be missing some other invalidation method, but at least it means it's jit cache related.
What if you change these lines (without any other changes from above):
To:
In Core/MIPS/x86/CompALU.cpp, CompFPU.cpp, CompLoadStore.cpp, and CompVFPU.cpp (they may not be exactly the same lines but you get the idea)? I think we're already assuming it's jit mechanics, I just want to rule it out for sure.
-[Unknown]
@Bigpet commented on GitHub (Jan 21, 2015):
Not sure what you mean by
case 20:I tried
and that did not help.
But changing it to
MIPSComp::jit->InvalidateCache();did indeed seem to helpI should clarify that this did not help (in fact it reliably crashes on level change)
but this did help:
@Bigpet commented on GitHub (Jan 22, 2015):
So, the most narrow change seems to be
Do you still need the
CONDITIONAL_DISABLEchanges tested?@unknownbrackets commented on GitHub (Jan 22, 2015):
Hmm. Hard to say. It may be just using func 20 a lot, so invalidating everything there fixes it. That's probably not a solution and may make things slow...
What if you change the 0x40 instead to 0x4000 or something?
Hmm, if that affects it, probably CONDITIONAL_DISABLE doesn't matter.
-[Unknown]
@Bigpet commented on GitHub (Jan 22, 2015):
4000 is not enough or it may be before that area
edit: This
MIPSComp::jit->InvalidateCacheAt(addr-0x2000, 0x4000);didn't help either, so it may not be in the vicinityif I increase it to something absurd like
MIPSComp::jit->InvalidateCacheAt(std::max(addr-0x10000000,0), 0x10000000);it works but I assume that's basically almost all code anyway (one zero less makes it crash already which is weird since that should cover around +-16meg area around the code)@unknownbrackets commented on GitHub (Mar 2, 2015):
Recently fixed an invalidation bug in jit, did that improve anything here?
-[Unknown]
@daniel229 commented on GitHub (Mar 2, 2015):
Still hanging.
@ppmeis commented on GitHub (Mar 2, 2015):
Confirmed it still hanging, even earlier than before.
@Ozzypozzy commented on GitHub (Jun 26, 2015):
What's happening with THUG 2 Remix? It works fairly well if you let the levels load without dynarec on.
@ppmeis commented on GitHub (Jul 25, 2015):
Tested with latest build. Crashing with fastmem on, black screen after a while with fastmen off.
@sum2012 commented on GitHub (Jul 31, 2015):
Can we learn from jpcsp 's code of Icache ? (as it run no problem )
@sum2012 commented on GitHub (Jul 31, 2015):
Yeah,I have some idea
@sum2012 commented on GitHub (Jul 31, 2015):
Hmm,I need more time to test
@sum2012 commented on GitHub (Aug 2, 2015):
The jpcsp's Icache code is in
https://github.com/jpcsp/jpcsp/blob/master/src/jpcsp/Allegrex/Instructions.java#L155
@LunaMoo commented on GitHub (May 9, 2017):
I worked around this issue by using cwcheat which doesn't do anything, but reads the code which game modifies(to refresh JIT), the game modifies lots of vhdp.q instructions(does so using sb)

it replaced some more code initially which was directly causing those crashes, but I think only because earlier messup with those broken vfpu instructions as it stopped affecting anything else after I invalidated jit there every frame.
@unknownbrackets commented on GitHub (May 9, 2017):
The sb - is it in a function that only gets called to update those instructions? Or just some memcpy? Does it get called once per frame? Does it call any cache instructions after doing so (in the function or its caller)?
It's not a great solution, but we could use a replacement hook on some function to clear the jit block it modifies (invalidating all jit may cause crashes in a replacement, though.) Not sure if it can be that simple.
Since there's no branching to the modified instructions our typical self-modifying check isn't triggering.
-[Unknown]
@LunaMoo commented on GitHub (May 9, 2017):
The function that modifies the code is called once per frame, but there are 4 sb's in two loops:


The second jump(after both loops) goes to a function with cache instructions:
Edit: In case they're useful, hashes:
50f7971181eab792:248 = sbFunction
f7a202f7aaa3eae4:60 = cacheFunction
@hrydgard commented on GitHub (May 9, 2017):
To recap what I remember, the function being modified is used for frustum culling, it effectively changes the sign of a few plane tests to adjust for where the camera is looking (which is a silly way to go about it, but whatever).
I seem to remember something about the function being in scratch memory (0x4000), maybe it's copied there after being modified?
The cache instructions afterwards correctly causes it to be invalidated and recompiled, so the culling works, but when the JIT cache later fills up and gets cleared a few hundred frames later, that's when things go south.
Can you check if the function being invalidated by the cache instructions is in the original location or moved to 0x4000-ish? If we patch the function with the "jit marker" but it then gets copied, that could explain things breaking, maybe...
@LunaMoo commented on GitHub (May 9, 2017):
0x4000 is empty, scratchpad starts from 0x10000 by memory viewer and seems to finish at 0x14000, seems there are only some values there, floats and some ints, mostly it's filled with 0's and doesn't have those instructions. Unless I missunderstand the scratchpad thing as I think "cache" has same address + 0x40000000.
I'm confused now as I'm not sure how to check if they get invalidated as they appear to change under both 0x088655D8 and 0x488655D8 in disassembly same way. I definitely saw invalid emuhack with those opcodes in RAM earlier at least once that was after sb, but before cache instruction, so I guess it would be caching broken instructions, but I didn't checked the cache then and now I can't notice any invalid emuhack. Made sure that I don't have any hacks and game is crashing as it should, tried with and without breakpoints, no luck, maybe they're just too spammy and I got lucky earlier as the invalid emuhack I remember seeing was only in one of those instructions at once.
@hrydgard commented on GitHub (May 9, 2017):
Sorry, I meant 0x10000 not 0x4000. Seems I might be mis-remembering or confusing with another game.
0x4xxxxxxxx is an "uncached" mirror of 0x0xxxxxxxxx. On the real system, writes/reads to 0x4xxxxxxxx bypass the cache entirely, and is thus suitable for writing data to be consumed by the GPU because then you don't need to invalidate the data cache lines. In PPSSPP we simply ignore this and emulate all memory as coherent ("uncached" from the point of view of the code, but in reality cached).
To check what is being validated, I meant to check the contents of the register used as a parameter for the cache instruction. That points to the cacheline being invalidated. The CPU needs to invalidate cachelines after writing to code, so that writes it did through the data cache appear when fetching instructions - the instruction cache could hide such changes.
@LunaMoo commented on GitHub (May 9, 2017):
Cache instruction parameter points to ram(0x088655D8 and following), so it would be invalidated after being modified. ~ This reminds me the problem cheats had before and solution which was invalidating before reading/writing with them, so I guess if it invalidates after writing portion of the opcode breaking it with invalid emuhack, it's too late and it just stays broken?
In the scratchpad what I thought was floating points, might just be cache instructions(disassembly behaved weirdly when starting from 0x4000, so I only checked in memory viewer before;p), but those don't trigger breakpoints.
@unknownbrackets commented on GitHub (May 10, 2017):
Invalidation should be checking that the instruction matches the emuhack before writing anything.
If an emuhack is being copied, that could definitely be an issue. We may be able to detect this if we detect a memcpy - we could check if the jit contains the source range, or more simply just invalidate the source range first?
Need some way to make sure it's not invalidating the caller. Maybe we can make the CALL to the replacement directly return to the dispatcher?
-[Unknown]
@Catarax commented on GitHub (Jun 9, 2018):
With a cheat code from LunaMoo, you can now play without any crash.
Tested on EUR version also, refresh rate to 1.
https://forums.ppsspp.org/showthread.php?tid=1475&pid=126855#pid126855
@unknownbrackets commented on GitHub (Jun 9, 2018):
Do we know what PSP function writes to that memory?
Worst case we could use a replacement hook to cause it to automatically refresh jit.
-[Unknown]
@LunaMoo commented on GitHub (Jun 9, 2018):
Few posts above there is a hash(50f7971181eab792:248) and a screenshot of the function which is replacing the opcodes partially.
@hrydgard commented on GitHub (Mar 1, 2019):
The real solution for this is to, like Dolphin, stop overwriting game code with emuhacks (jit entry opcodes) and instead write them to a separate memory space or some kind of hierarchical lookup table. Unfortunately this will increase RAM consumption a bit although that's becoming less and less of an issue, and also won't catch when code gets overwritten (although games are really supposed to invalidate the instruction cache in that case, and they really have to for things to work reliably on hardware).
Thinking about hardcoding these cheats in the emulator for now ... because the UX of having to use cheats just to make a game run properly is just horrible. Alternatively make a mode where we simply interpret instead of JIT in specially marked regions. Not sure what's best...
@hrydgard commented on GitHub (Mar 3, 2019):
Proper fix won't happen in 1.8.0, merged the ugly workaround.
@unknownbrackets commented on GitHub (Apr 6, 2020):
If we create a hook for 50f7971181eab792:248, and invalidate those same addresses at both the start and the end of that function, but disable the "auto-cheat"... does it work? Or does that not work, but the cheat does?
That there are
sbinstructions with offsets to 0x01/0x11/0x15 makes me worry that it is indeed disrupting emuhacks, so the proper fix is indeed moving away from them (for replacements too, really.)We could at least detect this scenario if we had a "shadow" version of RAM where we've written the emuhacks again. If the shadow emuhack doesn't match the read emuhack, then we know it's been modified. In theory, we could even reconstruct the intended opcode via the difference (at least for sb/sh modifications), but that's just doubling down on emuhacks.
I haven't looked at Dolphin, but in theory we could still support self-modifying code as we do now with a shadow buffer (not many pages would even commit) + a check against the original first instruction (maybe just stored at the emuhack address, with actual code at that + 4). It'd add some overhead, but not that much...
-[Unknown]
@hrydgard commented on GitHub (Apr 6, 2020):
Yeah, it's breaking emuhacks. I might try that hook idea though later.
I agree that the real path forward is getting rid of the emuhacks. We can afford a shadow RAM, I've only been concerned about address space on 32-bit devices (which conveniently Dolphin doesn't support).
@unknownbrackets commented on GitHub (Apr 6, 2020):
Well, at least we would not need VRAM. I guess the only worry is if you can execute code in the scratchpad - maybe I'll test later on a PSP. It'd make things easier for address space if you can't.
-[Unknown]
@hrydgard commented on GitHub (Apr 6, 2020):
You can absolutely execute code in the scratchpad, unfortunatelyHm to be honest I'm not actually that sure. But I seem to recall seeing it...
Probably worth testing indeed.
@unknownbrackets commented on GitHub (Apr 7, 2020):
PC can indeed be the scratchpad AND VRAM. It runs fine. In fact, scratchpad is a bit faster:
These timings are fairly consistent (at least to the millisecond) when running the code 10k times with about 106 ops each. We support all those cases currently, although our timings are a bit faster than cached in all cases (~5226us.)
Somehow Cached VRAM is slightly slower (5243us) even in PPSSPP... which makes me question my test, but I can't find anything wrong with it. Uncached VRAM is ironically faster.
Anyway, I guess that means we can't ignore either. Some enterprising developer may have realized that VRAM and scratchpad are faster for their one-off uncached dynamic code.
-[Unknown]
@hrydgard commented on GitHub (Apr 7, 2020):
VRAM is a surprise! Hah.
I am sure I have never seen code executing from VRAM, at least...
@sum2012 commented on GitHub (Sep 5, 2022):
v1.13.1-745-ga42807ea6 still need that hack
@benderscruffy don't keep tap me.Some issue like this already hard hack solution in ppsspp.
If have better solution pr, @hrydgard or @unknownbrackets would tap us.