v icon indicating copy to clipboard operation
v copied to clipboard

runtime crash (sigtramp) when using enum instead of int in map

Open thomas-mangin opened this issue 2 years ago • 0 comments

Describe the bug

I changed some maps from using string indexing to using an enum. The code was working with strings. Using the enum, it is now crashing. Replacing the enum with an int, the problem goes away.

The issue occurs with the normal bohem GC or if -gc none is passed.

Expected Behavior

Happy V coding without crash :wink:

Current Behavior

v run bug-mem.v
signal 11: segmentation fault
0   libsystem_platform.dylib            0x000000019313c2a4 _sigtramp + 56
1   bug-mem                             0x0000000104be9874 GC_try_to_collect_inner + 404
2   bug-mem                             0x0000000104be9874 GC_try_to_collect_inner + 404
3   bug-mem                             0x0000000104bf1a18 GC_collect_or_expand + 216
4   bug-mem                             0x0000000104bdf890 GC_generic_malloc_inner + 884
5   bug-mem                             0x0000000104be525c GC_generic_malloc_aligned + 108
6   bug-mem                             0x0000000104be54f0 GC_malloc_kind_global + 244
7   bug-mem                             0x0000000104bb8abc vcalloc + 188
8   bug-mem                             0x0000000104bd04d4 map_cached_rehash + 80
9   bug-mem                             0x0000000104bd0410 map_expand + 124
10  bug-mem                             0x0000000104bb9f7c map_set + 96
11  bug-mem                             0x0000000104bddb50 main__main + 440
12  bug-mem                             0x0000000104bde3d0 main + 84
13  dyld                                0x0000000192de3e50 start + 2544

Reproduction Steps

module main

enum MyBigEnum as u8 {
	_00
	_01
	_02
	_03
	_04
	_05
	_06
	_07
	_08
	_09
	_10
	_11
	_12
	_13
	_14
	_15
	_16
	_17
	_18
	_19
	_20
	_21
	_22
	_23
	_24
	_25
	_26
	_27
	_28
	_29
}

type Bug = map[MyBigEnum]string

fn main() {
	mut b := Bug(map[MyBigEnum]string{})
	
	for e in [MyBigEnum._00, ._01, ._02, ._03, ._04, ._05, ._06, ._07, ._08, ._09, ._10, ._11, ._12, ._13, ._14, ._15, ._16, ._17, ._18, ._19, ._20, ._21, ._22, ._23, ._24, ._25, ._26, ._27, ._28, ._29] {
		v := b[e] or {
			new_data := '......................................'
			b[e] = new_data
			new_data
		}		
		_ := v
	}
}

Possible Solution

Replacing the enum with an int, the issue seems to go away, but looking at the difference in C generation, I could not figure out why. It may also be possible to provide a str() function to the enum and index using string (which worked previously).

type NotBug = map[int]string

fn main() {
	mut b := NotBug(map[int]string{})

	for e in u8(0)..u8(30) {
		v := b[e] or {
			new_data := '......................................'
			b[e] = new_data
			new_data
		}		
		_ := v
	}
}

Additional Information/Context

the difference in code generation is:

--- broken.c	2023-03-20 22:57:41
+++ works.c	2023-03-20 22:57:27
@@ -805,42 +805,7 @@
 	StrIntpType__si_p, // 0+17
 	StrIntpType__si_vp, // 0+18
 }  StrIntpType;
-#pragma pack(push, 1)
-typedef enum {
-	main__MyBigEnum___00, // 
-	main__MyBigEnum___01, // +1
-	main__MyBigEnum___02, // +2
-	main__MyBigEnum___03, // +3
-	main__MyBigEnum___04, // +4
-	main__MyBigEnum___05, // +5
-	main__MyBigEnum___06, // +6
-	main__MyBigEnum___07, // +7
-	main__MyBigEnum___08, // +8
-	main__MyBigEnum___09, // +9
-	main__MyBigEnum___10, // +10
-	main__MyBigEnum___11, // +11
-	main__MyBigEnum___12, // +12
-	main__MyBigEnum___13, // +13
-	main__MyBigEnum___14, // +14
-	main__MyBigEnum___15, // +15
-	main__MyBigEnum___16, // +16
-	main__MyBigEnum___17, // +17
-	main__MyBigEnum___18, // +18
-	main__MyBigEnum___19, // +19
-	main__MyBigEnum___20, // +20
-	main__MyBigEnum___21, // +21
-	main__MyBigEnum___22, // +22
-	main__MyBigEnum___23, // +23
-	main__MyBigEnum___24, // +24
-	main__MyBigEnum___25, // +25
-	main__MyBigEnum___26, // +26
-	main__MyBigEnum___27, // +27
-	main__MyBigEnum___28, // +28
-	main__MyBigEnum___29, // +29
-} __attribute__((packed)) main__MyBigEnum;
-#pragma pack(pop)
 
-
 // Thread definitions:
 typedef pthread_t __v_thread;
 
@@ -939,7 +904,7 @@
 typedef string Array_fixed_string_11 [11];
 typedef voidptr Array_fixed_voidptr_11 [11];
 typedef array Array_RepIndex;
-typedef map Map_main__MyBigEnum_string;
+typedef map Map_int_string;
 typedef map Map_string_int;
 typedef u8 Array_fixed_u8_5 [5];
 typedef array Array_u64;
@@ -951,9 +916,8 @@
 typedef voidptr Array_fixed_voidptr_100 [100];
 typedef u8 Array_fixed_u8_17 [17];
 typedef array Array_StrIntpType;
-typedef array Array_main__MyBigEnum;
 typedef Array_u8 strings__Builder;
-typedef Map_main__MyBigEnum_string main__Bug;
+typedef Map_int_string main__NotBug;
 typedef bool (*anon_fn_voidptr__bool)(voidptr);
 typedef voidptr (*anon_fn_voidptr__voidptr)(voidptr);
 typedef int (*anon_fn_voidptr_voidptr__int)(voidptr,voidptr);
@@ -12491,31 +12455,25 @@
 
 // TypeDecl
 VV_LOCAL_SYMBOL void main__main(void) {
-	main__Bug b = ((new_map_noscan_key(sizeof(main__MyBigEnum), sizeof(string), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop)
+	main__NotBug b = ((new_map_noscan_key(sizeof(int), sizeof(string), &map_hash_int_4, &map_eq_int_4, &map_clone_int_4, &map_free_nop)
 	));
-	Array_main__MyBigEnum _t1 = new_array_from_c_array_noscan(30, 30, sizeof(main__MyBigEnum), _MOV((main__MyBigEnum[30]){
-			main__MyBigEnum___00, main__MyBigEnum___01, main__MyBigEnum___02, main__MyBigEnum___03, main__MyBigEnum___04, main__MyBigEnum___05, main__MyBigEnum___06, main__MyBigEnum___07, main__MyBigEnum___08,
-			main__MyBigEnum___09, main__MyBigEnum___10, main__MyBigEnum___11, main__MyBigEnum___12, main__MyBigEnum___13, main__MyBigEnum___14, main__MyBigEnum___15, main__MyBigEnum___16,
-			main__MyBigEnum___17, main__MyBigEnum___18, main__MyBigEnum___19, main__MyBigEnum___20, main__MyBigEnum___21, main__MyBigEnum___22, main__MyBigEnum___23, main__MyBigEnum___24,
-			main__MyBigEnum___25, main__MyBigEnum___26, main__MyBigEnum___27, main__MyBigEnum___28, main__MyBigEnum___29}));
-	for (int _t2 = 0; _t2 < _t1.len; ++_t2) {
-		main__MyBigEnum e = ((main__MyBigEnum*)_t1.data)[_t2];
-		string* _t4 = (string*)(map_get_check(ADDR(map, b), &(main__MyBigEnum[]){e}));
-		_option_string _t3 = {0};
-		if (_t4) {
-			*((string*)&_t3.data) = *((string*)_t4);
+	for (u8 e = ((u8)(0)); e < ((u8)(30)); ++e) {
+		string* _t2 = (string*)(map_get_check(ADDR(map, b), &(int[]){e}));
+		_option_string _t1 = {0};
+		if (_t2) {
+			*((string*)&_t1.data) = *((string*)_t2);
 		} else {
-			_t3.state = 2; _t3.err = _v_error(_SLIT("array index out of range"));
+			_t1.state = 2; _t1.err = _v_error(_SLIT("array index out of range"));
 		}
 		;
-		if (_t3.state != 0) {
-			IError err = _t3.err;
+		if (_t1.state != 0) {
+			IError err = _t1.err;
 			string new_data = _SLIT("......................................");
-			map_set(&b, &(main__MyBigEnum[]){e}, &(string[]) { new_data });
-			*(string*) _t3.data = new_data;
+			map_set(&b, &(int[]){e}, &(string[]) { new_data });
+			*(string*) _t1.data = new_data;
 		}
 		
-		string v = (*(string*)_t3.data);
+		string v = (*(string*)_t1.data);
 		{string _ = v;}
 		;
 	}

V version

V 0.3.3 968b519

Environment details (OS name and version, etc.)

V full version: V 0.3.3 3197ec1.968b519
OS: macos, macOS, 13.2.1, 22D68
Processor: 10 cpus, 64bit, little endian, Apple M1 Max

getwd: /Users/thomas/Code/github.com/ze-core/network/bugs
vexe: /Users/thomas/Unix/local/v/v
vexe mtime: 2023-03-20 21:23:47

vroot: OK, value: /Users/thomas/Unix/local/v
VMODULES: NOT writable, value: /Users/thomas/Unix/data/v/modules
VTMP: OK, value: /tmp/v_501

Git version: git version 2.39.2
Git vroot status: weekly.2023.11-42-g968b519b-dirty
.git/config present: true

CC version: Apple clang version 14.0.0 (clang-1400.0.29.202)
thirdparty/tcc status: thirdparty-macos-arm64 a668e5a0

thomas-mangin avatar Mar 20 '23 23:03 thomas-mangin