wasm-micro-runtime icon indicating copy to clipboard operation
wasm-micro-runtime copied to clipboard

Shared heap is not recognized by sub-modules

Open bkreminski-siemens opened this issue 4 months ago • 0 comments

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?

bkreminski-siemens avatar Aug 21 '25 14:08 bkreminski-siemens