Jelajahi Sumber

Provide default vprintf on UWP (#2725)

UWP apps do not have a console attached so any output to stdout/stderr
is lost. Therefore, provide a default BH_VPRINTF in that case for debug
builds which redirects output to the debugger.
zoraaver 2 tahun lalu
induk
melakukan
3c9cd40aa6

+ 5 - 7
core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c

@@ -1108,19 +1108,17 @@ wasmtime_ssp_fd_write(wasm_exec_env_t exec_env, struct fd_table *curfds,
     error = blocking_op_writev(exec_env, fo->file_handle, iov, (int)iovcnt,
                                nwritten);
 #else
-    ssize_t len = 0;
     /* redirect stdout/stderr output to BH_VPRINTF function */
     if (fo->is_stdio) {
         int i;
-        const struct iovec *iov1 = (const struct iovec *)iov;
-
-        for (i = 0; i < (int)iovcnt; i++, iov1++) {
-            if (iov1->iov_len > 0 && iov1->iov_base) {
+        *nwritten = 0;
+        for (i = 0; i < (int)iovcnt; i++) {
+            if (iov[i].buf_len > 0 && iov[i].buf != NULL) {
                 char format[16];
 
                 /* make up format string "%.ns" */
-                snprintf(format, sizeof(format), "%%.%ds", (int)iov1->iov_len);
-                len += (ssize_t)os_printf(format, iov1->iov_base);
+                snprintf(format, sizeof(format), "%%.%ds", (int)iov[i].buf_len);
+                *nwritten += (size_t)os_printf(format, iov[i].buf);
             }
         }
     }

+ 11 - 0
core/shared/platform/windows/platform_internal.h

@@ -179,6 +179,17 @@ typedef uint32_t os_raw_file_handle;
 
 #define bh_socket_t windows_handle *
 
+// UWP apps do not have stdout/stderr handles so provide a default
+// implementation of vprintf on debug builds so output from WASI libc is sent to
+// the debugger and not lost completely.
+#if !defined(BH_VPRINTF) && !defined(NDEBUG) && WINAPI_PARTITION_DESKTOP == 0
+int
+uwp_print_to_debugger(const char *format, va_list ap);
+
+#define BH_VPRINTF uwp_print_to_debugger
+#define UWP_DEFAULT_VPRINTF
+#endif
+
 #ifdef __cplusplus
 }
 #endif

+ 34 - 1
core/shared/platform/windows/win_util.c

@@ -57,4 +57,37 @@ convert_windows_error_code(DWORD windows_error_code)
         default:
             return __WASI_EINVAL;
     }
-}
+}
+
+#ifdef UWP_DEFAULT_VPRINTF
+int
+uwp_print_to_debugger(const char *format, va_list ap)
+{
+    // Provide a stack buffer which should be large enough for any realistic
+    // string so we avoid making an allocation on every printf call.
+    char stack_buf[2048];
+    char *buf = stack_buf;
+    int ret = vsnprintf(stack_buf, sizeof(stack_buf), format, ap);
+
+    if (ret >= sizeof(stack_buf)) {
+        // Allocate an extra byte for the null terminator.
+        char *heap_buf = BH_MALLOC(ret + 1);
+        buf = heap_buf;
+
+        if (heap_buf == NULL) {
+            errno = ENOMEM;
+            return -1;
+        }
+
+        ret = vsnprintf(heap_buf, ret + 1, format, ap);
+    }
+
+    if (ret >= 0)
+        OutputDebugStringA(buf);
+
+    if (buf != stack_buf)
+        BH_FREE(buf);
+
+    return ret;
+}
+#endif