简体   繁体   English

Z3使用JNA引发无效的内存访问

[英]Z3 raises invalid memory access with JNA

I am using the Z3 C api in java with jna. 我在jna中使用java中的Z3 C api。 I often get an invalid memory access, but only with the windows (.dll) and mac os (.dylib) libraries. 我经常获得无效的内存访问,但只能使用windows(.dll)和mac os(.dylib)库。 It does not happen when I use the linux one (.so). 当我使用linux(.so)时,它不会发生。

I temporarily solved this problem never calling the dec_ref procedures, both for ast and for all the other objects (I still call the inc_ref procs, and I use the mk_context_rc at the beginning). 我暂时解决了这个问题,从来没有调用dec_ref程序,包括ast和所有其他对象(我仍然调用inc_ref procs,我在开头使用mk_context_rc )。 Of course this solution is not sustainable. 当然,这种解决方案是不可持续的。

I guess it is due to the memory management somewhere. 我想这是由于某处的内存管理。 Even if I just use the mk_context it still crashes. 即使我只是使用mk_context它仍然崩溃。

In the thread JNA simple function call works on linux (x64) but not on windows (x86) the user experienced a similar problem, and it turned out it was due to some compiling configuration. 在线程中, JNA简单函数调用在linux(x64)上工作但在Windows(x86)上没有用户遇到类似的问题,结果发现这是由于一些编译配置。

This is the exception I get (on Mac OS X 10.6.8) 这是我得到的例外(在Mac OS X 10.6.8上)

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x000000000000000c
Crashed Thread:  0  Dispatch queue: com.apple.main-thread

and this is the trace of the failure 这是失败的痕迹

    Thread 0 Crashed:  Dispatch queue: com.apple.main-thread
0   libz3.dylib                     0x00000001250d4d64 unsigned int ast_array_hash<expr>(expr* const*, unsigned int, unsigned int) + 244
1   libz3.dylib                     0x00000001250cb16a ast_manager::register_node_core(ast*) + 36
2   libz3.dylib                     0x00000001250cbeae ast_manager::mk_app_core(func_decl*, unsigned int, expr* const*) + 134
3   libz3.dylib                     0x00000001250cc30d ast_manager::mk_app(func_decl*, unsigned int, expr* const*) + 749
4   libz3.dylib                     0x000000012528c194 map_proc::reconstruct(app*) + 214
5   libz3.dylib                     0x00000001254830b8 void for_each_expr_core<qe::lift_foreign_vars, obj_mark<expr, bit_vector, default_t2uint<expr> >, false, false>(qe::lift_foreign_vars&, obj_mark<expr, bit_vector, default_t2uint<expr> >&, expr*) + 760
6   libz3.dylib                     0x00000001254832c9 qe::lift_foreign_vars::lift(obj_ref<expr, ast_manager>&) + 61
7   libz3.dylib                     0x00000001254833a6 qe::datatype_plugin::simplify(obj_ref<expr, ast_manager>&) + 92
8   libz3.dylib                     0x000000012546b1a7 qe::quant_elim_plugin::check(unsigned int, app* const*, expr*, obj_ref<expr, ast_manager>&, bool, ref_vector<app, ast_manager>&, qe::def_vector*) + 535
9   libz3.dylib                     0x000000012546b8f9 qe::quant_elim_new::eliminate_block(unsigned int, app* const*, obj_ref<expr, ast_manager>&, ref_vector<app, ast_manager>&, bool, qe::def_vector*) + 445
10  libz3.dylib                     0x000000012545f2cb qe::quant_elim_new::eliminate_exists(unsigned int, app* const*, obj_ref<expr, ast_manager>&, ref_vector<app, ast_manager>&, bool, qe::def_vector*) + 67
11  libz3.dylib                     0x0000000125462170 qe::quant_elim_new::eliminate_exists_bind(unsigned int, app* const*, obj_ref<expr, ast_manager>&) + 88
12  libz3.dylib                     0x000000012545c0ba qe::expr_quant_elim::elim(obj_ref<expr, ast_manager>&) + 1012
13  libz3.dylib                     0x000000012545cb75 qe::expr_quant_elim::operator()(expr*, expr*, obj_ref<expr, ast_manager>&) + 113
14  libz3.dylib                     0x000000012548b993 qe_tactic::imp::operator()(ref<goal> const&, sref_buffer<goal>&, ref<model_converter>&, ref<proof_converter>&, obj_ref<dependency_manager<ast_manager::expr_dependency_config>::dependency, ast_manager>&) + 783
15  libz3.dylib                     0x00000001255debfa cleanup_tactical::operator()(ref<goal> const&, sref_buffer<goal>&, ref<model_converter>&, ref<proof_converter>&, obj_ref<dependency_manager<ast_manager::expr_dependency_config>::dependency, ast_manager>&) + 14
16  libz3.dylib                     0x00000001255d5e3d exec(tactic&, ref<goal> const&, sref_buffer<goal>&, ref<model_converter>&, ref<proof_converter>&, obj_ref<dependency_manager<ast_manager::expr_dependency_config>::dependency, ast_manager>&) + 109
17  libz3.dylib                     0x0000000125070ed8 _tactic_apply + 680
18  libz3.dylib                     0x00000001250711d9 Z3_tactic_apply + 105
19  jna4404318687023840668.tmp      0x000000010a00cd1c ffi_call_unix64 + 76
20  jna4404318687023840668.tmp      0x000000010a00c884 ffi_call + 644
21  jna4404318687023840668.tmp      0x000000010a003ca5 Java_com_sun_jna_Native_ffi_1prep_1cif + 1605
22  jna4404318687023840668.tmp      0x000000010a004282 Java_com_sun_jna_Native_invokePointer + 34
23  ???                             0x00000001031cfd2e 0 + 4347198766
24  ???                             0x00000001031cd658 0 + 4347188824
25  ???                             0xffb89c44ff5c4272 0 + 18426649695542329970

maybe they they can be useful to understand what I am doing wrong 也许他们有助于理解我做错了什么

Based on the comments in your question, it seems you are using tactics and other features only available in the new Z3 API. 根据您问题中的评论,您似乎正在使用仅在新Z3 API中提供的策略和其他功能。 Starting at version 4.0, reference counting is the default approach for managing memory in the Z3 API. 从版本4.0开始,引用计数是在Z3 API中管理内存的默认方法。 The Z3 API still has support for the old memory management policy (it is enabled when the API Z3_mk_context is used instead of Z3_mk_context_rc ). Z3 API仍然支持旧的内存管理策略(当使用API Z3_mk_context而不是Z3_mk_context_rc时启用它)。 However, the old memory management policy is not available for new objects (such as Solvers , Tactics , ...) that were introduced in version 4.0. 但是,旧的内存管理策略不适用于4.0版中引入的新对象(如SolversTactics等)。

The Z3 distribution contains a Python API. Z3发行版包含一个Python API。 The source code for the Python API is located in the sub-directory python in the Z3 distribution. Python API的源代码位于Z3发行版的子目录python中。 It demonstrates how to integrate the Z3 API in a managed language such as a Python. 它演示了如何将Z3 API集成到托管语言(如Python)中。 I believe a similar approach can be used to integrate the Z3 API in Java. 我相信可以使用类似的方法在Java中集成Z3 API。 The idea is to wrap every Z3 object with a Java object wrapper. 我们的想法是用Java对象包装器包装每个Z3对象。 The reference counter should be incremented in the constructor, and decremented when the Java garbage collector reclaims the wrapper. 引用计数器应在构造函数中递增,并在Java垃圾收集器回收包装器时递减。

The exception was raised because my main program and the java garbage collector were accessing Z3 concurrently. 引发异常的原因是我的主程序和java垃圾收集器同时访问Z3。 I solved just making the Library object thread-safe, wrapping it with the method Native.synchronizedLibrary 我解决了只是让Library对象线程安全,用Native.synchronizedLibrary方法包装它

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM