https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112730
Bug ID: 112730 Summary: Wrong code generated with Address Sanitizer for a call to a callback in contained subroutine, mapping not executable Product: gcc Version: 13.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: sanitizer Assignee: unassigned at gcc dot gnu.org Reporter: trnka at scm dot com CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org, jakub at gcc dot gnu.org, kcc at gcc dot gnu.org, marxin at gcc dot gnu.org Target Milestone: --- Created attachment 56696 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=56696&action=edit Testcase reproducing the issue The attached testcase works fine when compiled without sanitizers, prints a single dot and OK. When compiled with -fsanitize=address, it segfaults attempting the call to traverse_callback() inside traverse(). The problem seems to occur on GCC 9 through 14, at least. #0 0x0000155552500030 in ?? () #1 0x00000000004016b2 in json_traverse::traverse (p=0x602000000070) at test-json_traverse-minimal.f90:65 #2 0x00000000004017e1 in json_value_module::json_traverse ( json=<error reading variable: Cannot access memory at address 0x0>, p=0x602000000070, traverse_callback=0x0) at test-json_traverse-minimal.f90:55 #3 0x0000000000401609 in json_value_module::json_check_all_for_duplicate_keys (json=..., p=0x602000000070) at test-json_traverse-minimal.f90:80 #4 0x00000000004019a2 in test_json_traverse () at test-json_traverse-minimal.f90:111 The location in RIP seems to contain some sort of a trampoline: (gdb) disass $rip,+40 Dump of assembler code from 0x155552500030 to 0x155552500058: => 0x0000155552500030: mov $0x401244,%r11d 0x0000155552500036: movabs $0x155552500030,%r10 0x0000155552500040: rex.WB jmp *%r11 0x0000155552500043: nop … Here, $0x401244 is indeed the address of the callback which should get executed: (gdb) disass 0x00401244 Dump of assembler code for function json_check_all_for_duplicate_keys::duplicate_key_func: 0x0000000000401244 <+0>: push %rbp 0x0000000000401245 <+1>: mov %rsp,%rbp 0x0000000000401248 <+4>: push %r14 … The segfault is probably because the mapping containing the trampoline is not executable: (gdb) info proc mappings process 41564 Mapped address spaces: Start Addr End Addr Size Offset Perms objfile … 0x1555523f7000 0x155552f00000 0xb09000 0x0 rw-p …