Enable to use BH_VPRINTF macro to redirect stdout output (#560)

Enable to use BH_VPRINTF macro for platform Linux/Windows/Darwin/VxWorks to redirect the stdout output from platform os_printf/os_vprintf, or the wasi output from wasm app to the vprintf like callback function specified by BH_VPRINTF macro of cmake WAMR_BH_VPRINTF variable.

Signed-off-by: Wenyong Huang <wenyong.huang@intel.com>
This commit is contained in:
Wenyong Huang 2021-03-06 08:29:58 -06:00 committed by GitHub
parent a4239f1ffd
commit a1568825e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 132 additions and 7 deletions

View File

@ -202,4 +202,7 @@ if (WAMR_BUILD_TAIL_CALL EQUAL 1)
add_definitions (-DWASM_ENABLE_TAIL_CALL=1)
message (" Tail call enabled")
endif ()
if (DEFINED WAMR_BH_VPRINTF)
add_definitions (-DBH_VPRINTF=${WAMR_BH_VPRINTF})
endif ()

View File

@ -604,8 +604,31 @@ wasi_fd_write(wasm_exec_env_t exec_env, wasi_fd_t fd,
ciovec->buf_len = iovec_app->buf_len;
}
err = uvwasi_fd_write(uvwasi, fd,
ciovec_begin, iovs_len, &nwritten);
#ifndef BH_VPRINTF
err = uvwasi_fd_write(uvwasi, fd, ciovec_begin, iovs_len, &nwritten);
#else
/* redirect stdout/stderr output to BH_VPRINTF function */
if (fd == 1 || fd == 2) {
int i;
const struct iovec *iov1 = (const struct iovec *)ciovec_begin;
nwritten = 0;
for (i = 0; i < (int)iovs_len; i++, iov1++) {
if (iov1->iov_len > 0 && iov1->iov_base) {
char format[16];
/* make up format string "%.ns" */
snprintf(format, sizeof(format), "%%.%ds", (int)iov1->iov_len);
nwritten += (uvwasi_size_t)os_printf(format, iov1->iov_base);
}
}
err = 0;
}
else {
err = uvwasi_fd_write(uvwasi, fd, ciovec_begin, iovs_len, &nwritten);
}
#endif /* end of BH_VPRINTF */
if (err)
goto fail;

View File

@ -1237,7 +1237,29 @@ __wasi_errno_t wasmtime_ssp_fd_write(
if (error != 0)
return error;
#ifndef BH_VPRINTF
ssize_t len = writev(fd_number(fo), (const struct iovec *)iov, (int)iovcnt);
#else
ssize_t len = 0;
/* redirect stdout/stderr output to BH_VPRINTF function */
if (fd_number(fo) == 1 || fd_number(fo) == 2) {
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) {
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);
}
}
}
else {
len = writev(fd_number(fo), (const struct iovec *)iov, (int)iovcnt);
}
#endif /* end of BH_VPRINTF */
fd_object_release(fo);
if (len < 0)
return convert_errno(errno);

View File

@ -23,7 +23,11 @@ os_printf(const char *format, ...)
va_list ap;
va_start(ap, format);
#ifndef BH_VPRINTF
ret += vprintf(format, ap);
#else
ret += BH_VPRINTF(format, ap);
#endif
va_end(ap);
return ret;
@ -32,6 +36,10 @@ os_printf(const char *format, ...)
int
os_vprintf(const char *format, va_list ap)
{
#ifndef BH_VPRINTF
return vprintf(format, ap);
#else
return BH_VPRINTF(format, ap);
#endif
}

View File

@ -34,13 +34,21 @@ extern "C" {
#endif
#if defined(MSVC)
__declspec(dllimport) void *BH_MALLOC(unsigned int size);
__declspec(dllimport) void BH_FREE(void *ptr);
__declspec(dllimport) void *BH_MALLOC(unsigned int size);
__declspec(dllimport) void BH_FREE(void *ptr);
#else
void *BH_MALLOC(unsigned int size);
void BH_FREE(void *ptr);
#endif
#if defined(BH_VPRINTF)
#if defined(MSVC)
__declspec(dllimport) int BH_VPRINTF(const char *format, va_list ap);
#else
int BH_VPRINTF(const char *format, va_list ap);
#endif
#endif
#ifndef NULL
#define NULL (void*)0
#endif

View File

@ -23,7 +23,11 @@ os_printf(const char *format, ...)
va_list ap;
va_start(ap, format);
#ifndef BH_VPRINTF
ret += vprintf(format, ap);
#else
ret += BH_VPRINTF(format, ap);
#endif
va_end(ap);
return ret;
@ -32,6 +36,10 @@ os_printf(const char *format, ...)
int
os_vprintf(const char *format, va_list ap)
{
#ifndef BH_VPRINTF
return vprintf(format, ap);
#else
return BH_VPRINTF(format, ap);
#endif
}

View File

@ -23,7 +23,11 @@ os_printf(const char *format, ...)
va_list ap;
va_start(ap, format);
#ifndef BH_VPRINTF
ret += vprintf(format, ap);
#else
ret += BH_VPRINTF(format, ap);
#endif
va_end(ap);
return ret;
@ -32,6 +36,10 @@ os_printf(const char *format, ...)
int
os_vprintf(const char *format, va_list ap)
{
#ifndef BH_VPRINTF
return vprintf(format, ap);
#else
return BH_VPRINTF(format, ap);
#endif
}

View File

@ -16,3 +16,30 @@ bh_platform_destroy()
{
}
int
os_printf(const char *format, ...)
{
int ret = 0;
va_list ap;
va_start(ap, format);
#ifndef BH_VPRINTF
ret += vprintf(format, ap);
#else
ret += BH_VPRINTF(format, ap);
#endif
va_end(ap);
return ret;
}
int
os_vprintf(const char *format, va_list ap)
{
#ifndef BH_VPRINTF
return vprintf(format, ap);
#else
return BH_VPRINTF(format, ap);
#endif
}

View File

@ -49,9 +49,6 @@ typedef struct {
unsigned int waiting_count;
} korp_cond;
#define os_printf printf
#define os_vprintf vprintf
static inline size_t
getpagesize()
{

View File

@ -114,6 +114,27 @@ Currently we only profile the memory consumption of module, module_instance and
- **WAMR_APP_THREAD_STACK_SIZE_MAX**=n, default to 8 MB (8388608) if not set
> Note: the AOT boundary check with hardware trap mechanism might consume large stack since the OS may lazily grow the stack mapping as a guard page is hit, we may use this configuration to reduce the total stack usage, e.g. -DWAMR_APP_THREAD_STACK_SIZE_MAX=131072 (128 KB).
#### **WAMR_BH_VPRINTF**=<vprintf_callback>, default to disable if not set
> Note: if the vprintf_callback function is provided by developer, the os_printf() and os_vprintf() in Linux, Darwin, Windows and VxWorks platforms, besides WASI Libc output will call the callback function instead of libc vprintf() function to redirect the stdout output. For example, developer can define the callback function like below outside runtime lib:
>
> ```C
> int my_vprintf(const char *format, va_list ap)
> {
> /* output to pre-opened file stream */
> FILE *my_file = ...;
> return vfprintf(my_file, format, ap);
> /* or output to pre-opened file descriptor */
> int my_fd = ...;
> return vdprintf(my_fd, format, ap);
> /* or output to string buffer and print the string */
> char buf[128];
> vsnprintf(buf, sizeof(buf), format, ap);
> return my_printf("%s", buf);
> }
> ```
>
> and then use `cmake -DWAMR_BH_VPRINTF=my_vprintf ..` to pass the callback function, or add `BH_VPRINTF=my_vprintf` macro for the compiler, e.g. add line `add_defintions(-DBH_VPRINTF=my_vprintf)` in CMakeListst.txt.
**Combination of configurations:**
We can combine the configurations. For example, if we want to disable interpreter, enable AOT and WASI, we can run command: