Closed fadushin closed 5 years ago
Just a tiny bit more information on this, because I can reproduce a similar issue in my gen_server test. With the test_spawn_list.beam
, I get the following SEGV in memory_shallow_copy_term
on Linux (Ubuntu):
20:04:20 castro:/work/src/github/fadushin/AtomVM/build> gdb src/AtomVM core
GNU gdb (Ubuntu 8.1-0ubuntu3) 8.1.0.20180409-git
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from src/AtomVM...done.
[New LWP 90202]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `./src/AtomVM test_spawn_list.beam'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x000055ba679f62ca in memory_is_moved_marker (t=0x30) at /work/src/github/fadushin/AtomVM/src/libAtomVM/memory.c:136
136 return *t == 0x2B;
(gdb) where
#0 0x000055ba679f62ca in memory_is_moved_marker (t=0x30) at /work/src/github/fadushin/AtomVM/src/libAtomVM/memory.c:136
#1 0x000055ba679f6cc7 in memory_shallow_copy_term (t=49, new_heap=0x7fff3a73ff90, move=1) at /work/src/github/fadushin/AtomVM/src/libAtomVM/memory.c:407
#2 0x000055ba679f6a5e in memory_scan_and_copy (mem_start=0x55ba68374e20, mem_end=0x55ba68374e30, new_heap_pos=0x7fff3a740008, move=1)
at /work/src/github/fadushin/AtomVM/src/libAtomVM/memory.c:343
#3 0x000055ba679f621e in memory_gc (ctx=0x55ba68374c20, new_size=8) at /work/src/github/fadushin/AtomVM/src/libAtomVM/memory.c:115
#4 0x000055ba679f5ee7 in memory_ensure_free (c=0x55ba68374c20, size=2) at /work/src/github/fadushin/AtomVM/src/libAtomVM/memory.c:54
#5 0x000055ba679e3e52 in context_execute_loop (ctx=0x55ba68374c20, mod=0x55ba68374470, function_name=0x55ba67a0ae08 "start", arity=0)
at /work/src/github/fadushin/AtomVM/src/libAtomVM/opcodesswitch.h:971
#6 0x000055ba679dfba0 in main (argc=2, argv=0x7fff3a740948) at /work/src/github/fadushin/AtomVM/src/main.c:84
(gdb) list
131
132
133 static inline int memory_is_moved_marker(term *t)
134 {
135 // 0x2B is an unused tag
136 return *t == 0x2B;
137 }
138
139 static inline void memory_replace_with_moved_marker(term *to_be_replaced, term replace_with)
140 {
On OS X I get:
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x109e4b000)
* frame #0: 0x000000010001da4d AtomVM`memory_shallow_copy_term(t=4460867489, new_heap=0x00007ffeefbfdb70, move=0) at memory.c:413
frame #1: 0x000000010001dd0c AtomVM`memory_scan_and_copy(mem_start=0x0000000109e4aff0, mem_end=0x0000000109e4b000, new_heap_pos=0x00007ffeefbfdbb0, move=0) at memory.c:343
frame #2: 0x000000010001de14 AtomVM`memory_copy_term_tree(new_heap=0x0000000109e48f90, t=4460867426) at memory.c:160
frame #3: 0x000000010002db45 AtomVM`nif_erlang_spawn_3(ctx=0x0000000109a83ed0, argc=3, argv=0x0000000109a83ef8) at nifs.c:462
frame #4: 0x0000000100005727 AtomVM`context_execute_loop(ctx=0x0000000109a83ed0, mod=0x0000000109a3cf90, function_name="start", arity=0) at opcodesswitch.h:760
frame #5: 0x000000010000148e AtomVM`main(argc=2, argv=0x00007ffeefbff480) at main.c:86
frame #6: 0x00007fff73515ed9 libdyld.dylib`start + 1
when passing the term {state,undefined,test_gen_server,{state,0,0}}
to the proc.
The loop in:
int boxed_size = term_boxed_size(t) + 1;
term *dest = *new_heap;
for (int i = 0; i < boxed_size; i++) {
dest[i] = boxed_value[i];
}
crashes on the last iteration, when the term is {state, 0, 0}
-- boxed_size
in this case is 4, which I assume is 1 for the tuple, and 3 for each of the three elements.
I can get my spawn programs to not crash by ensuring we have enough space in the heap before a spawn.
10:54:54 spock:/work/src/github/fadushin/AtomVM> git diff src/libAtomVM/nifs.c
diff --git a/src/libAtomVM/nifs.c b/src/libAtomVM/nifs.c
index aa6b2a3..d239c59 100644
--- a/src/libAtomVM/nifs.c
+++ b/src/libAtomVM/nifs.c
@@ -457,6 +457,7 @@ static term nif_erlang_spawn_3(Context *ctx, int argc, term argv[])
//TODO: check available registers count
int reg_index = 0;
term t = argv[2];
+ memory_ensure_free(new_ctx, memory_estimate_usage(t));
while (!term_is_nil(t)) {
term *t_ptr = term_get_list_ptr(t);
new_ctx->x[reg_index] = memory_copy_term_tree(&new_ctx->heap_ptr, t_ptr[1]);
Added change to https://github.com/bettio/AtomVM/pull/53
Closed as PR 53 has been merged
I can get AtomVM to crash in some edge cases by passing a list in a nested structure to
spawn
.Here is a sample program that crashes AtomVM:
The output is:
The stack trace is:
We hit the abort statement in this part of the code in
memory_scan_and_copy
: