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

address-sanitizer fires on initialization (hl/c target) #1239

Open
byte0xcafe opened this issue Sep 21, 2024 · 0 comments
Open

address-sanitizer fires on initialization (hl/c target) #1239

byte0xcafe opened this issue Sep 21, 2024 · 0 comments

Comments

@byte0xcafe
Copy link

byte0xcafe commented Sep 21, 2024

Version & system Info:

OS: EndeavourOS Linux x86_64 
compiler:  gcc --version: gcc (GCC) 14.2.1 20240910

haxe --version: 4.3.6
hashlink-1.14 (compiled it myself)
haxelib list:
    domkit: [git]
    format: [3.7.0]
    greeter: [0.1.0]
    hashlink: [0.1.0]
    haxeui-core: [1.7.0]
    haxeui-heaps: [1.7.0]
    heaps: [2.0.0]
    hlc-compiler: [0.3.0]
    hlsdl: [1.14.0]
    hxcpp: [4.3.2]
    hxnativefiledialog: [1.0.0]
    lime-samples: [7.0.0]
    lime: [8.1.2]
    locator: [0.5.0]
    sinker: [0.6.0]

Working on a haxeui project using the heaps.io backend I occasionally got crashes of my app directly on startup (starting it via hashlink as well as using compiled hl/c).

Trying to nail the issue, I compiled my hl/c stuff with address-sanitzer and immediately got a hit in the generated init-code.

To investigate further, I added some printfs to the generated hl/c code and found, that the issue originates from the enum-init-code for some enums from heaps.io, in the run below it seems EventKind triggered it, but I also saw other enums triggering it.

The code seems iterating over some fields (see how r2 goes from 0 to 7) but at some point, the next iteration breaks and in this case, '8' ends up in r4 which is then interpreted as a pointer and triggers ASAN (within hl_types_ArrayObj_push).


[...]
t$hxd_$FlushMode
Type_initEnum @ 110
Type_initEnum @ 135
Type_initEnum @ 140
Type_initEnum @ 142
r6->size: 5
Type_initEnum 'N' 'h'
r12 = 1074034976
R4 = 129365776526064 R2 = 0
Type_initEnum @ 169
Type_initEnum 'S' 'h'
r12 = 1074034976
R4 = 1073961536 R2 = 1
Type_initEnum @ 169
Type_initEnum 'F' 'h'
r12 = 1074034976
R4 = 1074400384 R2 = 2
Type_initEnum @ 169
Type_initEnum 'F' 'h'
r12 = 1074034976
R4 = 1074944128 R2 = 3
Type_initEnum @ 169
Type_initEnum 'B' 'h'
r12 = 1074034976
R4 = 1074944176 R2 = 4
Type_initEnum @ 169
t$hxd_$DialogFlags
Type_initEnum @ 110
Type_initEnum @ 135
Type_initEnum @ 140
Type_initEnum @ 142
r6->size: 2
Type_initEnum 'Y' 'h'
r12 = 1074035576
R4 = 129365776526064 R2 = 0
Type_initEnum @ 169
Type_initEnum 'I' 'h'
r12 = 1074035576
R4 = 1073961824 R2 = 1
Type_initEnum @ 169
t$hxd_$Cursor
Type_initEnum @ 110
Type_initEnum @ 135
Type_initEnum @ 140
Type_initEnum @ 142
r6->size: 7
Type_initEnum 'D' 'h'
r12 = 1074036200
R4 = 129365776526064 R2 = 0
Type_initEnum @ 169
Type_initEnum 'B' 'h'
r12 = 1074036200
R4 = 1073962336 R2 = 1
Type_initEnum @ 169
Type_initEnum 'M' 'h'
r12 = 1074036200
R4 = 1074400544 R2 = 2
Type_initEnum @ 169
Type_initEnum 'T' 'h'
r12 = 1074036200
R4 = 1074947288 R2 = 3
Type_initEnum @ 169
Type_initEnum 'H' 'h'
r12 = 1074036200
R4 = 1074947336 R2 = 4
Type_initEnum @ 169
Type_initEnum 'C' 'h'
r12 = 1074036200
R4 = 1074947392 R2 = 5
Type_initEnum @ 169
Type_initEnum 'C' 'h'
r12 = 1074036200
R4 = 1074947392 R2 = 6
Type_initEnum @ 169
t$hxd_$EventKind    <-- issues happens in init-code for this enum
Type_initEnum @ 110
Type_initEnum @ 135
Type_initEnum @ 140
Type_initEnum @ 142
r6->size: 13
Type_initEnum 'E' 'h'
r12 = 1074036488
R4 = 129365776526064 R2 = 0
Type_initEnum @ 169
Type_initEnum 'E' 'h'
r12 = 1074036488
R4 = 1073962464 R2 = 1
Type_initEnum @ 169
Type_initEnum 'E' 'h'
r12 = 1074036488
R4 = 1074400584 R2 = 2
Type_initEnum @ 169
Type_initEnum 'E' 'h'
r12 = 1074036488
R4 = 1074948024 R2 = 3
Type_initEnum @ 169
Type_initEnum 'E' 'h'
r12 = 1074036488
R4 = 1074948072 R2 = 4
Type_initEnum @ 169
Type_initEnum 'E' 'h'
r12 = 1074036488
R4 = 1074948128 R2 = 5
Type_initEnum @ 169
Type_initEnum 'E' 'h'
r12 = 1074036488
R4 = 1074948128 R2 = 6
Type_initEnum @ 169
Type_initEnum 'E' 'E'
r12 = 1074036488
R4 = 1074933416 R2 = 7
Type_initEnum @ 169
Type_initEnum 'E' 'E'
r12 = 1074036488
R4 = 8 R2 = 1695909888
AddressSanitizer:DEADLYSIGNAL
=================================================================
==18292==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000018 (pc 0x567e642c78e8 bp 0x7ffd00d83a10 sp 0x7ffd00d83970 T0)
==18292==The signal is caused by a READ memory access.
==18292==Hint: address points to the zero page.
    #0 0x567e642c78e8 in hl_types_ArrayObj_push /tmp/build/hl/types/ArrayObj.c:134:11
    #1 0x567e647c50ba in Type_initEnum /tmp/build/_std/Type.c:168:8
    #2 0x567e64f2c037 in fun$init /tmp/build/hl/init.c:10993:8
    #3 0x567e64fee2f3 in hl_entry_point /tmp/build/plastyx.c:1019:2
    #4 0x567e642770bd in hlc_static_call /tmp/build/hl/reflect.c:17:4
    #5 0x75a851235993 in hl_call_method /tmp/hashlink-1.14/src/std/fun.c:197:8
    #6 0x75a851235c7e in hl_dyn_call /tmp/hashlink-1.14/src/std/fun.c:244:9
    #7 0x75a851236ad9 in hl_dyn_call_safe /tmp/hashlink-1.14/src/std/fun.c:473:8
    #8 0x567e6427695d in main /tmp/hashlink/hashlink-1.14_debug/include/hlc_main.c:158:8
    #9 0x75a850fb6e07 in __libc_start_call_main /usr/src/debug/glibc/glibc/csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #10 0x75a850fb6ecb in __libc_start_main /usr/src/debug/glibc/glibc/csu/../csu/libc-start.c:360:3
    #11 0x567e64141c34 in _start (/tmp/build/main+0x58fc34) (BuildId: c9a8d7f974e483bc7604dce3b4bf887028ed0aec)


AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /tmp/build/hl/types/ArrayObj.c:134:11 in hl_types_ArrayObj_push
==18292==ABORTING

The characters printed out above originate from my instrumentation in

hl__Enum Type_initEnum(hl_type* r0,hl_type* r1) : 
[...]
	if( r12 == NULL ) hl_null_access();
	printf("Type_initEnum '%s' '%s'\n", r8, r3->_hx___ename__->bytes);
	printf("r12 = %lu\n", (uint64_t)r12);
	r15 = hl_types_ArrayObj_push(r12,((vdynamic*)r9));
	PRINT_LINE("Type_initEnum");
	goto label$9fea9d9_3_29;
[...]

And here the generated hl_types_ArrayObj_push function:

int hl_types_ArrayObj_push(hl__types__ArrayObj r0,vdynamic* r1) {
	varray *r4, *r6;
	int r2, r5;
	r2 = r0->length;
	r4 = r0->array;
	//if(r4 == 0){
		printf("R4 = %lu R2 = %u\n", (uint64_t)r4, r2);
	//}
	r5 = r4->size;
	if( r5 != r2 ) goto label$1b258ef_5_6;
	hl_types_ArrayObj___expand(r0,r2);
	goto label$1b258ef_5_9;
	label$1b258ef_5_6:
	r5 = r0->length;
	++r5;
	r0->length = r5;
	label$1b258ef_5_9:
	r6 = r0->array;
	((vdynamic**)(r6 + 1))[r2] = r1;
	r5 = r0->length;
	return r5;
}

To ensure, the issue is not related to my code, which includes native extensions, I tried to reproduce with the heaps.io-hello-world-project.
ASAN fires for this as well directly on startup and it is also an out-of-bounds READ but different location:

AddressSanitizer:DEADLYSIGNAL
=================================================================
==19477==ERROR: AddressSanitizer: SEGV on unknown address 0x00004020000d (pc 0x7c958e11ab30 bp 0x7ffc084c5390 sp 0x7ffc084c5368 T0)
==19477==The signal is caused by a READ memory access.
    #0 0x7c958e11ab30 in __sanitizer_internal_memmove /usr/src/debug/gcc/gcc/libsanitizer/sanitizer_common/sanitizer_libc.cpp:75
    #1 0x7c958dfa4eb8 in hl_bytes_blit (/tmp/hashlink/tmp/hashlink-1.14/build//bin/libhl.so.1+0x69eb8) (BuildId: 771e3fba1794b2b8e54a9f23982d5d7ce0bef4ce)
    #2 0x60572e9f914d in hl_types_ArrayBytes_hl_UI16___expand hl/types/ArrayBytes_hl_UI16.c:1051
    #3 0x60572e9f4fb6 in hl_types_ArrayBytes_hl_UI16_push hl/types/ArrayBytes_hl_UI16.c:186
    #4 0x60572ea1d77b in h3d_impl_MemoryManager_initIndexes h3d/impl/MemoryManager.c:115
    #5 0x60572ea1d57d in h3d_impl_MemoryManager_init h3d/impl/MemoryManager.c:74
    #6 0x60572ea14fe6 in h3d_Engine_onCreate h3d/Engine.c:505
    #7 0x60572ed17631 in h3d_impl_GlDriver_init__$1 h3d/impl/GlDriver.c:5603
    #8 0x60572ebfbc18 in haxe_Timer_delay__$1 haxe/Timer.c:70
    #9 0x60572ebfb880 in haxe_Timer_new__$1 haxe/Timer.c:21
    #10 0x60572ebf77b4 in sys_thread_EventLoop_progress sys/thread/EventLoop.c:232
    #11 0x60572ee5b32f in hxd_System_runMainLoop hxd/System.c:312
    #12 0x60572ebfbc49 in haxe_Timer_delay__$1 haxe/Timer.c:70
    #13 0x60572ebfb880 in haxe_Timer_new__$1 haxe/Timer.c:21
    #14 0x60572ebf91a5 in sys_thread_EventLoop_loop sys/thread/EventLoop.c:491
    #15 0x60572f08c3d5 in sys_thread__Thread_Thread_Impl__processEvents sys/thread/_Thread/Thread_Impl_.c:43
    #16 0x60572f109cba in fun$init hl/init.c:11886
    #17 0x60572f16d70b in hl_entry_point /tmp/repro3/build/Main.c:521
    #18 0x60572f10c96c in hlc_static_call hl/reflect.c:17
    #19 0x7c958dfab1e9 in hl_call_method (/tmp/hashlink/tmp/hashlink-1.14/build//bin/libhl.so.1+0x701e9) (BuildId: 771e3fba1794b2b8e54a9f23982d5d7ce0bef4ce)
    #20 0x7c958dfab4d0 in hl_dyn_call (/tmp/hashlink/tmp/hashlink-1.14/build//bin/libhl.so.1+0x704d0) (BuildId: 771e3fba1794b2b8e54a9f23982d5d7ce0bef4ce)
    #21 0x7c958dfac2f4 in hl_dyn_call_safe (/tmp/hashlink/tmp/hashlink-1.14/build//bin/libhl.so.1+0x712f4) (BuildId: 771e3fba1794b2b8e54a9f23982d5d7ce0bef4ce)
    #22 0x60572e9d217a in main /tmp/hashlink/tmp/hashlink-1.14/build//../src/hlc_main.c:158
    #23 0x7c958da59e07  (/usr/lib/libc.so.6+0x25e07) (BuildId: 98b3d8e0b8c534c769cb871c438b4f8f3a8e4bf3)
    #24 0x7c958da59ecb in __libc_start_main (/usr/lib/libc.so.6+0x25ecb) (BuildId: 98b3d8e0b8c534c769cb871c438b4f8f3a8e4bf3)
    #25 0x60572e9d19b4 in _start (/tmp/repro3/build/Main+0x4089b4) (BuildId: 2eaee664e7adb445e3b705f611a49f14b8d70801)

The Main.hx is simply the hello-world-heaps example:

class Main extends hxd.App {
    override function init() {
        var tf = new h2d.Text(hxd.res.DefaultFont.get(), s2d);
        tf.text = "Hello World !";
    }
    static function main() {
        new Main();
    }
}

Compiled to hl/c like this:

haxe --main Main -lib heaps -lib hlsdl -debug -hl build/Main.c

And natively compiled like so:

gcc -o Main Main.c -I . -I ${HL}/../src -L ${HL}/bin/ -lhl -g -lSDL2 ${HL}/bin/uv.hdll ${HL}/bin/sdl.hdll ${HL}/bin/fmt.hdll ${HL}/bin/ui.hdll -luv -fsanitize=address -lSDL2 -lm

Where HL points to the hashlink-1.14 build/source.

The hello-world Haxe example runs smoothly though.

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

1 participant