summaryrefslogtreecommitdiffstats
path: root/src/VBox/Main/glue/errorprint.cpp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 03:01:46 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 03:01:46 +0000
commitf8fe689a81f906d1b91bb3220acde2a4ecb14c5b (patch)
tree26484e9d7e2c67806c2d1760196ff01aaa858e8c /src/VBox/Main/glue/errorprint.cpp
parentInitial commit. (diff)
downloadvirtualbox-f8fe689a81f906d1b91bb3220acde2a4ecb14c5b.tar.xz
virtualbox-f8fe689a81f906d1b91bb3220acde2a4ecb14c5b.zip
Adding upstream version 6.0.4-dfsg.upstream/6.0.4-dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Main/glue/errorprint.cpp')
-rw-r--r--src/VBox/Main/glue/errorprint.cpp175
1 files changed, 175 insertions, 0 deletions
diff --git a/src/VBox/Main/glue/errorprint.cpp b/src/VBox/Main/glue/errorprint.cpp
new file mode 100644
index 00000000..26067adf
--- /dev/null
+++ b/src/VBox/Main/glue/errorprint.cpp
@@ -0,0 +1,175 @@
+/* $Id: errorprint.cpp $ */
+
+/** @file
+ * MS COM / XPCOM Abstraction Layer:
+ * Error info print helpers. This implements the shared code from the macros from errorprint.h.
+ */
+
+/*
+ * Copyright (C) 2009-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+
+#include <VBox/com/ErrorInfo.h>
+#include <VBox/com/errorprint.h>
+#include <VBox/log.h>
+
+#include <ProgressImpl.h>
+
+#include <iprt/stream.h>
+#include <iprt/message.h>
+#include <iprt/path.h>
+
+namespace com
+{
+
+void GluePrintErrorInfo(const com::ErrorInfo &info)
+{
+ bool haveResultCode = false;
+#if defined (RT_OS_WIN)
+ haveResultCode = info.isFullAvailable();
+ bool haveComponent = true;
+ bool haveInterfaceID = true;
+#else /* defined (RT_OS_WIN) */
+ haveResultCode = true;
+ bool haveComponent = info.isFullAvailable();
+ bool haveInterfaceID = info.isFullAvailable();
+#endif
+
+ try
+ {
+ Utf8Str str;
+ RTCList<Utf8Str> comp;
+
+ Bstr bstrDetailsText = info.getText();
+ if (!bstrDetailsText.isEmpty())
+ str = Utf8StrFmt("%ls\n",
+ bstrDetailsText.raw());
+ if (haveResultCode)
+ comp.append(Utf8StrFmt("code %Rhrc (0x%RX32)",
+ info.getResultCode(),
+ info.getResultCode()));
+ if (haveComponent)
+ comp.append(Utf8StrFmt("component %ls",
+ info.getComponent().raw()));
+ if (haveInterfaceID)
+ comp.append(Utf8StrFmt("interface %ls",
+ info.getInterfaceName().raw()));
+ if (!info.getCalleeName().isEmpty())
+ comp.append(Utf8StrFmt("callee %ls",
+ info.getCalleeName().raw()));
+
+ if (comp.size() > 0)
+ {
+ str += "Details: ";
+ for (size_t i = 0; i < comp.size() - 1; ++i)
+ str += comp.at(i) + ", ";
+ str += comp.last();
+ str += "\n";
+ }
+
+ // print and log
+ RTMsgError("%s", str.c_str());
+ Log(("ERROR: %s", str.c_str()));
+ }
+ catch (std::bad_alloc &)
+ {
+ RTMsgError("std::bad_alloc in GluePrintErrorInfo!");
+ Log(("ERROR: std::bad_alloc in GluePrintErrorInfo!\n"));
+ }
+}
+
+void GluePrintErrorContext(const char *pcszContext, const char *pcszSourceFile, uint32_t ulLine)
+{
+ // pcszSourceFile comes from __FILE__ macro, which always contains the full path,
+ // which we don't want to see printed:
+ // print and log
+ const char *pszFilenameOnly = RTPathFilename(pcszSourceFile);
+ RTMsgError("Context: \"%s\" at line %d of file %s\n", pcszContext, ulLine, pszFilenameOnly);
+ Log(("Context: \"%s\" at line %d of file %s\n", pcszContext, ulLine, pszFilenameOnly));
+}
+
+void GluePrintRCMessage(HRESULT rc)
+{
+ // print and log
+ RTMsgError("Code %Rhra (extended info not available)\n", rc);
+ Log(("ERROR: Code %Rhra (extended info not available)\n", rc));
+}
+
+static void glueHandleComErrorInternal(com::ErrorInfo &info,
+ const char *pcszContext,
+ HRESULT rc,
+ const char *pcszSourceFile,
+ uint32_t ulLine)
+{
+ if (info.isFullAvailable() || info.isBasicAvailable())
+ {
+ const com::ErrorInfo *pInfo = &info;
+ do
+ {
+ GluePrintErrorInfo(*pInfo);
+
+ pInfo = pInfo->getNext();
+ /* If there is more than one error, separate them visually. */
+ if (pInfo)
+ {
+ /* If there are several errors then at least basic error
+ * information must be available, otherwise something went
+ * horribly wrong. */
+ Assert(pInfo->isFullAvailable() || pInfo->isBasicAvailable());
+
+ RTMsgError("--------\n");
+ }
+ }
+ while (pInfo);
+ }
+ else
+ GluePrintRCMessage(rc);
+
+ GluePrintErrorContext(pcszContext, pcszSourceFile, ulLine);
+}
+
+void GlueHandleComError(ComPtr<IUnknown> iface,
+ const char *pcszContext,
+ HRESULT rc,
+ const char *pcszSourceFile,
+ uint32_t ulLine)
+{
+ /* If we have full error info, print something nice, and start with the
+ * actual error message. */
+ com::ErrorInfo info(iface, COM_IIDOF(IUnknown));
+
+ glueHandleComErrorInternal(info,
+ pcszContext,
+ rc,
+ pcszSourceFile,
+ ulLine);
+
+}
+
+void GlueHandleComErrorProgress(ComPtr<IProgress> progress,
+ const char *pcszContext,
+ HRESULT rc,
+ const char *pcszSourceFile,
+ uint32_t ulLine)
+{
+ /* Get the error info out of the progress object. */
+ ProgressErrorInfo ei(progress);
+
+ glueHandleComErrorInternal(ei,
+ pcszContext,
+ rc,
+ pcszSourceFile,
+ ulLine);
+}
+
+} /* namespace com */
+