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

com.hippo.quickjs.android.JSEvaluationException: null at fib.js:1 #12

Open
bjhexn opened this issue Aug 16, 2021 · 16 comments
Open

com.hippo.quickjs.android.JSEvaluationException: null at fib.js:1 #12

bjhexn opened this issue Aug 16, 2021 · 16 comments

Comments

@bjhexn
Copy link

bjhexn commented Aug 16, 2021

QuickJS quickJS = new QuickJS.Builder().build();
JSRuntime runtime;
JSContext jsContext;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_quick_jsactivity);

    initJSContent();
    demo();
}

private void initJSContent() {
    runtime = quickJS.createJSRuntime();
    jsContext = runtime.createJSContext();
}

private void demo() {
    String script1 = "" +
            "function fib(n) {" +
            "  return n;" +
            "}";
    jsContext.evaluate(script1, "fib.js");
    int result = jsContext.evaluate("fib(6)", "fib.js", int.class);
    LogUtils.log("demo result = " + result );
}

@Override
public void onClick(View v) {
    int id = v.getId();
    if (id == R.id.btn_quick_js) {
        //initJSContent();
        demo();
    } else if (id == R.id.btn_quick_js2) {
        demo();
    }
}

"demo()" execute in onCreate() is 0K , but tap button execute "demo" happened crash. If initialize " initJSContent();" in onClick, no crash。 “JSContent” may be reused ?

是否有遇到同样的问题? jscontent 是否可以复用?

@bjhexn
Copy link
Author

bjhexn commented Aug 16, 2021

问题描述:

  1. 在onCreate 创建实例可以运行
  2. 在点击按钮的时候不再次进程初始化,就会报错。
  3. jsContent是否可以复用?如果不新创建JSRuntime, 只创建jsContent又会提示内存溢出。

@seven332
Copy link
Owner

seven332 commented Aug 17, 2021

JSContent 支持复用,JSRuntime 也支持复用。

你遇到的问题是这个吧?
com.hippo.quickjs.android.JSEvaluationException: SyntaxError: stack overflow
at fib.js:1

QuickJS 说堆栈溢出了,但实际上并没有。
QuickJS 通过 __builtin_frame_address 获取当前栈顶指针,在创建 JSRuntime 的时候取当前栈顶指针存到 stack_top 里,之后每次执行 js 脚本的时候,都再取当前栈顶指针,和之前的 stack_top 比较,看两者之差是否超过一个最大值,默认是 256 * 1024。在 PC 里这个逻辑没问题,因为之后的栈顶指针肯定在 stack_top 后面,而在 Android 里不一定,下一次用 JNI,当前栈顶指针和 stack_top 之差可能是负数,用的还是 size_t,就溢出了,导致认为堆栈溢出。

所以这是 QuickJS 在 Android 上的 bug。

简单的解决方法就是禁用堆栈检查,虽有宏来控制,但很难从编译参数上来禁用堆栈检查。
所以直接改源码,quickjs.c 76 行附近,注释掉 CONFIG_STACK_CHECK。

#if !defined(EMSCRIPTEN)
/* enable stack limitation */
// #define CONFIG_STACK_CHECK
#endif

最后说一个和 issue 无关的建议,QuickJS 在 Android 上问题太多,玩一玩就行了,千万别上生产环境。

@bjhexn
Copy link
Author

bjhexn commented Aug 18, 2021

  1. 现在的问题是可以,可以复用。在onCreate中可以进行初始化和执行js。 但是在点击按钮的时候,就无法执行了,出现上面的异常。 在onClick 里再初始化一次就可以了, 问题比较奇怪,代码比较简单你可以把我上面的demo贴进来试试。

  2. QuickJS 在 Android 上问题多? 有具体的问题吗?或相关文档, 谢谢回复。

@bjhexn
Copy link
Author

bjhexn commented Aug 18, 2021

JSContent 支持复用,JSRuntime 也支持复用。

你遇到的问题是这个吧?
com.hippo.quickjs.android.JSEvaluationException: SyntaxError: stack overflow
at fib.js:1

QuickJS 说堆栈溢出了,但实际上并没有。
QuickJS 通过 __builtin_frame_address 获取当前栈顶指针,在创建 JSRuntime 的时候取当前栈顶指针存到 stack_top 里,之后每次执行 js 脚本的时候,都再取当前栈顶指针,和之前的 stack_top 比较,看两者之差是否超过一个最大值,默认是 256 * 1024。在 PC 里这个逻辑没问题,因为之后的栈顶指针肯定在 stack_top 后面,而在 Android 里不一定,下一次用 JNI,当前栈顶指针和 stack_top 之差可能是负数,用的还是 size_t,就溢出了,导致认为堆栈溢出。

所以这是 QuickJS 在 Android 上的 bug。

简单的解决方法就是禁用堆栈检查,虽有宏来控制,但很难从编译参数上来禁用堆栈检查。
所以直接改源码,quickjs.c 76 行附近,注释掉 CONFIG_STACK_CHECK。

#if !defined(EMSCRIPTEN)
/* enable stack limitation */
// #define CONFIG_STACK_CHECK
#endif

最后说一个和 issue 无关的建议,QuickJS 在 Android 上问题太多,玩一玩就行了,千万别上生产环境。

你遇到的问题是这个吧?
com.hippo.quickjs.android.JSEvaluationException: SyntaxError: stack overflow
at fib.js:1

不是这个问题哈

@seven332
Copy link
Owner

贴下堆栈?

@bjhexn
Copy link
Author

bjhexn commented Aug 18, 2021

2021-08-18 11:39:22.556 1932-2766/system_process E/TaskPersister: File error accessing recents directory (directory doesn't exist?).
2021-08-18 11:39:27.184 32190-32190/com.example.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.myapplication, PID: 32190
com.hippo.quickjs.android.JSEvaluationException: null
at fib.js:1

    at com.hippo.quickjs.android.JSContext.evaluateInternal(JSContext.java:164)
    at com.hippo.quickjs.android.JSContext.evaluate(JSContext.java:93)
    at com.my.app.webview.quickjs.QuickJSActivity.demo(QuickJSActivity.java:56)
    at com.my.app.webview.quickjs.QuickJSActivity.onClick(QuickJSActivity.java:68)
    at android.view.View.performClick(View.java:7140)
    at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:992)
    at android.view.View.performClickInternal(View.java:7117)
    at android.view.View.access$3500(View.java:801)
    at android.view.View$PerformClick.run(View.java:27351)
    at android.os.Handler.handleCallback(Handler.java:883)
    at android.os.Handler.dispatchMessage(Handler.java:100)
    at android.os.Looper.loop(Looper.java:214)
    at android.app.ActivityThread.main(ActivityThread.java:7356)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

@bjhexn
Copy link
Author

bjhexn commented Aug 18, 2021

代码如下
public class QuickJSActivity extends AppCompatActivity implements View.OnClickListener {

public static final String PATH = "/test/quickjs";

private Button btn;

QuickJS quickJS = new QuickJS.Builder().build();
JSRuntime runtime;
JSContext jsContext;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_quick_jsactivity);

    btn = findViewById(R.id.btn_quick_js);
    btn.setOnClickListener(this);
    findViewById(R.id.btn_quick_js2).setOnClickListener(this);

    initJSContent();
    demo();
}

@Override
protected void onResume() {
    super.onResume();
}

private void initJSContent() {
    runtime = quickJS.createJSRuntime();
    jsContext = runtime.createJSContext();
}

private void demo() {
    String script1 = "" +
            "function fib(n) {" +
            "  return n;" +
            "}";
    jsContext.evaluate(script1, "fib.js");
    int result = jsContext.evaluate("fib(6)", "fib.js", int.class);
    LogUtils.log("demo result = " + result );
}

@Override
public void onClick(View v) {
    int id = v.getId();
    if (id == R.id.btn_quick_js) {
        initJSContent();
        demo();
    } else if (id == R.id.btn_quick_js2) {
        demo();
    }
}

}

@bjhexn
Copy link
Author

bjhexn commented Aug 18, 2021

onCreate 执行没问题,点击 btn2会出现崩溃, 按钮btn1 在进行初始化则不会报错。

@seven332
Copy link
Owner

不确定是不是同一个问题,你可以试试把 #define CONFIG_STACK_CHECK 注释掉。

请问你用的是什么设备什么系统?

@bjhexn
Copy link
Author

bjhexn commented Aug 18, 2021

用的模拟器 和小米10 都有问题。

@sangpark
Copy link

Hi I'm not sure I was able to follow this issue but from looking at the code and from Google Translate, this looks to be a similar issue to something I'm experiencing. Is there something I can try to resolve these somewhat random null pointer exceptions at line 1 and also stackoverflow errors?

@seven332
Copy link
Owner

@sangpark Remove #define CONFIG_STACK_CHECK in quickjs.c. It may work.

@sangpark
Copy link

@seven332 Thanks for the info, I'm working on doing that now. But in the meantime, as I look into the issue, I see that the quickjs project has a commit that attempts to detect stack overflows

bellard/quickjs@c8ea4c4

It looks like the version of QuickJS this repo has a snapshot of is a bit out of date. Do you have any plans of bumping the QuickJS version and tagging a new build?

@gitusman
Copy link

I have quickjs library imported in Android. I dont have access to quickjs.c
So then how can i disable CONFIG_STACK_CHECK?

@gitusman
Copy link

Also, is there any better library to use instead of quickJs?

@gitusman
Copy link

I found this library and it is working great. No more exceptions.
api 'io.github.taoweiji.quickjs:quickjs-android:1.3.0'

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

4 participants