Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception: null function object #3949

Open
ericCHensssssssss opened this issue Dec 7, 2024 · 32 comments
Open

Exception: null function object #3949

ericCHensssssssss opened this issue Dec 7, 2024 · 32 comments

Comments

@ericCHensssssssss
Copy link

Error report when i run wasm app which build from kotlin .

I find the [wasm-micro-runtime] codes missed some logic.please check the screen shot, i have marked the lost parts

image

Method wasm_struct_obj_set_field at gc_object.c

@ericCHensssssssss
Copy link
Author

image

@ericCHensssssssss
Copy link
Author

kotlin-wasm-wasi-example-wasm-wasi.wasm.zip
this is the wasm file which can reproduce the error

@ericCHensssssssss
Copy link
Author

it work well use wasmedge

@ericCHensssssssss
Copy link
Author

Uploading 20241207173026.jpg…

@lum1n0us
Copy link
Collaborator

lum1n0us commented Dec 9, 2024

kotlin-wasm-wasi-example-wasm-wasi.wasm.zip this is the wasm file which can reproduce the error

would you mind uploading the wasm again? kotlin-wasm-wasi-example-wasm-wasi.wasm seems broken and is failed for validation, even with wabt tools

vscode ➜ /SDF/030_github_issues/3949 $ /opt/wabt-1.0.36/bin/wasm-validate --enable-all ./kotlin-wasm-wasi-example-wasm-wasi.wasm
0000063: error: unexpected type form (got -0x32)
vscode ➜ /SDF/030_github_issues/3949 $ /opt/wabt-1.0.36/bin/wasm-validate --enable-gc ./kotlin-wasm-wasi-example-wasm-wasi.wasm
0000063: error: unexpected type form (got -0x32)
vscode ➜ /SDF/030_github_issues/3949 $ /opt/wabt-1.0.36/bin/wasm-validate  ./kotlin-wasm-wasi-example-wasm-wasi.wasm
0000063: error: unexpected type form (got 0x4e)

@TianlongLiang
Copy link
Collaborator

Could you please tell me the command you use(to execute which function)? I tried to execute your wasm, it seems don't have any main function:
image

@lum1n0us
Copy link
Collaborator

lum1n0us commented Dec 9, 2024

kotlin-wasm-wasi-example-wasm-wasi.wasm.zip this is the wasm file which can reproduce the error

would you mind uploading the wasm again? kotlin-wasm-wasi-example-wasm-wasi.wasm seems broken and is failed for validation, even with wabt tools

vscode ➜ /SDF/030_github_issues/3949 $ /opt/wabt-1.0.36/bin/wasm-validate --enable-all ./kotlin-wasm-wasi-example-wasm-wasi.wasm
0000063: error: unexpected type form (got -0x32)
vscode ➜ /SDF/030_github_issues/3949 $ /opt/wabt-1.0.36/bin/wasm-validate --enable-gc ./kotlin-wasm-wasi-example-wasm-wasi.wasm
0000063: error: unexpected type form (got -0x32)
vscode ➜ /SDF/030_github_issues/3949 $ /opt/wabt-1.0.36/bin/wasm-validate  ./kotlin-wasm-wasi-example-wasm-wasi.wasm
0000063: error: unexpected type form (got 0x4e)

Seems not important. Let's focus on @TianlongLiang 's question.

@ericCHensssssssss
Copy link
Author

Could you please tell me the command you use(to execute which function)? I tried to execute your wasm, it seems don't have any main function:

This is the command i used. method name is myTest

./iwasm -f myTest kotlin-wasm-wasi-example-wasm-wasi.wasm

@ericCHensssssssss
Copy link
Author

kotlin-wasm-wasi-example-wasm-wasi.wasm.zip this is the wasm file which can reproduce the error

would you mind uploading the wasm again? kotlin-wasm-wasi-example-wasm-wasi.wasm seems broken and is failed for validation, even with wabt tools

vscode ➜ /SDF/030_github_issues/3949 $ /opt/wabt-1.0.36/bin/wasm-validate --enable-all ./kotlin-wasm-wasi-example-wasm-wasi.wasm
0000063: error: unexpected type form (got -0x32)
vscode ➜ /SDF/030_github_issues/3949 $ /opt/wabt-1.0.36/bin/wasm-validate --enable-gc ./kotlin-wasm-wasi-example-wasm-wasi.wasm
0000063: error: unexpected type form (got -0x32)
vscode ➜ /SDF/030_github_issues/3949 $ /opt/wabt-1.0.36/bin/wasm-validate  ./kotlin-wasm-wasi-example-wasm-wasi.wasm
0000063: error: unexpected type form (got 0x4e)

Seems not important. Let's focus on @TianlongLiang 's question.

i reupload the files. please help to check ,thanks
Uploading kotlin-wasm-wasi-example-wasm-wasi.wasm.zip…

@lum1n0us
Copy link
Collaborator

Could you please tell me the command you use(to execute which function)? I tried to execute your wasm, it seems don't have any main function:

This is the command i used. method name is myTest

./iwasm -f myTest kotlin-wasm-wasi-example-wasm-wasi.wasm

Would you mind sharing with us the output of running ⬆️ commands? It will be better if adding "-v=5"

@ericCHensssssssss
Copy link
Author

i added some more logs 。the error log is the last two lines。
====error logs
PUSH_REF,value: 0x0
Executing opcode: 0x14
Exception: null function object, type index: 976

-----more detail logs

PUSH_REF,value: 0x112042b68
Executing opcode: 0xfb
WASM_OP_GC_PREFIX Executing opcode: 0x2
Struct object: 0x112042b68
Field index: 1, Type index: 96
Is signed: false
Field type: 107
Field size: 8
PUSH_REF,value: 0x1120149e0
Executing opcode: 0xfb
WASM_OP_GC_PREFIX Executing opcode: 0x16
Executing opcode: 0xfb
WASM_OP_GC_PREFIX Executing opcode: 0x2
Struct object: 0x1120149e0
Field index: 2, Type index: 104
Is signed: false
Field type: 99
Field size: 8
field_size == 8 && field.field_type == REF_TYPE_HT_NULLABLE
gc_obj is not NULL
PUSH_REF,value: 0x112014b48
Executing opcode: 0xfb
WASM_OP_GC_PREFIX Executing opcode: 0x2
Struct object: 0x112014b48
Field index: 5, Type index: 28
Is signed: false
Field type: 99
Field size: 8
field_size == 8 && field.field_type == REF_TYPE_HT_NULLABLE
gc_obj is NULL
PUSH_REF,value: 0x0
Executing opcode: 0x14
Exception: null function object, type index: 976

@ericCHensssssssss
Copy link
Author

log.txt

@lum1n0us i add the detail log. if you need other info please let me know

@lum1n0us
Copy link
Collaborator

It might be another problem. Here is the details:

  • The Exception "null function object" comes from func[23]. Its name is kotlin.collections.toList
  • Relative wasm code is
============== func 23 ====================
  0xf50a | 83 02       | size of function
  0xf50c | 06          | 6 local blocks
  0xf50d | 01 63 e0 00 | 1 locals of type Ref((ref null (module 96)))
  0xf511 | 01 7f       | 1 locals of type I32
  0xf513 | 01 63 e0 00 | 1 locals of type Ref((ref null (module 96)))
  0xf517 | 01 7f       | 1 locals of type I32
  0xf519 | 01 63 e0 00 | 1 locals of type Ref((ref null (module 96)))
  0xf51d | 01 63 e0 00 | 1 locals of type Ref((ref null (module 96)))
  ...
  0xf5a9 | 04 63 e0 00 | if blockty:Type(Ref((ref null (module 96))))
  0xf5ad | 20 00       | local_get local_index:0                            <- local#0. param#0
  0xf5af | 22 05       | local_tee local_index:5                            <- local#5 = local#0
  0xf5b1 | 41 00       | i32_const value:0
  0xf5b3 | 20 05       | local_get local_index:5                            <- local#5
  0xf5b5 | fb 02 60 01 | struct_get struct_type_index:96 field_index:1      <- struct_type#96.[1]. local#5.[1]
  0xf5b9 | fb 16 e8 00 | ref_cast_non_null hty:Concrete(Module(104))
  0xf5bd | fb 02 68 02 | struct_get struct_type_index:104 field_index:2     <- struct_type#104.[2]. local#5.[1].[2]
  0xf5c1 | fb 02 1c 05 | struct_get struct_type_index:28 field_index:5      <- struct_type#28.[5]. local#5.[1].[2].[5]
  0xf5c5 | 14 d0 07    | call_ref type_index:976                            <- Exception: null function object
  0xf5c8 | 05          | else
  • Like your found, the problem struct_get struct_type#28 [5] returns NULL.
  • But the problem is not struct_set struct_type#28 [5] doesn't set the value properly.
  • What I found is there is no such an opcode like struct_set struct_type#28 in the whole .wasm. 4 globals will initialize its fields via struct_new struct_type#28. But seems none of them are passed into func#23(need to be sure)
  • So I am wondering the original kotlin code might be helpful to locate the problem. Like does the 1st parameter of kotlin.collections.toList initilizaed properly?
  • Here is the call-stack.
#00: 0xf5c8 - kotlin.collections.toList
#01: 0xf0ec - kotlin.collections.distinct
#02: 0x2857b - kotlinx.datetime.internal.format.OptionalFormatStructure.<init>
#03: 0x1f984 - kotlinx.datetime.format.AbstractDateTimeFormatBuilder.appendOptionalImpl
#04: 0x1f654 - kotlinx.datetime.format.optional
#05: 0x1f691 - kotlinx.datetime.format.optional$default
#06: 0x2d396 - kotlinx.datetime.ISO_DATE_TIME_OFFSET_WITH_TRAILING_ZEROS$lambda.invoke
#07: 0x2d3ea - kotlinx.datetime.ISO_DATE_TIME_OFFSET_WITH_TRAILING_ZEROS$lambda.invoke
#08: 0x1c940 - kotlinx.datetime.format.Companion.Format
#09: 0x2d404 - kotlinx.datetime.<init properties Instant.kt>
#10: 0x2cc5b - kotlinx.datetime.<get-ISO_DATE_TIME_OFFSET_WITH_TRAILING_ZEROS>
#11: 0x2d149 - kotlinx.datetime.Instant.toString
#12: 0x2f380 - myTest

ericCHensssssssss pushed a commit to ericCHensssssssss/kotlin-wasm-wasi-template that referenced this issue Dec 12, 2024
…tification_referrer_id=NT_kwDOCercKbUxMzczODI0NjM2NjoxNjYzODY3Mjk#issuecomment-2536050908
@ericCHensssssssss
Copy link
Author

this is the bug project which produce the error.
https://github.com/ericCHensssssssss/kotlin-wasm-wasi-template/tree/main/src/wasmWasiMain/kotlin
image

Your analysis seems reasonable,but it can work well at wasmedge runtime

image

@lum1n0us
Copy link
Collaborator

It appears to be a challenging issue. I will start from the beginning to reproduce it and plan to insert some logging to aid my understanding. Would you mind:

@ericCHensssssssss
Copy link
Author

1、Assume that you already have a development environment for Kotlin and Gradle
2、As the project relays on kotlinx-datetime,so you need build on your local ,
i changed the project version from kotlinx-datetime:0.6.1-SNAPSHOT to kotlinx-datetime:0.6.2-SNAPSHOT(on my local pc)
git clone https://github.com/Kotlin/kotlinx-datetime.git
change the version to 0.6.2-SNAPSHOT

3、git clone https://github.com/ericCHensssssssss/kotlin-wasm-wasi-template
4、build the project use gradle 。
5、The codes at BugReproduce2.kt,this is The code produce the error
val now = Clock.System.now()
println("the time is"+now)

If you have any other request,please let me know,thanks。

@ericCHensssssssss
Copy link
Author

@lum1n0us if you need i Reproduce it and add some more logs, I think it is ok。

@lum1n0us
Copy link
Collaborator

Thanks. I've met several problems and definitely needs some help. Here are my steps:


This is the callstack:

#00:   [#23] 0xf5c8 - kotlin.collections.toList  <- we met the "null pointer" exception here.
#01:   [#17] 0xf0ec - kotlin.collections.distinct
#02: [#1804] 0x2857b - kotlinx.datetime.internal.format.OptionalFormatStructure.<init>
#03: 0x1f984 - kotlinx.datetime.format.AbstractDateTimeFormatBuilder.appendOptionalImpl
#04: 0x1f654 - kotlinx.datetime.format.optional
#05: 0x1f691 - kotlinx.datetime.format.optional$default
#06: 0x2d396 - kotlinx.datetime.ISO_DATE_TIME_OFFSET_WITH_TRAILING_ZEROS$lambda.invoke
#07: 0x2d3ea - kotlinx.datetime.ISO_DATE_TIME_OFFSET_WITH_TRAILING_ZEROS$lambda.invoke
#08: 0x1c940 - kotlinx.datetime.format.Companion.Format
#09: 0x2d404 - kotlinx.datetime.<init properties Instant.kt>
#10: 0x2cc5b - kotlinx.datetime.<get-ISO_DATE_TIME_OFFSET_WITH_TRAILING_ZEROS>
#11: 0x2d149 - kotlinx.datetime.Instant.toString
#12: 0x2f380 - myTest

I logged every call(). the last part likes below. Hope it can help to trace which value is NULL.

[11:16:37:202 - 7FE820579780]:  -> call kotlin.collections.toList().
[11:16:37:202 - 7FE820579780]:  -> call kotlin.collections.HashSet.<get-size>().
[11:16:37:202 - 7FE820579780]:  -> call kotlin.collections.HashMap.<get-size>().

@ericCHensssssssss
Copy link
Author

git clone https://github.com/Kotlin/kotlinx-datetime.git
change to 0.6.2. <= HERE. I assume you're talking about tags. but there is only 0.6.1.
-- this is just for tags(build from the latest codes and to be used by kotlin-wasm-wasi-template,) ,because the latest codes have not released in 0.6.1,so i use 0.6.2 as my local latest codes. you can use any other tags you like,just make sure kotlin-wasm-wasi-template use the latest

build. <= HERE. what's the command? like $ ./gradlew ?
-- build the wasi target and publish it to maven local , it will download it when build kotlin-wasm-wasi-template

git clone https://github.com/ericCHensssssssss/kotlin-wasm-wasi-template
apply ⬆️ kotlinx-datetime. <= HERE. how to do?

----change the Gradle dependencies version of Kotlinx-datetime**

image

build the project. <= HERE. what's the command? $ ./gradlew wasmWasiWasmEdgeRun will fail
---- i use gradle wasmWasiRun to build the wasm file. and then run at wasm-micro-runtime or wasmedge

@ericCHensssssssss
Copy link
Author

I feel like your analysis is right, it just feels weird that it works on wasmEdge, i am not familiar with wasmEdge,So Thanks for you keep help。

@ericCHensssssssss
Copy link
Author

@lum1n0us i raised a question at kotlinx-datatime, the response from kotlinx-datatime is:

Sorry, I couldn't reproduce your issue. When I run the code you provided in a Wasm/WASI test, the test passes with no problems. I don't know how to use "micro-wasm-runtime" to run Wasm programs. If you provide a self-contrained step-by-step instruction, I could look into it, but otherwise, I'd suspect that it's the runtime's fault: how come this code runs just fine in the browser?

@ericCHensssssssss
Copy link
Author

0xf5c5 | 14 d0 07 | call_ref type_index:976 <- Exception: null function object

is it possible,This ref is global,no need set 。
i guess

@ericCHensssssssss
Copy link
Author

need init the func-ref when struct.new ?

ref.func $kotlin.collections.ArrayList.___fun_84
ref.func $kotlin.collections.ArrayList.isEmpty___fun_85
ref.func $kotlin.collections.AbstractMutableList.contains___fun_59
ref.func $kotlin.collections.ArrayList.iterator___fun_90
ref.func $kotlin.collections.AbstractCollection.containsAll___fun_233
ref.func $kotlin.collections.ArrayList.get___fun_86
ref.func $kotlin.collections.ArrayList.indexOf___fun_88
ref.func $kotlin.collections.ArrayList.listIterator___fun_94
struct.new $kotlin.collections.List.itable___type_28

@lum1n0us
Copy link
Collaborator

lum1n0us commented Dec 20, 2024

Finally, I've set up both Kotlin projects. After quickly reviewing the code, particularly BugReproduce2.kt.

I must admit I'm not well-versed in Kotlin. But I'll share what I observed.
Clock.System.now() uses override fun now(): Instant = @Suppress("DEPRECATION_ERROR") Instant.now() found in common/src/Clock.kt.

In common/src/Instant.kt, now() is defined as public func now(): Instant. By the way, it's marked as deprecated and suggests reverting to Clock.System.now(), which is quite confusing.

So, could you please run BugReproduce2 in Kotlin?

If it is doable, would you mind adding some logs around OptionalFormatStructure.<init> to see what'
s missing?

#00:   [#23] 0xf5c8 - kotlin.collections.toList  <- we met the "null pointer" exception here.
#01:   [#17] 0xf0ec - kotlin.collections.distinct
#02: [#1804] 0x2857b - kotlinx.datetime.internal.format.OptionalFormatStructure.<init>  <- MAYBE in this function?

@lum1n0us
Copy link
Collaborator

0xf5c5 | 14 d0 07 | call_ref type_index:976 <- Exception: null function object

is it possible,This ref is global,no need set 。 i guess

About this. you are right. The function uses a global value of type #28 which is a member of a value of type #104.

There are only 16 global values of type #104. Out of these, only 4 have a non-null value of type #28 as members. Moreover, when the exception occurs, none of the 4 are in use.

It doesn't seem to be a problem with execution. It appears more like an issue of incomplete implementation.

@ericCHensssssssss
Copy link
Author

0xf5c5 | 14 d0 07 | call_ref type_index:976 <- Exception: null function object
is it possible,This ref is global,no need set 。 i guess

About this. you are right. The function uses a global value of type #28 which is a member of a value of type #104.

There are only 16 global values of type #104. Out of these, only 4 have a non-null value of type #28 as members. Moreover, when the exception occurs, none of the 4 are in use.

It doesn't seem to be a problem with execution. It appears more like an issue of incomplete implementation.

sorry?I don't fully understand, do you mean the Kotlin test project is incomplete implementation or the wasmr incomplete implementation?

@ericCHensssssssss
Copy link
Author

ericCHensssssssss commented Dec 21, 2024

Finally, I've set up both Kotlin projects. After quickly reviewing the code, particularly BugReproduce2.kt.

--Thanks ,I've been waiting to hear from you,I want use wasm-micro-runtime in iot,i try wasmEdge,wasm ..., I find wasm-micro-runtime is the best for me。

I must admit I'm not well-versed in Kotlin. But I'll share what I observed. Clock.System.now() uses override fun now(): Instant = @Suppress("DEPRECATION_ERROR") Instant.now() found in common/src/Clock.kt.

In common/src/Instant.kt, now() is defined as public func now(): Instant. By the way, it's marked as deprecated and suggests reverting to Clock.System.now(), which is quite confusing.

---it is ok ,Instant.now() maybe changed in the future,so suggest uses override fun now() function。

So, could you please run BugReproduce2 in Kotlin?
---it worked well at jvm, Kotlin run in jvm。

If it is doable, would you mind adding some logs around OptionalFormatStructure.<init> to see what' s missing?

#00:   [#23] 0xf5c8 - kotlin.collections.toList  <- we met the "null pointer" exception here.
#01:   [#17] 0xf0ec - kotlin.collections.distinct
#02: [#1804] 0x2857b - kotlinx.datetime.internal.format.OptionalFormatStructure.<init>  <- MAYBE in this function?

-- what logs you want to have。i saw you the last response, maybe incomplete implement。 so it means no need to add logs, sorry,not understand fully

@ericCHensssssssss
Copy link
Author

By the way,as it need build kotlinx-datetime on you local,you can add log at the kotlin file

image

ericCHensssssssss pushed a commit to ericCHensssssssss/kotlin-wasm-wasi-template that referenced this issue Dec 22, 2024
…tification_referrer_id=NT_kwDOCercKbUxMzczODI0NjM2NjoxNjYzODY3Mjk#issuecomment-2536050908
ericCHensssssssss pushed a commit to ericCHensssssssss/kotlin-wasm-wasi-template that referenced this issue Dec 22, 2024
…tification_referrer_id=NT_kwDOCercKbUxMzczODI0NjM2NjoxNjYzODY3Mjk#issuecomment-2536050908
ericCHensssssssss pushed a commit to ericCHensssssssss/kotlin-wasm-wasi-template that referenced this issue Dec 22, 2024
…tification_referrer_id=NT_kwDOCercKbUxMzczODI0NjM2NjoxNjYzODY3Mjk#issuecomment-2536050908
@lum1n0us
Copy link
Collaborator

Struggled with Gradle and was defeated. :(

Appreciate the details on where the function is. Looking at the call stack, I'm thinking the error might happen when calculating the field variable.

I plan to use logging to find out:

  • If every element returned by basicFormat(format) includes a member named 'field'.
  • If every element's field can be processed by distinct(), such as being comparable.
  • If the result from distinct() comes back empty.
  • If formField() is equipped to manage invalid inputs.

@ericCHensssssssss
Copy link
Author

Hi ,do you have some new findings

@lum1n0us
Copy link
Collaborator

Might need some help. I am trying to use kotlin.reflect.full.memberProperties but failed on gradle

Unresolved reference: implementation

Any suggestion?

diff --git a/build.gradle.kts b/build.gradle.kts
index 0c16b80..f8ea463 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -54,6 +54,7 @@ kover {
 }
 
 dependencies {
+    implementation("org.jetbrains.kotlin:kotlin-reflect:2.1.0")
     kover(project(":kotlinx-datetime"))
     kover(project(":kotlinx-datetime-serialization"))
 }

diff --git a/core/common/src/internal/format/FormatStructure.kt b/core/common/src/internal/format/FormatStructure.kt
index 16f2317..64fae57 100644
--- a/core/common/src/internal/format/FormatStructure.kt
+++ b/core/common/src/internal/format/FormatStructure.kt
@@ -8,6 +8,7 @@ package kotlinx.datetime.internal.format
 import kotlinx.datetime.internal.format.formatter.*
 import kotlinx.datetime.internal.format.parser.*
 import kotlinx.datetime.internal.isAsciiDigit
+import kotlin.reflect.full.memberProperties  // -> to make sure every element returned by basicFormat(format) includes a member named 'field'.

 internal sealed interface FormatStructure<in T> {
     fun parser(): ParserStructure<T>

@ericCHensssssssss
Copy link
Author

you can add dependencies at sourceSet like this

image

Another info i find want share to you
I find the null function at Another point。 this is the screenSHot

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants