diff options
author | Caslyn Tonelli <caslyn@google.com> | 2023-04-16 02:03:58 +0000 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2023-04-17 13:31:50 -0700 |
commit | 88613ee285ffa1ff019c3ea9311dfa4d1e99c5d9 (patch) | |
tree | e28c0b33ac4d123b13d8e47afb955ac70829b4a4 | |
parent | 74dbfe7e758a994632cf449a3a0eb5023aa7e7aa (diff) | |
download | scudo-88613ee285ffa1ff019c3ea9311dfa4d1e99c5d9.tar.gz |
[scudo] Descriptive Fucshia errors
`dieOnError` in fuchsia.cpp takes the syscall name, status code, and
relevant size parameter to describe what failed, the reason, and size
context. Several different Fuchsia syscalls can fail underlying Scudo's
map operation and gets hidden if using `dieOnMapUnmapError`.
The reason for this change is to provide an error status code and more
helpful information to debug failures.
GitOrigin-RevId: ced95a5765f5743761e72685ecc944dde990305a
Change-Id: I21996460546e565719fc1ba7c5d4a1aba6357e8c
-rw-r--r-- | standalone/fuchsia.cpp | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/standalone/fuchsia.cpp b/standalone/fuchsia.cpp index ef93542ef62..0788c4198e5 100644 --- a/standalone/fuchsia.cpp +++ b/standalone/fuchsia.cpp @@ -19,6 +19,7 @@ #include <zircon/compiler.h> #include <zircon/process.h> #include <zircon/sanitizer.h> +#include <zircon/status.h> #include <zircon/syscalls.h> namespace scudo { @@ -31,6 +32,16 @@ void NORETURN die() { __builtin_trap(); } // with ZX_HANDLE_INVALID. static_assert(ZX_HANDLE_INVALID == 0, ""); +static void NORETURN dieOnError(zx_status_t Status, const char *FnName, + uptr Size) { + char Error[128]; + formatString(Error, sizeof(Error), + "SCUDO ERROR: %s failed with size %zuKB (%s)", FnName, + Size >> 10, zx_status_get_string(Status)); + outputRaw(Error); + die(); +} + static void *allocateVmar(uptr Size, MapPlatformData *Data, bool AllowNoMem) { // Only scenario so far. DCHECK(Data); @@ -42,7 +53,7 @@ static void *allocateVmar(uptr Size, MapPlatformData *Data, bool AllowNoMem) { Size, &Data->Vmar, &Data->VmarBase); if (UNLIKELY(Status != ZX_OK)) { if (Status != ZX_ERR_NO_MEMORY || !AllowNoMem) - dieOnMapUnmapError(Status == ZX_ERR_NO_MEMORY ? Size : 0); + dieOnError(Status, "zx_vmar_allocate", Size); return nullptr; } return reinterpret_cast<void *>(Data->VmarBase); @@ -73,7 +84,7 @@ void *map(void *Addr, uptr Size, const char *Name, uptr Flags, Status = _zx_vmo_set_size(Vmo, VmoSize + Size); if (Status != ZX_OK) { if (Status != ZX_ERR_NO_MEMORY || !AllowNoMem) - dieOnMapUnmapError(Status == ZX_ERR_NO_MEMORY ? Size : 0); + dieOnError(Status, "zx_vmo_set_size", VmoSize + Size); return nullptr; } } else { @@ -81,7 +92,7 @@ void *map(void *Addr, uptr Size, const char *Name, uptr Flags, Status = _zx_vmo_create(Size, ZX_VMO_RESIZABLE, &Vmo); if (UNLIKELY(Status != ZX_OK)) { if (Status != ZX_ERR_NO_MEMORY || !AllowNoMem) - dieOnMapUnmapError(Status == ZX_ERR_NO_MEMORY ? Size : 0); + dieOnError(Status, "zx_vmo_create", Size); return nullptr; } _zx_object_set_property(Vmo, ZX_PROP_NAME, Name, strlen(Name)); @@ -99,7 +110,7 @@ void *map(void *Addr, uptr Size, const char *Name, uptr Flags, Status = _zx_vmar_map(Vmar, MapFlags, Offset, Vmo, VmoSize, Size, &P); if (UNLIKELY(Status != ZX_OK)) { if (Status != ZX_ERR_NO_MEMORY || !AllowNoMem) - dieOnMapUnmapError(Status == ZX_ERR_NO_MEMORY ? Size : 0); + dieOnError(Status, "zx_vmar_map", Size); return nullptr; } @@ -120,7 +131,7 @@ void *map(void *Addr, uptr Size, const char *Name, uptr Flags, } if (UNLIKELY(Status != ZX_OK)) { if (Status != ZX_ERR_NO_MEMORY || !AllowNoMem) - dieOnMapUnmapError(Status == ZX_ERR_NO_MEMORY ? Size : 0); + dieOnError(Status, "zx_vmar_op_range", Size); return nullptr; } @@ -145,7 +156,7 @@ void unmap(void *Addr, uptr Size, uptr Flags, MapPlatformData *Data) { const zx_status_t Status = _zx_vmar_unmap(Vmar, reinterpret_cast<uintptr_t>(Addr), Size); if (UNLIKELY(Status != ZX_OK)) - dieOnMapUnmapError(); + dieOnError(Status, "zx_vmar_unmap", Size); } if (Data) { if (Data->Vmo != ZX_HANDLE_INVALID) @@ -160,8 +171,9 @@ void setMemoryPermission(UNUSED uptr Addr, UNUSED uptr Size, UNUSED uptr Flags, (Flags & MAP_NOACCESS) ? 0 : (ZX_VM_PERM_READ | ZX_VM_PERM_WRITE); DCHECK(Data); DCHECK_NE(Data->Vmar, ZX_HANDLE_INVALID); - if (_zx_vmar_protect(Data->Vmar, Prot, Addr, Size) != ZX_OK) - dieOnMapUnmapError(); + const zx_status_t Status = _zx_vmar_protect(Data->Vmar, Prot, Addr, Size); + if (Status != ZX_OK) + dieOnError(Status, "zx_vmar_protect", Size); } void releasePagesToOS(UNUSED uptr BaseAddress, uptr Offset, uptr Size, |