Closed user202729 closed 6 months ago
What platform are you on and what version of Asymptote are you using? With Asymptote version 2.86, the error message I get is:
implicitshipout=false;
^
base.old/plain.asy: 58.18: dereference of null pointer
Configuration:
asy --version
Asymptote version 2.86 [(C) 2004 Andy Hammerlindl, John C. Bowman, Tom Prince]
ENABLED OPTIONS:
V3D 3D vector graphics output
WebGL 3D HTML rendering
OpenGL 3D OpenGL rendering
SSBO GLSL shader storage buffer objects
GSL GNU Scientific Library (special functions)
FFTW3 Fast Fourier transforms
Eigen Eigenvalue library
XDR External Data Representation (portable binary file format for V3D)
CURL URL support
LSP Language Server Protocol
Readline Interactive history and editing
Sigsegv Distinguish stack overflows from segmentation faults
GC Boehm garbage collector
threads Render OpenGL in separate thread
DISABLED OPTIONS:
In any case, a raised assert is not a segmentation fault and has no security implications.
$ asy --version
Asymptote version 2.87-25 [(C) 2004 Andy Hammerlindl, John C. Bowman, Tom Prince]
ENABLED OPTIONS:
V3D 3D vector graphics output
WebGL 3D HTML rendering
OpenGL 3D OpenGL rendering
SSBO GLSL shader storage buffer objects
GSL GNU Scientific Library (special functions)
FFTW3 Fast Fourier transforms
XDR External Data Representation (portable binary file format for V3D)
CURL URL support
LSP Language Server Protocol
Readline Interactive history and editing
Sigsegv Distinguish stack overflows from segmentation faults
GC Boehm garbage collector
threads Render OpenGL in separate thread
DISABLED OPTIONS:
Eigen Eigenvalue library
I just built from source from git latest I think.
I can't reproduce this behaviour.
What platform did you compile it on and what compiler did use. Also, what version of Boehm GC are you using?
I use Arch Linux, and install the AUR package asymptote-git
with the default configuration.
I'm not sure how to check Boehm GC version.
Sorry, it appears that I accidentally closed the issue, but in any case try compiling Asymptote directly from an official release (or from the latest git source).
It's weird that you can't reproduce the issue, maybe you disabled assertions in your build?
Either way, I tracked down the issue a bit.
If I print out the virtual machine code of asy -s -c 'void f(){}; var a=f();'
, then the code is
0 constpush <item 0x7f287c4fff60>
1 builtin
2 varsave 1
3 pop
4 ret
0 constpush <item 0x7f287c43e570>
1 builtin
2 varsave 1
3 pop
4 ret
0 pushclosure
1 makefunc
2 varsave 2
3 pop
4 ret
0 ret
0 varpush 2
1 popcall
2 varsave 3
3 pop
4 ret
/usr/include/c++/13.2.1/bits/stl_vector.h:1232: std::vector<_Tp, _Alloc>::reference std::vector<_Tp, _Alloc>::back() [with _Tp = vm::item; _Alloc = gc_allocator_ignore_off_page<vm::item>; reference = vm::item&]: Assertion '!this->empty()' failed.
Aborted (core dumped)
The issue is caused by the varsave
line which tries to access the top item of the stack, but the stack is empty. The compiler should not have allowed the deduced type to have type void
.
Asserts are forced to be enabled in common.h:
/****
* common.h
*
* Definitions common to all files.
*****/
#ifndef COMMON_H
#define COMMON_H
#undef NDEBUG
Can you reproduce the issue by building from https://sourceforge.net/projects/asymptote/files/2.86/asymptote-2.86.src.tgz/download?
The code void f(){}; var a=f();
should assign void to a
silently, without any error. There surely isn't any use for this but it is considered an innocuous error. An assert if it arises in the official code would be something to fix (unless it is a compiler or library bug on your system).
For the record here is the virtual machine code for Asymptote version 2.86 produced by asy -s -c 'void f(){}; var a=f();'
0 constpush <item 0x7fb3ea57cea0>
1 builtin
2 varsave 1
3 pop
4 ret
0 constpush <item 0x7fb3ea0b7750>
1 builtin
2 varsave 1
3 pop
4 ret
0 constpush <item 0x7fb3e913b300>
1 builtin
2 varsave 2
3 pop
4 ret
0 pushclosure
1 makefunc
2 varsave 3
3 pop
4 ret
0 ret
0 varpush 3
1 popcall
2 varsave 4
3 pop
4 ret
0 ret
0 ret
Correction: on disabling the garbage collector, I was finally able to reproduce a segmentation fault, so we have now have something to fix:
valgrind asy -c 'void f(){}; var a=f();'
==2911906== Memcheck, a memory error detector
==2911906== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==2911906== Using Valgrind-3.22.0 and LibVEX; rerun with -h for copyright info
==2911906== Command: ./asy -dir base -s -c void\ f(){};\ var\ a=f();
==2911906==
0 constpush <item 0x159be1b0>
1 builtin
2 varsave 1
3 pop
4 ret
0 constpush <item 0x17882490>
1 builtin
2 varsave 1
3 pop
4 ret
0 constpush <item 0x17c8f960>
1 builtin
2 varsave 2
3 pop
4 ret
0 pushclosure
1 makefunc
2 varsave 3
3 pop
4 ret
0 ret
0 varpush 3
1 popcall
2 varsave 4
3 pop
4 ret
==2911906== Invalid read of size 8
==2911906== at 0x67CB60: top (stack.h:122)
==2911906== by 0x67CB60: vm::stack::runWithOrWithoutClosure(vm::lambda*, vm::frame*, vm::frame*) (stack.cc:376)
==2911906== by 0x6A7D69: runRunnable(absyntax::runnable*, trans::coenv&, vm::interactiveStack&, transMode) (process.cc:167)
==2911906== by 0x6A80B5: itree::run(trans::coenv&, vm::interactiveStack&, transMode) (process.cc:293)
==2911906== by 0x6AA293: icore::doRun(bool, transMode) (process.cc:224)
==2911906== by 0x6AA97A: doExec (process.cc:301)
==2911906== by 0x6AA97A: doExec (process.cc:298)
==2911906== by 0x6AA97A: runString(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool) (process.cc:856)
==2911906== by 0x67CA61: vm::stack::runWithOrWithoutClosure(vm::lambda*, vm::frame*, vm::frame*) (stack.cc:465)
==2911906== by 0x67D6B6: run (stack.cc:209)
==2911906== by 0x67D6B6: vm::stack::load(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (stack.cc:566)
==2911906== by 0x58E244: run::loadModule(vm::stack*) (runtime.in:766)
==2911906== by 0x67CA61: vm::stack::runWithOrWithoutClosure(vm::lambda*, vm::frame*, vm::frame*) (stack.cc:465)
==2911906== by 0x6A7D69: runRunnable(absyntax::runnable*, trans::coenv&, vm::interactiveStack&, transMode) (process.cc:167)
Maybe the reason why you can't reproduce the assertion error is that accessing back()
of an empty vector is undefined behavior, my version of libcxx just happen to raise an error, but your version doesn't.
Defining _GLIBCXX_DEBUG
would turn that undefined behavior into "definitely an error", I think. (but that also worsen performance of lower_bound
to O(n), among other things)
To reproduce:
Error message:
Granted the code is invalid Asymptote code, but it would be nice if the interpreter can give better diagnostic than segmentation fault.