question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Calling function with string arguments returns out of bounds memory error.

See original GitHub issue

Seems like trying to load and call a function that uses pointers to access strings fails to access memory in either an exported or imported memory.

Example code:

            using var engine = new Engine();
            using var module = Module.FromFile(engine, "../../../wasm/bucketing-lib-debug.wasm");
            using var linker = new Linker(engine);
            using var store = new Store(engine);
            linker.Define(
                "env",
                "abort",
                Function.FromCallback(store, (int message, int filename, int linenum, int colnum) =>
                {
                    var inst = linker.Instantiate(store, module);
                    var mem = inst.GetMemory(store, "memory");

                    var messageStr = From64Bitstring(mem.ReadString(store, message, 1000));
                    var filenameStr = From64Bitstring(mem.ReadString(store, filename, 1000));
                    var lineNumStr = From64Bitstring(mem.ReadString(store, linenum, 1000));
                    var colNumStr = From64Bitstring(mem.ReadString(store, colnum, 1000));
                    Console.WriteLine(messageStr);
                    Console.WriteLine(filenameStr);
                    Console.WriteLine(lineNumStr);
                    Console.WriteLine(colNumStr);
                })
            );
            var memory = new Memory(store, 10);
            linker.Define("env", "memory", memory);
            
            var config = "{\"project\":{\"_id\":\"_project\"},\"environment\":{\"_id\":\"environment\"}}\0";
            var user = "{\"user_id\":\"test_id\"}";
            
            var configaddr = 0;
            
            
            var configBytesWritten = memory?.WriteString(store, configaddr, config);
            var useraddr = configaddr + configBytesWritten!;
            var userBytesWritten = memory?.WriteString(store, (int) useraddr, user);
            
            var instance = linker.Instantiate(store, module);
            //var memory = instance.GetMemory(store, "memory");
            
            
            dynamic generateBucketedConfig = instance.GetFunction(store, "generateBucketedConfig")!;


            if (configBytesWritten == null || userBytesWritten == null)
            {
                Console.Out.WriteLine("Failed to write to memory.");
                return;
            }

            var config2 = memory.ReadString(store, configaddr, (int) configBytesWritten);
            var user2 = memory.ReadString(store, (int) useraddr, (int) userBytesWritten);


            Console.Out.WriteLine("Config data: " + config2);
            Console.Out.WriteLine("user data: " + user2);
            var span = memory.GetSpan(store);
            var result = generateBucketedConfig?.Invoke(store, (int)configaddr, (int)useraddr);

            Console.WriteLine("generateBucketedConfig result: " + result);

WAT file of relevant function showing param usage via pointers:

(func $src/index/generateBucketedConfig (param $0 i32) (param $1 i32) (result i32)
  (local $2 i32)
  (local $3 i32)
  (local $4 i32)
  (local $5 i32)
  global.get $~lib/memory/__stack_pointer
  i32.const 12
  i32.sub
  global.set $~lib/memory/__stack_pointer
  call $~stack_check
  global.get $~lib/memory/__stack_pointer
  i64.const 0
  i64.store
  global.get $~lib/memory/__stack_pointer
  i32.const 0
  i32.store offset=8
  global.get $~lib/memory/__stack_pointer
  global.get $~lib/memory/__stack_pointer
  local.get $0
  local.set $2
  local.get $2
  call $~lib/assemblyscript-json/JSON/_JSON.parse<~lib/string/String>
  local.tee $2
  i32.store
  local.get $2
  i32.const 3
  call $~lib/rt/__instanceof
  if (result i32)
   local.get $2
  else
   i32.const 1184
   i32.const 2960
   i32.const 4
   i32.const 41
   call $~lib/builtins/abort
   unreachable
  end
  local.tee $2
  i32.store
  global.get $~lib/memory/__stack_pointer
  global.get $~lib/memory/__stack_pointer
  local.get $1
  local.set $3
  local.get $3
  call $~lib/assemblyscript-json/JSON/_JSON.parse<~lib/string/String>
  local.tee $3
  i32.store offset=4
  local.get $3
  i32.const 3
  call $~lib/rt/__instanceof
  if (result i32)
   local.get $3
  else
   i32.const 1184
   i32.const 2960
   i32.const 5
   i32.const 39
   call $~lib/builtins/abort
   unreachable
  end
  local.tee $3
  i32.store offset=4
  global.get $~lib/memory/__stack_pointer
  i32.const 0
  local.get $2
  call $src/index/BucketedUserConfig#constructor
  local.tee $4
  i32.store offset=8
  local.get $4
  call $src/index/BucketedUserConfig#stringify
  local.set $5
  global.get $~lib/memory/__stack_pointer
  i32.const 12
  i32.add
  global.set $~lib/memory/__stack_pointer
  local.get $5
 )

Error output:

Config data: {"project":{"_id":"_project"},"environment":{"_id":"environment"}}
user data: {"user_id":"test_id"}
Unhandled exception. Wasmtime.TrapException: wasm trap: out of bounds memory access
wasm backtrace:
    0:  0x36a - <unknown>!~lib/string/String.UTF8.byteLength
    1: 0x69f2 - <unknown>!~lib/string/String.UTF8.encode
    2: 0x1638 - <unknown>!~lib/string/String.UTF8.encode@varargs
    3: 0x6c0e - <unknown>!~lib/assemblyscript-json/util/index/Buffer.fromString
    4: 0x5f16 - <unknown>!~lib/assemblyscript-json/JSON/_JSON.parse<~lib/string/String>
    5: 0x7c4b - <unknown>!src/index/generateBucketedConfig
    6: 0x7f2d - <unknown>!export:src/index/generateBucketedConfig

   at Wasmtime.Function.Invoke(StoreContext context, ReadOnlySpan`1 arguments)
   at Wasmtime.Function.Invoke(IStore store, Object[] arguments)
   at System.Dynamic.UpdateDelegates.UpdateAndExecute4[T0,T1,T2,T3,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2, T3 arg3)
   at Example.Program.runWASM() in /Users/jamiesinn/git/dotnet-server-sdk/Example/Program.cs:line 75
   at Example.Program.Main(String[] args) in /Users/jamiesinn/git/dotnet-server-sdk/Example/Program.cs:line 12
   at Example.Program.<Main>(String[] args)

What are we doing wrong here? or is this an unsupported method of accessing a function?

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:15 (9 by maintainers)

github_iconTop GitHub Comments

1reaction
JamieSinncommented, Mar 15, 2022

Awesome! Thanks!

We had issues enabling and finding the proper WASI config - it would always complain with not being able to find fd_write.

WASM is a new area for us - and this helps a ton in understanding how to use it!

0reactions
peterhuenecommented, Mar 14, 2022

By the way, with the above program’s WASI configuration, you should be able to console.log from within the exported function in the AssemblyScript program to verify that it is indeed passing the JSON correctly.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Array of strings. Compiler error. Maybe memory out ...
You are exceeding array bounds since while (argv[num++] != NULL). will stop when argv[num] is NULL , yet argv[] 's dimension is 2...
Read more >
ARR30-C. Do not form or use out-of-bounds pointers or array
The error is that the while loop in the GetMachineName() function (used to extract the host name from a longer string) is not...
Read more >
Memory access out of bounds in Chrome · Issue #1384
I'm getting the following intermittent error running the develop version in Chrome, running from a web worker. Chrome Version 89.0.4389.90 ...
Read more >
CWE-125: Out-of-bounds Read (4.12) - MITRE
A crash can occur when the code reads a variable amount of data and assumes that a sentinel exists to stop the read...
Read more >
2.2. Common String Manipulation Errors | Secure Coding ...
Improperly bounded string copies occur when data is copied from a source to a fixed-length character array (for example, when reading from ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found