[PATCH v2 0/4] Add another way to check for MTE-tagged addresses on remote targets
Gustavo Romero
gustavo.romero@linaro.org
Thu Apr 4 05:35:24 GMT 2024
On 4/3/24 11:39 AM, Luis Machado wrote:
> On 4/3/24 15:29, Gustavo Romero wrote:
>> Hi Luis,
>>
>> On 4/3/24 8:51 AM, Luis Machado wrote:
>>> Hi,
>>>
>>> On 3/28/24 22:48, Gustavo Romero wrote:
>>>> This series introduces a new method to check for MTE-tagged addresses on
>>>> remote targets.
>>>>
>>>> A new remote packet, qMemTagAddrCheck, is introduced, along with a new
>>>> remote feature associated with it, 'memory-tagging-check-add+'. Only
>>>> when 'memory-tagging-check-add+' feature is advertised GDB will use the
>>>> new packet to query if an address is tagged.
>>>>
>>>> This new mechanism allows for checking MTE addresses in an OS-agnostic
>>>> way, which is necessary when debugging targets that do not support
>>>> '/proc/<PID>/smaps', as the current method of reading the smaps contents
>>>> fails in such cases.
>>>>
>>>> Since v1:
>>>> - Fixed build error "no match for ‘operator!=’ (operand types are ‘packet_result’ and ‘packet_status’)"
>>>> reported by Linaro CI bot, caused by a last-minute rebase;
>>>> - Added instructions on how to test the series on a remote target using
>>>> QEMU gdbstub (-g option) -- see below.
>>>> ----
>>>>
>>>> This series can be tested with the 'mte_t' binary found in:
>>>> https://people.linaro.org/~gustavo.romero/gdb, using the GDB
>>>> 'memory-tag print-allocation-tag' command to show the allocation
>>>> tag for array pointer 'a'. To download mte_t:
>>>>
>>>> $ wget https://people.linaro.org/~gustavo.romero/gdb/mte_t
>>>> $ chmod +x ./mte_t
>>>>
>>>> ... or build it from source:
>>>>
>>>> $ wget https://people.linaro.org/~gustavo.romero/gdb/mte_t.c
>>>> $ gcc -march=armv8.5-a+memtag -static -g3 -O0 mte_t.c -o mte_t
>>>>
>>>> For example, testing the address check for the aarch64_linux_nat.c
>>>> target:
>>>>
>>>> gromero@arm64:~/code$ ~/git/binutils-gdb_remote/build/gdb/gdb -q ./mte_t
>>>> Reading symbols from ./mte_t...
>>>> (gdb) run
>>>> Starting program: /home/gromero/code/mte_t
>>>> a[] address is 0xfffff7ffc000
>>>> a[0] = 1 a[1] = 2
>>>> 0x100fffff7ffc000
>>>> a[0] = 3 a[1] = 2
>>>> Expecting SIGSEGV...
>>>>
>>>> Program received signal SIGSEGV, Segmentation fault
>>>> Memory tag violation
>>>> Fault address unavailable.
>>>> 0x0000000000418658 in write ()
>>>> (gdb) bt
>>>> #0 0x0000000000418658 in write ()
>>>> #1 0x000000000040a3bc in _IO_new_file_write ()
>>>> #2 0x0000000000409574 in new_do_write ()
>>>> #3 0x000000000040ae20 in _IO_new_do_write ()
>>>> #4 0x000000000040b55c in _IO_new_file_overflow ()
>>>> #5 0x0000000000407414 in puts ()
>>>> #6 0x000000000040088c in main () at mte_t.c:119
>>>> (gdb) frame 6
>>>> #6 0x000000000040088c in main () at mte_t.c:119
>>>> 119 printf("...haven't got one\n");
>>>> (gdb) memory-tag print-logical-tag a
>>>> $1 = 0x1
>>>> (gdb) memory-tag print-allocation-tag &a[16]
>>>> $2 = 0x0
>>>> (gdb) # Tag mismatch
>>>> (gdb)
>>>>
>>>>
>>>> Testing address check on a core file:
>>>>
>>>> gromero@arm64:~/code$ ulimit -c unlimited
>>>> gromero@arm64:~/code$ ./mte_t
>>>> a[] address is 0xffffb3bcc000
>>>> a[0] = 1 a[1] = 2
>>>> 0x900ffffb3bcc000
>>>> a[0] = 3 a[1] = 2
>>>> Expecting SIGSEGV...
>>>> Segmentation fault (core dumped)
>>>> gromero@arm64:~/code$ ~/git/binutils-gdb_remote/build/gdb/gdb -q ./mte_t ./core
>>>> Reading symbols from ./mte_t...
>>>> [New LWP 256036]
>>>> Core was generated by `./mte_t'.
>>>> Program terminated with signal SIGSEGV, Segmentation fault
>>>> Memory tag violation
>>>> Fault address unavailable.
>>>> #0 0x0000000000418658 in write ()
>>>> (gdb) bt
>>>> #0 0x0000000000418658 in write ()
>>>> #1 0x000000000040a3bc in _IO_new_file_write ()
>>>> #2 0x0000000000409574 in new_do_write ()
>>>> #3 0x000000000040ae20 in _IO_new_do_write ()
>>>> #4 0x000000000040b55c in _IO_new_file_overflow ()
>>>> #5 0x0000000000407414 in puts ()
>>>> #6 0x000000000040088c in main () at mte_t.c:119
>>>> (gdb) frame 6
>>>> #6 0x000000000040088c in main () at mte_t.c:119
>>>> 119 printf("...haven't got one\n");
>>>> (gdb) memory-tag print-logical-tag a
>>>> $1 = 0x9
>>>> (gdb) memory-tag print-allocation-tag &a[16]
>>>> $2 = 0x0
>>>> (gdb) # Tag mismatch
>>>> (gdb)
>>>>
>>>>
>>>> And, finally, testing it on a remote target using QEMU gdbstub
>>>> which supports the new 'memory-tagging-check-add+' feature (WIP).
>>>>
>>>> Clone and build QEMU:
>>>>
>>>> $ git clone --depth=1 --single-branch -b mte https://github.com/gromero/qemu.git
>>>> $ mkdir qemu/build && cd qemu/build
>>>> $ ../configure --target-list=aarch64-linux-user --disable-docs
>>>> $ make -j
>>>> $ wget https://people.linaro.org/~gustavo.romero/gdb/mte_t
>>>> $ chmod +x ./mte_t
>>>> $ ./qemu-aarch64 -g 1234 ./mte_t
>>>>
>>>> ... and connect to QEMU gdbstub from GDB:
>>>>
>>>> gromero@amd:~/git/binutils-gdb/build$ ./gdb/gdb -q
>>>> (gdb) target remote localhost:1234
>>>> Remote debugging using localhost:1234
>>>> Reading /tmp/qemu/build/mte_t from remote target...
>>>> warning: File transfers from remote targets can be slow. Use "set sysroot" to access files locally instead.
>>>> Reading /tmp/qemu/build/mte_t from remote target...
>>>> Reading symbols from target:/tmp/qemu/build/mte_t...
>>>> (gdb) c
>>>> Continuing.
>>>>
>>>> Program received signal SIGSEGV, Segmentation fault
>>>> Memory tag violation
>>>> Fault address unavailable.
>>>> 0x0000000000407290 in puts ()
>>>> (gdb) bt
>>>> #0 0x0000000000407290 in puts ()
>>>> #1 0x000000000040088c in main () at mte_t.c:119
>>>> (gdb) frame 1
>>>> #1 0x000000000040088c in main () at mte_t.c:119
>>>> 119
>>>> (gdb) memory-tag print-allocation-tag a
>>>> $1 = 0x2
>>>> (gdb) set debug remote on
>>>> (gdb) memory-tag print-allocation-tag a
>>>> [remote] Sending packet: $qMemTagAddrCheck:200400000802000#1f
>>>> [remote] Received Ack
>>>> [remote] Packet received: 01
>>>> [remote] Sending packet: $qMemTags:400000802000,1:1#6f
>>>> [remote] Received Ack
>>>> [remote] Packet received: m02
>>>> $2 = 0x2
>>>> (gdb)
>>>
>>> Out of curiosity, I see you exercised native, core and QEMU-based remote debugging. Did you give the gdbserver-based remote debugging a try?
>>>
>>> I think that is an important check given a gdb + gdbserver debugging session will also use the remote target, but will instead rely on accessing the remote smaps file.
>>
>> Nope. I'll give it a try before sending v3 today.
>
> Awesome. Thanks.
The fallback mechanism works when tested against the gdbserver.
I'll paste the results into the cover letter for v3. That's a nice test, thanks!
Cheers,
Gustavo
More information about the Gdb-patches
mailing list