google / gapid

Graphics API Debugger
https://gapid.dev
Apache License 2.0
2.21k stars 327 forks source link

Read() fails when trying to read into memory handled by the coherent memory tracker. #2730

Open hevrard opened 5 years ago

hevrard commented 5 years ago

When trying to trace a replay from an APK created by export_replay, a read() into mapped memory leads to an error. This is apparently due to the GAPII coherent memory tracker.

The APK runs GAPIR which reads resource from the APK assets into various zones of memory. The first read() of a resource into a memory mapped by vkMapMemory() fails with EFAULT (i.e., destination pointer is in invalid memory range).

@AWoloszyn says the issue comes from GAPII coherent memory tracker, which I am not familiar with. If the destination buffer is first cleared with zeros before the read(), then the error disappears -- but this is costly.

Reproduction:

  1. Trace a Vulkan application
  2. use gapit export_replay -apk ... to create a stand-alone replay APK form the capture
  3. install this APK, and try to trace it
hevrard commented 5 years ago

Another option is to do the read() to a temporary buffer, and then copy this buffer to the destination buffer -- this copy does not use a read call, so the coherent memory tracker should work just fine.

hevrard commented 5 years ago

A lightweight approach may be: assume we can use read() by default, but treat a read() EFAULT error by trying to dirty destination pages and re-try the read. If the read() fails again then properly raise an error.

This way there's no overhead in regular replay, and we dirty the destination pages lazily only when needed.

AWoloszyn commented 5 years ago

That will work for gapir replay. However it still won't fix the problem in the general case for the memory tracker.

hevrard commented 5 years ago

2856 makes sure the to work around this issue when replaying form an asset archive on Android.