Shared heap is not recognized by sub-modules
Thanks for filing a bug or defect report! Please fill out the TODOs below.
Subject of the issue
Looks like the shared heap is not recognized by linked sub-module (nulled upon instantiation). I am assuming that the shared heap should be available across all linked sub-modules, but please correct me if I'm wrong.
By modifying wasm_runtime_attach_shared_heap_internal function in wasm_memory.c by traversing sub-modules and assigning the same shared heap to all of them, the address space in the shared heap became accessible in sub-module, and the strings passed across successfully. Not sure whether this would be a valid approach, though, so looking for feedback.
#if WASM_ENABLE_MULTI_MODULE != 0
WASMModuleInstance *module_instance = (WASMModuleInstance *)module_inst;
// roll back the list of sub-modules
module_instance->e->sub_module_inst_list =
&module_instance->e->sub_module_inst_list_head;
LOG_WARNING("warning: about to assign shared heap to submodules\n");
bh_list *sub_module_inst_list = NULL;
WASMRegisteredModule *sub_module_list_node = NULL;
sub_module_inst_list =
((WASMModuleInstanceExtra *)((WASMModuleInstance *)module_inst)->e)
->sub_module_inst_list;
sub_module_list_node =
bh_list_first_elem(sub_module_inst_list);
while (sub_module_list_node) {
LOG_WARNING("Processing sub-module %s\n", sub_module_list_node->module_name);
WASMModuleCommon *sub_module = sub_module_list_node->module;
WASMModuleInstanceExtra *sub_module_inst = ((WASMModuleInstanceExtra *)((WASMModuleInstance *)sub_module)->e);
LOG_WARNING("Processing sub-module heap %d\n", sub_module_inst->shared_heap);
sub_module_inst->shared_heap = shared_heap;
sub_module_list_node = bh_list_elem_next(sub_module_list_node);
}
#endif
Test case
A simple exercise with string passing between modules, based on command/reactor pattern-based example: https://github.com/bytecodealliance/wasm-micro-runtime/blob/main/doc/multi_module.md
iwasm was built with shared heap switch:
set (WAMR_BUILD_SHARED_HEAP 1)
reactor.c:
/*
* Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef __wasi__
#include <wasi_socket_ext.h>
#else
#include <netdb.h>
#endif
int lookup_host(const char *host)
{
struct addrinfo hints, *res, *result;
int errcode;
char addrstr[100];
void *ptr;
printf("reactor::lookup_host: enter %s\n", host);
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
printf("reactor::lookup_host: calling getaddrinfo, host=%s\n", host);
errcode = getaddrinfo(host, NULL, &hints, &result);
if (errcode != 0)
{
perror("getaddrinfo");
printf("getaddrinfo error %d", errcode);
return -1;
}
printf("reactor::lookup_host: after getaddrinfo %s\n", host);
res = result;
printf("Host: %s\n", host);
while (res)
{
switch (res->ai_family)
{
case AF_INET:
ptr = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
break;
case AF_INET6:
ptr = &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
break;
default:
printf("Unsupported address family: %d\n", res->ai_family);
continue;
}
inet_ntop(res->ai_family, ptr, addrstr, 100);
printf("IPv%d address: %s (%s)\n", res->ai_family == AF_INET6 ? 6 : 4,
addrstr, res->ai_socktype == SOCK_STREAM ? "TCP" : "UDP");
res = res->ai_next;
}
freeaddrinfo(result);
return EXIT_SUCCESS;
}
__attribute__((export_name("resolve"))) int
resolve(const char * host)
{
setvbuf(stdout, NULL, _IONBF, 0);
printf("reactor::resolve: enter %p, %s\n", host, host);
return lookup_host(host);
}
command.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
__attribute__((import_module("reactor")))
__attribute__((import_name("resolve"))) extern int
resolve(const char * host);
extern void *
shared_heap_malloc(uint32_t size);
extern void
shared_heap_free(void *ptr);
int my_resolve()
{
setvbuf(stdout, NULL, _IONBF, 0);
char *host = NULL;
host = shared_heap_malloc(32);
if (!host)
{
printf("command::my_resolve: failed to allocalte shared heap memory, exiting\n");
return -1;
}
strcpy(host, "localhost");
printf("command::my_resolve: enter %p, %ld\n", host, strlen(host));
resolve(host);
shared_heap_free(host);
return 0;
}
int main(int argc, char *argv[])
{
setvbuf(stdout, NULL, _IONBF, 0);
return 0;
}
Your environment
- Host OS = Ubuntu 22.04.3 LTS
- WAMR version = https://github.com/bytecodealliance/wasm-micro-runtime/commit/58fae578e758a441a0a39f2c7b846bba555e3229
Steps to reproduce
iwasm -v=5 --allow-resolve=localhost --addr-pool=0.0.0.0/0 --shared-heap-size=1024 -f my_resolve command.wasm
Expected behavior
Shared heap should be accessible by linked sub-module
Actual behavior
Access memory violation trying to access address space of shared heap from linked sub-module
Extra Info
Anything else you'd like to add?