From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id AD69E3858D28; Sun, 21 Apr 2024 21:41:24 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AD69E3858D28 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1713735684; bh=xRPql8EQQgu1k7Gu3O8owGWlz8zw/DfiqTljIysIRZg=; h=From:To:Subject:Date:From; b=Z6brmGNiM2OIOmATMyYht+dAEte9LOGQPj8UV1eIwFX5bIxlBVNKdjtvbkqmDMzJf WE1cVMSXy9BXGkdmWCdkc/R43dijlHg1wn01H68rTP/jMrwLz45Fd0hBUJZAmJGOdc 09ZFUCQ6FuRf5IUEDUQz3YfVwkuGsA95isrsj4AM= From: "thiago.bauermann at linaro dot org" To: gdb-prs@sourceware.org Subject: [Bug breakpoints/31665] New: [arm] Hardware watchpoints trigger at the wrong place with memset/memcopy/memmove Date: Sun, 21 Apr 2024 21:41:23 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gdb X-Bugzilla-Component: breakpoints X-Bugzilla-Version: HEAD X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: thiago.bauermann at linaro dot org X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P2 X-Bugzilla-Assigned-To: unassigned at sourceware dot org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter target_milestone attachments.created Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://sourceware.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 List-Id: https://sourceware.org/bugzilla/show_bug.cgi?id=3D31665 Bug ID: 31665 Summary: [arm] Hardware watchpoints trigger at the wrong place with memset/memcopy/memmove Product: gdb Version: HEAD Status: UNCONFIRMED Severity: normal Priority: P2 Component: breakpoints Assignee: unassigned at sourceware dot org Reporter: thiago.bauermann at linaro dot org Target Milestone: --- Created attachment 15476 --> https://sourceware.org/bugzilla/attachment.cgi?id=3D15476&action=3Ded= it Disassembly of __memcpy_neon, also used for memmove. On an armv8l-linux-gnueabihf system, hardware watchpoints only trigger at the end of the inferior execution instead of in memset, memcpy, or memmove. E.g., with the following program (which I'm posting upstream as part of gdb.base/memops-watchpoint.exp): #include #include int main (void) { /* Some targets need 4-byte alignment for hardware watchpoints. */ char s[40] __attribute__ ((aligned (4))) =3D "This is a relatively long string..."; char a[40] __attribute__ ((aligned (4))) =3D "String to be overwritten with zeroes"; char b[40] __attribute__ ((aligned (4))) =3D "Another string to be memcopied..."; char c[40] __attribute__ ((aligned (4))) =3D "Another string to be memmoved..."; /* Break here. */ memset (a, 0, sizeof (a)); memcpy (b, s, sizeof (b)); memmove (c, s, sizeof (c)); printf ("b =3D '%s'\n", b); printf ("c =3D '%s'\n", c); return 0; } Compiled with: $ gcc -fno-builtin-memset \ -fno-builtin-memcpy \ -fno-builtin-memmove \ -g \ -o /tmp/memops-watchpoint \ /tmp/memops-watchpoint.c This happens: (gdb) break 18 Breakpoint 1 at 0x6bc: file /tmp/memops-watchpoint.c, line 18. (gdb) r Starting program: /tmp/memops-watchpoint [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1= ". Breakpoint 1, main () at /tmp/memops-watchpoint.c:18 18 memset (a, 0, sizeof (a)); (gdb) watch -location a[28] Hardware watchpoint 2: -location a[28] (gdb) c Continuing. b =3D 'This is a relatively long string...' c =3D 'This is a relatively long string...' Hardware watchpoint 2: -location a[28] Old value =3D 104 'h' New value =3D 3 '\003' 0xf7fc2868 in _dl_fini () at dl-fini.c:68 warning: 68 dl-fini.c: No such file or directory (gdb) bt #0 0xf7fc2868 in _dl_fini () at dl-fini.c:68 #1 0xf7ebe506 in __run_exit_handlers (status=3D0, listp=3D0xf7fae534 <__exit_funcs>, run_list_atexit=3Drun_list_atexit@entry=3Dtrue, run_dtors=3Drun_dtors@entry=3Dtrue) at exit.c:113 #2 0xf7ebe612 in __GI_exit (status=3D) at exit.c:143 #3 0xf7ead7da in __libc_start_call_main (main=3D0x400625
, main@entry=3D0xf7fae000, argc=3D1, argc@entry=3D-134549128, argv=3D0xfffef3= 64, argv@entry=3D0xf7faf380 <__exit_funcs_lock>) at ../sysdeps/nptl/libc_start_call_main.h:74 #4 0xf7ead886 in __libc_start_main_impl (main=3D0xf7fae000, argc=3D-134549= 128, argv=3D0xf7faf380 <__exit_funcs_lock>, init=3D, fini=3D0x0, rtld_fini=3D0xf7fc27d9 <_dl_fini>, stack_end=3D0xfffef364) at libc-start.c:392 #5 0x00400550 in _start () Backtrace stopped: previous frame identical to this frame (corrupt stack?) (gdb) The same behaviour is seen with memcpy and memmove. In the example above, that would be when watching b[28] and c[28]. When using software watchpoints, it works as expected: (gdb) break 18 Breakpoint 1 at 0x6bc: file /tmp/memops-watchpoint.c, line 18. (gdb) r Starting program: /tmp/memops-watchpoint=20 [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1= ". Breakpoint 1, main () at /tmp/memops-watchpoint.c:18 18 memset (a, 0, sizeof (a)); (gdb) set can-use-hw-watchpoints 0 (gdb) watch -location a[28] Watchpoint 2: -location a[28] (gdb) c Continuing. Watchpoint 2: -location a[28] Old value =3D 104 'h' New value =3D 0 '\000' memset () at ../sysdeps/arm/memset.S:52 warning: 52 ../sysdeps/arm/memset.S: No such file or directory (gdb) bt #0 memset () at ../sysdeps/arm/memset.S:52 #1 0x004006ca in main () at /tmp/memops-watchpoint.c:18 (gdb)=20 memset here is: (gdb) disassemble Dump of assembler code for function memset: 0xf7efc1e0 <+0>: mov r3, r0 0xf7efc1e4 <+4>: cmp r2, #8 0xf7efc1e8 <+8>: bcc 0xf7efc234 0xf7efc1ec <+12>: tst r3, #3 0xf7efc1f0 <+16>: strbne r1, [r3], #1 0xf7efc1f4 <+20>: subne r2, r2, #1 0xf7efc1f8 <+24>: bne 0xf7efc1ec 0xf7efc1fc <+28>: and r1, r1, #255 @ 0xff 0xf7efc200 <+32>: orr r1, r1, r1, lsl #8 0xf7efc204 <+36>: orr r1, r1, r1, lsl #16 0xf7efc208 <+40>: mov r12, r1 0xf7efc20c <+44>: subs r2, r2, #8 0xf7efc210 <+48>: stmiacs r3!, {r1, r12} 0xf7efc214 <+52>: subscs r2, r2, #8 0xf7efc218 <+56>: stmiacs r3!, {r1, r12} 0xf7efc21c <+60>: subscs r2, r2, #8 0xf7efc220 <+64>: stmiacs r3!, {r1, r12} 0xf7efc224 <+68>: subscs r2, r2, #8 0xf7efc228 <+72>: stmiacs r3!, {r1, r12} =3D> 0xf7efc22c <+76>: bcs 0xf7efc20c 0xf7efc230 <+80>: and r2, r2, #7 0xf7efc234 <+84>: subs r2, r2, #1 0xf7efc238 <+88>: strbcs r1, [r3], #1 0xf7efc23c <+92>: subscs r2, r2, #1 0xf7efc240 <+96>: strbcs r1, [r3], #1 0xf7efc244 <+100>: subscs r2, r2, #1 0xf7efc248 <+104>: strbcs r1, [r3], #1 0xf7efc24c <+108>: subscs r2, r2, #1 0xf7efc250 <+112>: strbcs r1, [r3], #1 0xf7efc254 <+116>: bcs 0xf7efc234 0xf7efc258 <+120>: bx lr End of assembler dump. (gdb)=20 The disassembly of __memcpy_neon (used in this machine) is somewhat big, so I'll attach it instead. memmove also uses __memcpy_neon. This is with a 32-bit Ubuntu 22.04 userland running on a 64-bit kernel 5.4.0-131-generic, with a Neoverse-N1 processor. --=20 You are receiving this mail because: You are on the CC list for the bug.=