Introduce GFXSTREAM_ABORT instead of normal abort.

This CL moves most of our abort() callsites to use the new
GFXSTREAM_ABORT macro, which will allow us to track metrics
about when and where we abort.

Generated code is not yet changed, and test and third-party
code is not affected.

Bug: 204125485
Test: Compile, run emulator.

Change-Id: I909d79a35121f24a60e3b4db2745af5ceeee369c
diff --git a/stream-servers/ChannelStream.cpp b/stream-servers/ChannelStream.cpp
index 2cee81f..7e9bfcf 100644
--- a/stream-servers/ChannelStream.cpp
+++ b/stream-servers/ChannelStream.cpp
@@ -18,6 +18,7 @@
 #define EMUGL_DEBUG_LEVEL  0
 #include "host-common/debug.h"
 #include "host-common/dma_device.h"
+#include "host-common/GfxstreamFatalError.h"
 
 #include <assert.h>
 #include <memory.h>
@@ -106,8 +107,8 @@
 }
 
 const unsigned char *ChannelStream::readFully( void *buf, size_t len) {
-    fprintf(stderr, "%s: FATAL: not intended for use with ChannelStream\n", __func__);
-    abort();
+    GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+        << "not intended for use with ChannelStream";
 }
 
 void ChannelStream::onSave(android::base::Stream* stream) {
diff --git a/stream-servers/ColorBuffer.cpp b/stream-servers/ColorBuffer.cpp
index eefe1a1..f4aeda5 100644
--- a/stream-servers/ColorBuffer.cpp
+++ b/stream-servers/ColorBuffer.cpp
@@ -440,6 +440,7 @@
     assert(m_yuv_converter.get());
 #endif
 
+
     m_yuv_converter->readPixels((uint8_t*)pixels, pixels_size);
 
     return;
diff --git a/stream-servers/CompositorVk.cpp b/stream-servers/CompositorVk.cpp
index 822c146..4397a49 100644
--- a/stream-servers/CompositorVk.cpp
+++ b/stream-servers/CompositorVk.cpp
@@ -567,9 +567,9 @@
     for (size_t i = 0; i < currentComposition.m_composeLayers.size(); ++i) {
         const auto &layer = currentComposition.m_composeLayers[i];
         if (m_vkSampler != layer->m_vkSampler) {
-            COMPOSITOR_VK_ERROR("Unsupported sampler(%#" PRIxPTR ").",
-                                reinterpret_cast<uintptr_t>(layer->m_vkSampler));
-            std::abort();
+            GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+                << "Unsupported sampler(" << reinterpret_cast<uintptr_t>(layer->m_vkSampler)
+                << ").";
         }
         imageInfos[i] =
             VkDescriptorImageInfo({.sampler = VK_NULL_HANDLE,
diff --git a/stream-servers/DisplayVk.cpp b/stream-servers/DisplayVk.cpp
index 4657a46..060c987 100644
--- a/stream-servers/DisplayVk.cpp
+++ b/stream-servers/DisplayVk.cpp
@@ -5,6 +5,7 @@
 #include <glm/glm.hpp>
 #include <glm/gtx/matrix_transform_2d.hpp>
 
+#include "host-common/GfxstreamFatalError.h"
 #include "host-common/logging.h"
 #include "vulkan/VkCommonOperations.h"
 #include "vulkan/VkFormatUtils.h"
@@ -117,9 +118,8 @@
 
     if (!SwapChainStateVk::validateQueueFamilyProperties(m_vk, m_vkPhysicalDevice, surface,
                                                          m_swapChainQueueFamilyIndex)) {
-        DISPLAY_VK_ERROR(
-            "DisplayVk can't create VkSwapchainKHR with given VkDevice and VkSurfaceKHR.");
-        ::abort();
+        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+            << "DisplayVk can't create VkSwapchainKHR with given VkDevice and VkSurfaceKHR.";
     }
     auto swapChainCi = SwapChainStateVk::createSwapChainCi(
         m_vk, surface, m_vkPhysicalDevice, width, height,
@@ -128,10 +128,9 @@
     m_vk.vkGetPhysicalDeviceFormatProperties(m_vkPhysicalDevice, swapChainCi->imageFormat,
                                              &formatProps);
     if (!(formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) {
-        DISPLAY_VK_ERROR(
-            "DisplayVk: The image format chosen for present VkImage can't be used as the color "
-            "attachment, and therefore can't be used as the render target of CompositorVk.");
-        ::abort();
+        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+            << "DisplayVk: The image format chosen for present VkImage can't be used as the color "
+               "attachment, and therefore can't be used as the render target of CompositorVk.";
     }
     m_swapChainStateVk = std::make_unique<SwapChainStateVk>(m_vk, m_vkDevice, *swapChainCi);
     m_compositorVk = CompositorVk::create(
@@ -183,7 +182,6 @@
     }
 
     std::shared_ptr<PostResource> postResource = m_postResourceFuture.value().get();
-
     VkSemaphore imageReadySem = postResource->m_swapchainImageAcquireSemaphore;
 
     uint32_t imageIndex;
@@ -395,9 +393,8 @@
             targetBuffer->m_vkImageView, targetBuffer->m_vkImageCreateInfo.extent.width,
             targetBuffer->m_vkImageCreateInfo.extent.height);
         if (!compositorVkRenderTarget) {
-            DISPLAY_VK_ERROR(
-                "Fail to create CompositorVkRenderTarget for the target display buffer.");
-            std::abort();
+            GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+                << "Failed to create CompositorVkRenderTarget for the target display buffer.";
         }
         m_compositorVkRenderTargets.pop_back();
         m_compositorVkRenderTargets.push_front(compositorVkRenderTarget);
@@ -407,8 +404,8 @@
     std::future<std::unique_ptr<ComposeResource>> composeResourceFuture =
         std::move(m_composeResourceFuture.value());
     if (!composeResourceFuture.valid()) {
-        DISPLAY_VK_ERROR("Invalid composeResourceFuture in m_postResourceFutures.");
-        std::abort();
+        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+            << "Invalid composeResourceFuture in m_postResourceFutures.";
     }
     std::unique_ptr<ComposeResource> composeResource = composeResourceFuture.get();
 
@@ -637,8 +634,8 @@
     uint32_t renderTargetIndex, uint32_t numLayers, const ComposeLayer layers[],
     const std::vector<std::shared_ptr<DisplayBufferInfo>> &composeBuffers) {
     if (!m_surfaceState) {
-        DISPLAY_VK_ERROR("Haven't bound to a surface, can't compare and save composition.");
-        ::abort();
+        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+            << "Haven't bound to a surface, can't compare and save composition.";
     }
     auto [iPrevComposition, compositionNotFound] =
         m_surfaceState->m_prevCompositions.emplace(renderTargetIndex, 0);
diff --git a/stream-servers/FrameBuffer.cpp b/stream-servers/FrameBuffer.cpp
index f284eb0..5a4c70f 100644
--- a/stream-servers/FrameBuffer.cpp
+++ b/stream-servers/FrameBuffer.cpp
@@ -38,6 +38,7 @@
 
 #include "host-common/crash_reporter.h"
 #include "host-common/feature_control.h"
+#include "host-common/GfxstreamFatalError.h"
 #include "host-common/logging.h"
 #include "host-common/misc.h"
 #include "host-common/vm_operations.h"
@@ -1391,7 +1392,7 @@
             // emugl::emugl_crash_reporter(
             //     "FATAL: color buffer with handle %u already exists",
             //     handle);
-            ::abort();
+            GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER));
         }
 
         resHandle = createColorBufferWithHandleLocked(
@@ -2021,8 +2022,9 @@
 
     GLenum resetStatus = s_gles2.glGetGraphicsResetStatusEXT();
     if (resetStatus != GL_NO_ERROR) {
-        ERR("Stream server aborting due to graphics reset. ResetStatus: %#x", resetStatus);
-        abort();
+        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) <<
+                "Stream server aborting due to graphics reset. ResetStatus: " <<
+                std::hex << resetStatus;
     }
 
     WindowSurface* surface = (*w).second.first.get();
diff --git a/stream-servers/GfxStreamBackend.cpp b/stream-servers/GfxStreamBackend.cpp
index ba96592..5565141 100644
--- a/stream-servers/GfxStreamBackend.cpp
+++ b/stream-servers/GfxStreamBackend.cpp
@@ -22,6 +22,7 @@
 #include "host-common/android_pipe_device.h"
 #include "host-common/vm_operations.h"
 #include "host-common/window_agent.h"
+#include "host-common/GfxstreamFatalError.h"
 #include "host-common/HostmemIdMapping.h"
 #include "host-common/FeatureControl.h"
 #include "host-common/feature_control.h"
@@ -406,11 +407,8 @@
            (renderer_flags & GFXSTREAM_RENDERER_FLAGS_ASYNC_FENCE_CB));
 
     if (useVulkanNativeSwapchain && !enableVk) {
-        fprintf(stderr,
-                "%s: can't enable vulkan native swapchain, Vulkan is disabled, "
-                "fatal\n",
-                __func__);
-        abort();
+        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) <<
+                            "can't enable vulkan native swapchain, Vulkan is disabled";
     }
 
     emugl::vkDispatch(false /* don't use test ICD */);
@@ -470,8 +468,7 @@
     auto openglesRenderer = android_getOpenglesRenderer();
 
     if (!openglesRenderer) {
-        fprintf(stderr, "%s: no renderer started, fatal\n", __func__);
-        abort();
+        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "No renderer started, fatal";
     }
 
     address_space_set_vm_operations(getConsoleAgents()->vm);
diff --git a/stream-servers/PostWorker.cpp b/stream-servers/PostWorker.cpp
index edf851f..7a90f0c 100644
--- a/stream-servers/PostWorker.cpp
+++ b/stream-servers/PostWorker.cpp
@@ -24,6 +24,8 @@
 #include "OpenGLESDispatch/EGLDispatch.h"
 #include "OpenGLESDispatch/GLESv2Dispatch.h"
 #include "RenderThreadInfo.h"
+#include "base/Tracing.h"
+#include "host-common/GfxstreamFatalError.h"
 #include "host-common/misc.h"
 #include "vulkan/VkCommonOperations.h"
 
@@ -229,8 +231,8 @@
 // clear() is useful for outputting consistent colors.
 void PostWorker::clearImpl() {
     if (m_displayVk) {
-        POST_ERROR("PostWorker with Vulkan doesn't support clear.");
-        ::std::abort();
+        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+            << "PostWorker with Vulkan doesn't support clear";
     }
 #ifndef __linux__
     s_gles2.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT |
@@ -241,8 +243,8 @@
 
 void PostWorker::composeImpl(const ComposeDevice* p) {
     if (m_displayVk) {
-        POST_ERROR("PostWorker with Vulkan doesn't support ComposeV1.");
-        ::std::abort();
+        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+            << "PostWorker with Vulkan doesn't support ComposeV1";
     }
     // bind the subwindow eglSurface
     if (!m_mainThreadPostingOnly && m_needsToRebindWindow) {
@@ -317,8 +319,8 @@
 
     if (m_displayVk) {
         if (!targetColorBufferPtr) {
-            ERR("failed to retrieve the composition target buffer\n");
-            std::abort();
+            GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) <<
+                                "Failed to retrieve the composition target buffer";
         }
         // We don't copy the render result to the targetHandle color buffer
         // when using the Vulkan native host swapchain, because we directly
@@ -434,8 +436,8 @@
 
 void PostWorker::glesComposeLayer(ComposeLayer* l, uint32_t w, uint32_t h) {
     if (m_displayVk) {
-        POST_ERROR("Should not reach with native Vulkan swapchain enabled.");
-        ::std::abort();
+        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) <<
+                            "Should not reach with native vulkan swapchain enabled.";
     }
     if (l->composeMode == HWC2_COMPOSITION_DEVICE) {
         ColorBufferPtr cb = mFb->findColorBuffer(l->cbHandle);
@@ -463,9 +465,8 @@
     int rotation,
     void* pixels) {
     if (m_displayVk) {
-        POST_ERROR(
-            "Screenshot not supported with native Vulkan swapchain enabled.");
-        ::std::abort();
+        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) <<
+                            "Screenshot not supported with native Vulkan swapchain enabled.";
     }
     cb->readPixelsScaled(
         width, height, format, type, rotation, pixels);
diff --git a/stream-servers/RingStream.cpp b/stream-servers/RingStream.cpp
index 3aaea95..2df0797 100644
--- a/stream-servers/RingStream.cpp
+++ b/stream-servers/RingStream.cpp
@@ -20,6 +20,7 @@
 #include "host-common/crash_reporter.h"
 #include "host-common/debug.h"
 #include "host-common/dma_device.h"
+#include "host-common/GfxstreamFatalError.h"
 
 #include <assert.h>
 #include <memory.h>
@@ -276,8 +277,7 @@
     uint32_t available,
     size_t* count, char** current,const char* ptrEnd) {
 
-    fprintf(stderr, "%s: nyi. abort\n", __func__);
-    abort();
+    GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "nyi. abort";
 
     uint32_t xferTotal = available / sizeof(struct asg_type2_xfer);
 
@@ -346,8 +346,7 @@
 }
 
 const unsigned char *RingStream::readFully( void *buf, size_t len) {
-    fprintf(stderr, "%s: FATAL: not intended for use with RingStream\n", __func__);
-    abort();
+    GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "not intended for use with RingStream";
 }
 
 void RingStream::onSave(android::base::Stream* stream) {
diff --git a/stream-servers/SyncThread.cpp b/stream-servers/SyncThread.cpp
index 0ce5a0e..f03b01c 100644
--- a/stream-servers/SyncThread.cpp
+++ b/stream-servers/SyncThread.cpp
@@ -20,6 +20,7 @@
 #include "base/Thread.h"
 #include "OpenGLESDispatch/OpenGLDispatchLoader.h"
 #include "host-common/crash_reporter.h"
+#include "host-common/GfxstreamFatalError.h"
 #include "host-common/sync_device.h"
 
 #ifndef _MSC_VER
@@ -51,10 +52,8 @@
 #define SYNC_THREAD_CHECK(condition)                                        \
     do {                                                                    \
         if (!(condition)) {                                                 \
-            fprintf(stderr, "%s(%s:%d): %s is false\n", __func__, __FILE__, \
-                    __LINE__, #condition);                                  \
-            fflush(stderr);                                                 \
-            ::std::abort();                                                 \
+            GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) <<              \
+                #condition << " is false";                                  \
         }                                                                   \
     } while (0)
 
diff --git a/stream-servers/VirtioGpuTimelines.cpp b/stream-servers/VirtioGpuTimelines.cpp
index c4664d4..df5a1ac 100644
--- a/stream-servers/VirtioGpuTimelines.cpp
+++ b/stream-servers/VirtioGpuTimelines.cpp
@@ -16,12 +16,7 @@
 #include <cinttypes>
 #include <cstdio>
 
-#define VGT_ERROR(fmt, ...)                                                   \
-    do {                                                                      \
-        fprintf(stderr, "%s(%s:%d): " fmt "\n", __func__, __FILE__, __LINE__, \
-                ##__VA_ARGS__);                                               \
-        fflush(stderr);                                                       \
-    } while (0)
+#include "host-common/GfxstreamFatalError.h"
 
 using TaskId = VirtioGpuTimelines::TaskId;
 using CtxId = VirtioGpuTimelines::CtxId;
@@ -56,26 +51,22 @@
     AutoLock lock(mLock);
     auto iTask = mTaskIdToTask.find(taskId);
     if (iTask == mTaskIdToTask.end()) {
-        VGT_ERROR("Task(id = %" PRIu64 ") can't be found.",
-                  static_cast<uint64_t>(taskId));
-        ::std::abort();
+        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+            << "Task(id = " << static_cast<uint64_t>(taskId) << ") can't be found";
     }
     std::shared_ptr<Task> task = iTask->second.lock();
     if (task == nullptr) {
-        VGT_ERROR("Task(id = %" PRIu64 ") has been destroyed.",
-                  static_cast<uint64_t>(taskId));
-        ::std::abort();
+        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+            << "Task(id = " << static_cast<uint64_t>(taskId) << ") has been destroyed";
     }
     if (task->mId != taskId) {
-        VGT_ERROR("Task id mismatch. Expected %" PRIu64 ". Actual %" PRIu64,
-                  static_cast<uint64_t>(taskId),
-                  static_cast<uint64_t>(task->mId));
-        ::std::abort();
+        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+            << "Task id mismatch. Expected " << static_cast<uint64_t>(taskId) << " Actual "
+            << static_cast<uint64_t>(task->mId);
     }
     if (task->mHasCompleted) {
-        VGT_ERROR("Task(id = %" PRIu64 ") has been set to completed.",
-                  static_cast<uint64_t>(taskId));
-        ::std::abort();
+        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+            << "Task(id = " << static_cast<uint64_t>(taskId) << ") has been set to completed.";
     }
     task->mHasCompleted = true;
     poll_locked(task->mCtxId);
@@ -84,9 +75,8 @@
 void VirtioGpuTimelines::poll_locked(CtxId ctxId) {
     auto iTimelineQueue = mTimelineQueues.find(ctxId);
     if (iTimelineQueue == mTimelineQueues.end()) {
-        VGT_ERROR("Context(id = %" PRIu64 ") doesn't exist.",
-                  static_cast<uint64_t>(ctxId));
-        ::std::abort();
+        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+            << "Context(id = " << ctxId << " doesn't exist";
     }
     std::list<TimelineItem> &timelineQueue = iTimelineQueue->second;
     auto i = timelineQueue.begin();
@@ -107,4 +97,4 @@
         }
     }
     timelineQueue.erase(timelineQueue.begin(), i);
-}
\ No newline at end of file
+}
diff --git a/stream-servers/glestranslator/EGL/EglGlobalInfo.cpp b/stream-servers/glestranslator/EGL/EglGlobalInfo.cpp
index eb0b6f7..f6fcb97 100644
--- a/stream-servers/glestranslator/EGL/EglGlobalInfo.cpp
+++ b/stream-servers/glestranslator/EGL/EglGlobalInfo.cpp
@@ -19,6 +19,7 @@
 #include "EglDisplay.h"
 #include "EglOsApi.h"
 
+#include "host-common/GfxstreamFatalError.h"
 #include "GLcommon/GLutils.h"
 
 #include <string.h>
@@ -39,7 +40,7 @@
 void EglGlobalInfo::setEgl2Egl(EGLBoolean enable, bool nullEgl) {
     if (nullEgl && enable == EGL_FALSE) {
         // No point in nullEgl backend for non egl2egl cases.
-        std::abort();
+        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER));
     }
     sEgl2Egl = enable;
     setGles2Gles(enable);
diff --git a/stream-servers/glestranslator/EGL/EglImp.cpp b/stream-servers/glestranslator/EGL/EglImp.cpp
index e2b67b2..1886598 100644
--- a/stream-servers/glestranslator/EGL/EglImp.cpp
+++ b/stream-servers/glestranslator/EGL/EglImp.cpp
@@ -30,6 +30,7 @@
 #include "base/Stream.h"
 #include "base/System.h"
 #include "base/SharedLibrary.h"
+#include "host-common/GfxstreamFatalError.h"
 #include "host-common/logging.h"
 
 #include "EglWindowSurface.h"
@@ -1080,9 +1081,8 @@
     } else if (r == 5 && g == 5 && b == 5 && a == 1) {
         *colorFormat = GL_RGB5_A1;
     } else {
-        fprintf(stderr, "%s:%d: invalid color format R%dG%dB%dA%d\n", __func__,
-                __LINE__, r, g, b, a);
-        abort();
+        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+            << "invalid color format R" << r << "G" << g << "B" << b << "A" << a;
     }
 
     // Blanket provide 24/8 depth/stencil format for now.
diff --git a/stream-servers/virtio-gpu-gfxstream-renderer.cpp b/stream-servers/virtio-gpu-gfxstream-renderer.cpp
index f3bca54..d93e688 100644
--- a/stream-servers/virtio-gpu-gfxstream-renderer.cpp
+++ b/stream-servers/virtio-gpu-gfxstream-renderer.cpp
@@ -24,6 +24,7 @@
 #include "host-common/HostmemIdMapping.h"
 #include "host-common/address_space_device.h"
 #include "host-common/android_pipe_common.h"
+#include "host-common/GfxstreamFatalError.h"
 #include "host-common/opengles.h"
 #include "host-common/vm_operations.h"
 
@@ -46,10 +47,9 @@
 #define VGPLOG(fmt,...)
 #endif
 
-#define VGP_FATAL(fmt,...) do { \
-    fprintf(stderr, "virto-goldfish-pipe fatal error: %s:%d: " fmt "\n", __func__, __LINE__, ##__VA_ARGS__); \
-    abort(); \
-} while(0);
+#define VGP_FATAL()                                    \
+    GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << \
+            "virtio-goldfish-pipe fatal error: "
 
 #ifdef VIRTIO_GOLDFISH_EXPORT_API
 
@@ -235,7 +235,8 @@
         case VIRGL_FORMAT_YV12:
             return true;
         default:
-            VGP_FATAL("Unknown virgl format: 0x%x", format);
+            VGP_FATAL() << "Unknown virgl format 0x" << std::hex << format;
+            return false;
     }
 }
 
@@ -331,7 +332,7 @@
                 bpp = 1;
                 break;
             default:
-                VGP_FATAL("Unknown format: 0x%x", format);
+                VGP_FATAL() << "Unknown format: 0x" << std::hex << format;
         }
 
         uint32_t stride = totalWidth * bpp;
@@ -361,7 +362,7 @@
             uvWidth = totalWidth / 2;
             uvPlaneCount = 2;
         } else {
-            VGP_FATAL("Unknown yuv virgl format: 0x%x", format);
+            VGP_FATAL() << "Unknown yuv virgl format: 0x" << std::hex << format;
         }
         uint32_t uvHeight = totalHeight / 2;
         uint32_t uvStride = align_up_power_of_2(uvWidth, uvAlign);
@@ -391,7 +392,7 @@
                 bpp = 1;
                 break;
             default:
-                VGP_FATAL("Unknown format: 0x%x", format);
+                VGP_FATAL() << "Unknown format: 0x" << std::hex << format;
         }
 
         uint32_t stride = totalWidth * bpp;
@@ -415,13 +416,13 @@
             res->linearSize);
 
     if (box->x > res->args.width || box->y > res->args.height) {
-        VGP_FATAL("Box out of range of resource");
+        VGP_FATAL() << "Box out of range of resource";
     }
     if (box->w == 0U || box->h == 0U) {
-        VGP_FATAL("Empty transfer");
+        VGP_FATAL() << "Empty transfer";
     }
     if (box->x + box->w > res->args.width) {
-        VGP_FATAL("Box overflows resource width");
+        VGP_FATAL() << "Box overflows resource width";
     }
 
     size_t linearBase = virgl_format_to_linear_base(
@@ -440,8 +441,9 @@
     size_t end = start + length;
 
     if (end > res->linearSize) {
-        VGP_FATAL("start + length overflows! linearSize %zu, start %zu length %zu (wanted %zu)",
-                  res->linearSize, start, length, start + length);
+        VGP_FATAL() << "start + length overflows! linearSize "
+            << res->linearSize << " start " << start << " length " << length << " (wanted "
+            << start + length << ")";
     }
 
     uint32_t iovIndex = 0;
@@ -452,7 +454,7 @@
     while (written < length) {
 
         if (iovIndex >= res->numIovs) {
-            VGP_FATAL("write request overflowed numIovs");
+            VGP_FATAL() << "write request overflowed numIovs";
         }
 
         const char* iovBase_const = static_cast<const char*>(res->iov[iovIndex].iov_base);
@@ -476,7 +478,7 @@
                            toWrite);
                     break;
                 default:
-                    VGP_FATAL("Invalid sync dir: %d", dir);
+                    VGP_FATAL() << "Invalid sync dir " << dir;
             }
             written += toWrite;
         }
@@ -525,15 +527,17 @@
         mVirglRendererCallbacks = *callbacks;
         mVirtioGpuOps = android_getVirtioGpuOps();
         if (!mVirtioGpuOps) {
-            VGP_FATAL("Could not get virtio gpu ops!");
+            GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "Could not get virtio gpu ops!";
         }
         mReadPixelsFunc = android_getReadPixelsFunc();
         if (!mReadPixelsFunc) {
-            VGP_FATAL("Could not get read pixels func!");
+            GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+                << "Could not get read pixels func!";
         }
         mAddressSpaceDeviceControlOps = get_address_space_device_control_ops();
         if (!mAddressSpaceDeviceControlOps) {
-            VGP_FATAL("Could not get address space device control ops!");
+            GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+                << "Could not get address space device control ops!";
         }
         if (flags & GFXSTREAM_RENDERER_FLAGS_ASYNC_FENCE_CB) {
             VGPLOG("Using async fence cb.");
@@ -551,8 +555,8 @@
         VirglCtxId asCtxId = (VirglCtxId)(uintptr_t)hwPipe;
         auto it = mContexts.find(asCtxId);
         if (it == mContexts.end()) {
-            fprintf(stderr, "%s: fatal: pipe id %u not found\n", __func__, asCtxId);
-            abort();
+            GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+                << "fatal: pipe id " << asCtxId << " not found";
         }
 
         auto& entry = it->second;
@@ -570,8 +574,8 @@
         for (auto resId : resIds) {
             auto resEntryIt = mResources.find(resId);
             if (resEntryIt == mResources.end()) {
-                fprintf(stderr, "%s: fatal: res id %u entry not found\n", __func__, resId);
-                abort();
+                GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+                    << "res id " << resId << " entry not found";
             }
 
             auto& resEntry = resEntryIt->second;
@@ -637,9 +641,8 @@
     void setContextAddressSpaceHandleLocked(VirglCtxId ctxId, uint32_t handle) {
         auto ctxIt = mContexts.find(ctxId);
         if (ctxIt == mContexts.end()) {
-            fprintf(stderr, "%s: fatal: ctx id %u not found\n", __func__,
-                    ctxId);
-            abort();
+            GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+                << "ctx id " << ctxId << " not found";
         }
 
         auto& ctxEntry = ctxIt->second;
@@ -650,17 +653,15 @@
     uint32_t getAddressSpaceHandleLocked(VirglCtxId ctxId) {
         auto ctxIt = mContexts.find(ctxId);
         if (ctxIt == mContexts.end()) {
-            fprintf(stderr, "%s: fatal: ctx id %u not found\n", __func__,
-                    ctxId);
-            abort();
+            GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+                << "ctx id " << ctxId << " not found ";
         }
 
         auto& ctxEntry = ctxIt->second;
 
         if (!ctxEntry.hasAddressSpaceHandle) {
-            fprintf(stderr, "%s: fatal: ctx id %u doesn't have address space handle\n", __func__,
-                    ctxId);
-            abort();
+            GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+                << "ctx id " << ctxId << " doesn't have address space handle";
         }
 
         return ctxEntry.addressSpaceHandle;
@@ -670,15 +671,15 @@
 
         auto resEntryIt = mResources.find(resId);
         if (resEntryIt == mResources.end()) {
-            fprintf(stderr, "%s: fatal: resid %u not found\n", __func__, resId);
-            abort();
+            GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+                << " resid " << resId << " not found";
         }
 
         auto& resEntry = resEntryIt->second;
 
         if (!resEntry.iov) {
-            fprintf(stderr, "%s: fatal:resid %u had empty iov\n", __func__, resId);
-            abort();
+            GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+                << "resid " << resId << " has empty iov ";
         }
 
         uint32_t* iovWords = (uint32_t*)(resEntry.iov[0].iov_base);
diff --git a/stream-servers/vulkan/VkAndroidNativeBuffer.cpp b/stream-servers/vulkan/VkAndroidNativeBuffer.cpp
index 9f92bcf..4a8f363 100644
--- a/stream-servers/vulkan/VkAndroidNativeBuffer.cpp
+++ b/stream-servers/vulkan/VkAndroidNativeBuffer.cpp
@@ -15,6 +15,7 @@
 #include "cereal/common/goldfish_vk_private_defs.h"
 #include "cereal/common/goldfish_vk_extension_structs.h"
 
+#include "host-common/GfxstreamFatalError.h"
 #include "stream-servers/FrameBuffer.h"
 #include "GrallocDefs.h"
 #include "VkCommonOperations.h"
diff --git a/stream-servers/vulkan/VkCommonOperations.cpp b/stream-servers/vulkan/VkCommonOperations.cpp
index fc95906..330324f 100644
--- a/stream-servers/vulkan/VkCommonOperations.cpp
+++ b/stream-servers/vulkan/VkCommonOperations.cpp
@@ -34,6 +34,7 @@
 #include "base/System.h"
 #include "base/Tracing.h"
 #include "common/goldfish_vk_dispatch.h"
+#include "host-common/GfxstreamFatalError.h"
 #include "host-common/vm_operations.h"
 
 #ifdef _WIN32
@@ -792,7 +793,6 @@
 
     sVkEmulation->physdev = physdevs[maxScoringIndex];
     sVkEmulation->deviceInfo = deviceInfos[maxScoringIndex];
-
     // Postcondition: sVkEmulation has valid device support info
 
     // Ask about image format support here.
@@ -1876,7 +1876,6 @@
     bool readRes = FrameBuffer::getFB()->
         readColorBufferContents(
             colorBufferHandle, &cbNumBytes, nullptr);
-
     if (!readRes) {
         fprintf(stderr, "%s: Failed to read color buffer 0x%x\n",
                 __func__, colorBufferHandle);
@@ -2008,7 +2007,7 @@
             });
         }
     }
-        
+
     vk->vkCmdCopyBufferToImage(
         sVkEmulation->commandBuffer,
         sVkEmulation->staging.buffer,
@@ -2469,8 +2468,8 @@
         if (res == VK_NOT_READY) {
             continue;
         }
-        VK_COMMON_ERROR("Invalid fence state: %d", static_cast<int>(res));
-        ::std::abort();
+        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+            << "Invalid fence state: " << static_cast<int>(res);
     }
     VkCommandBuffer commandBuffer;
     VkCommandBufferAllocateInfo allocateInfo = {
@@ -2504,9 +2503,7 @@
 void acquireColorBuffersForHostComposing(const std::vector<uint32_t>& layerColorBuffers,
                                          uint32_t renderTargetColorBuffer) {
     if (!sVkEmulation || !sVkEmulation->live) {
-        VK_COMMON_ERROR("Host Vulkan device lost.");
-        ::std::abort();
-        return;
+        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "Host Vulkan device lost";
     }
 
     std::vector<std::tuple<uint32_t, VkImageLayout>> colorBuffersAndLayouts;
@@ -2647,9 +2644,7 @@
 static VkFence doReleaseColorBufferForGuestRendering(
     const std::vector<uint32_t>& colorBufferHandles) {
     if (!sVkEmulation || !sVkEmulation->live) {
-        VK_COMMON_ERROR("Host Vulkan device lost.");
-        ::std::abort();
-        return VK_NULL_HANDLE;
+        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "Host Vulkan device lost";
     }
 
     AutoLock lock(sVkEmulationLock);
@@ -2772,9 +2767,7 @@
 void releaseColorBufferFromHostComposingSync(const std::vector<uint32_t>& colorBufferHandles) {
     VkFence fence = doReleaseColorBufferForGuestRendering(colorBufferHandles);
     if (!sVkEmulation || !sVkEmulation->live) {
-        VK_COMMON_ERROR("Host Vulkan device lost.");
-        ::std::abort();
-        return;
+        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) << "Host Vulkan device lost";
     }
 
     AutoLock lock(sVkEmulationLock);
diff --git a/stream-servers/vulkan/VkDecoderGlobalState.cpp b/stream-servers/vulkan/VkDecoderGlobalState.cpp
index d480316..24139fc 100644
--- a/stream-servers/vulkan/VkDecoderGlobalState.cpp
+++ b/stream-servers/vulkan/VkDecoderGlobalState.cpp
@@ -44,6 +44,7 @@
 #include "common/goldfish_vk_deepcopy.h"
 #include "common/goldfish_vk_dispatch.h"
 #include "host-common/address_space_device_control_ops.h"
+#include "host-common/GfxstreamFatalError.h"
 #include "host-common/vm_operations.h"
 #include "host-common/feature_control.h"
 #include "vk_util.h"
@@ -456,8 +457,8 @@
 
         if (m_emu->instanceSupportsMoltenVK) {
             if (!m_vk->vkSetMTLTextureMVK) {
-                fprintf(stderr, "Cannot find vkSetMTLTextureMVK\n");
-                abort();
+                GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) <<
+                        "Cannot find vkSetMTLTextureMVK";
             }
         }
 
@@ -3032,11 +3033,8 @@
             vk_find_struct<VkExportMemoryAllocateInfo>(pAllocateInfo);
 
         if (exportAllocInfoPtr) {
-            fprintf(stderr,
-                    "%s: Fatal: Export allocs are to be handled "
-                    "on the guest side / VkCommonOperations.\n",
-                    __func__);
-            abort();
+            GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) <<
+                "Export allocs are to be handled on the guest side / VkCommonOperations.";
         }
 
         const VkMemoryDedicatedAllocateInfo* dedicatedAllocInfoPtr =
@@ -4370,7 +4368,7 @@
                 currSi.pWaitSemaphores = pBindInfo[i].pWaitSemaphores;
                 waitDstStageMasks.resize(pBindInfo[i].waitSemaphoreCount, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
                 currSi.pWaitDstStageMask = waitDstStageMasks.data();
-                
+
                 currSi.signalSemaphoreCount = 0;
                 currSi.pSignalSemaphores = nullptr;
 
@@ -4515,8 +4513,8 @@
 
         auto poolInfo = android::base::find(mDescriptorPoolInfo, pool);
         if (!poolInfo) {
-            fprintf(stderr, "%s: FATAL: descriptor pool %p not found\n", __func__, pool);
-            abort();
+            GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+                << "descriptor pool " << pool << " not found ";
         }
 
         DispatchableHandleInfo<uint64_t>* setHandleInfo = sBoxedHandleManager.get(poolId);
@@ -4555,9 +4553,10 @@
                 *didAlloc = true;
                 return allocedSet;
             } else {
-                fprintf(stderr, "%s: FATAL: descriptor pool %p wanted to get set with id 0x%llx but it wasn't allocated\n", __func__,
-                        pool, (unsigned long long)poolId);
-                abort();
+                GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+                        << "descriptor pool " << pool << " wanted to get set with id 0x" <<
+                        std::hex << poolId;
+                return nullptr;
             }
         }
     }
@@ -4587,9 +4586,8 @@
         if (queueInfo) {
             device = queueInfo->device;
         } else {
-            fprintf(stderr, "%s: FATAL: queue %p (boxed: %p) with no device registered\n", __func__,
-                    queue, boxed_queue);
-            abort();
+            GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+                << "queue " << queue << "(boxed: " << boxed_queue << ") with no device registered";
         }
 
         std::vector<VkDescriptorSet> setsToUpdate(descriptorSetCount, nullptr);
@@ -6259,8 +6257,8 @@
             } else if (isDescriptorTypeBufferView(type)) {
                 numBufferViews += count;
             } else {
-                fprintf(stderr, "%s: fatal: unknown descriptor type 0x%x\n", __func__, type);
-                abort();
+                GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+                    << "unknown descriptor type 0x" << std::hex << type;
             }
         }
 
@@ -6303,8 +6301,8 @@
                 entryForHost.stride = sizeof(VkBufferView);
                 ++bufferViewCount;
             } else {
-                fprintf(stderr, "%s: fatal: unknown descriptor type 0x%x\n", __func__, type);
-                abort();
+                GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+                    << "unknown descriptor type 0x" << std::hex << type;
             }
 
             res.linearizedTemplateEntries.push_back(entryForHost);
diff --git a/stream-servers/vulkan/VulkanStream.cpp b/stream-servers/vulkan/VulkanStream.cpp
index 9529c10..7c326d4 100644
--- a/stream-servers/vulkan/VulkanStream.cpp
+++ b/stream-servers/vulkan/VulkanStream.cpp
@@ -18,6 +18,7 @@
 #include "base/BumpPool.h"
 
 #include "host-common/feature_control.h"
+#include "host-common/GfxstreamFatalError.h"
 
 #include <vector>
 
@@ -56,12 +57,12 @@
         *ptrAddr = nullptr;
         return;
     }
-    
+
     *ptrAddr = mPool.alloc(bytes);
 
     if (!*ptrAddr) {
-        fprintf(stderr, "%s: FATAL: alloc failed. Wanted size: %zu\n", __func__, bytes);
-        abort();
+        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) <<
+                "alloc failed. Wanted size: " << bytes;
     }
 }
 
@@ -99,10 +100,8 @@
     android::base::Stream::fromBe32((uint8_t*)&len);
 
     if (len == UINT32_MAX) {
-        fprintf(stderr,
-                "%s: FATAL: VulkanStream can't allocate %u bytes\n",
-                __func__, UINT32_MAX);
-        abort();
+        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) <<
+                "VulkanStream can't allocate UINT32_MAX bytes";
     }
 
     alloc((void**)forOutput, len + 1);
@@ -137,8 +136,8 @@
 ssize_t VulkanStream::read(void *buffer, size_t size) {
     commitWrite();
     if (!mStream->readFully(buffer, size)) {
-        E("FATAL: Could not read back %zu bytes", size);
-        abort();
+        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+            << "Could not read back " << size << " bytes";
     }
     return size;
 }
@@ -162,16 +161,16 @@
 
 void VulkanStream::commitWrite() {
     if (!valid()) {
-        E("FATAL: Tried to commit write to vulkan pipe with invalid pipe!");
-        abort();
+        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) <<
+                            "Tried to commit write to vulkan pipe with invalid pipe!";
     }
-    
+
     int written =
         mStream->writeFully(mWriteBuffer.data(), mWritePos);
-    
+
     if (written) {
-        E("FATAL: Did not write exactly %zu bytes!", mWritePos);
-        abort();
+        GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER))
+            << "Did not write exactly " << mWritePos << " bytes!";
     }
     mWritePos = 0;
 }
@@ -226,10 +225,8 @@
 }
 
 ssize_t VulkanMemReadingStream::write(const void* buffer, size_t size) {
-    fprintf(stderr,
-            "%s: FATAL: VulkanMemReadingStream does not support writing\n",
-            __func__);
-    abort();
+    GFXSTREAM_ABORT(FatalError(ABORT_REASON_OTHER)) <<
+            "VulkanMemReadingStream does not support writing";
 }
 
 uint8_t* VulkanMemReadingStream::beginTrace() {
diff --git a/stream-servers/vulkan/vk_util.h b/stream-servers/vulkan/vk_util.h
index 92c0469..053f2e4 100644
--- a/stream-servers/vulkan/vk_util.h
+++ b/stream-servers/vulkan/vk_util.h
@@ -35,6 +35,8 @@
 
 #include "base/Lock.h"
 #include "common/vk_struct_id.h"
+#include "VkCommonOperations.h"
+#include "host-common/GfxstreamFatalError.h"
 
 struct vk_struct_common {
     VkStructureType sType;
@@ -267,9 +269,7 @@
     do {                                                                 \
         VkResult err = x;                                                \
         if (err != VK_SUCCESS) {                                         \
-            ::fprintf(stderr, "%s(%u) %s: %s failed, error code = %d\n", \
-                      __FILE__, __LINE__, __FUNCTION__, #x, err);        \
-            ::abort();                                                   \
+            GFXSTREAM_ABORT(FatalError(err));                            \
         }                                                                \
     } while (0)