From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id bfsyCcOJ4mj5ZiAAWB0awg (envelope-from ) for ; Sun, 05 Oct 2025 11:07:47 -0400 Authentication-Results: simark.ca; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=dominicclifton.name header.i=@dominicclifton.name header.a=rsa-sha256 header.s=email header.b=id0Sb21W; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 171621E0B6; Sun, 05 Oct 2025 11:07:47 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIM_INVALID,DKIM_SIGNED,HTML_MESSAGE,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,RCVD_IN_VALIDITY_CERTIFIED_BLOCKED, RCVD_IN_VALIDITY_RPBL_BLOCKED,RCVD_IN_VALIDITY_SAFE_BLOCKED autolearn=ham autolearn_force=no version=4.0.1 Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id F24411E047 for ; Sun, 05 Oct 2025 11:07:44 -0400 (EDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 823F83858D38 for ; Sun, 5 Oct 2025 15:07:38 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 823F83858D38 Authentication-Results: sourceware.org; dkim=fail reason="signature verification failed" (1024-bit key, unprotected) header.d=dominicclifton.name header.i=@dominicclifton.name header.a=rsa-sha256 header.s=email header.b=id0Sb21W Received: from mx03.hydraservices.com (mx03.hydraservices.com [82.113.145.160]) by sourceware.org (Postfix) with ESMTPS id A45D43858C83 for ; Sun, 5 Oct 2025 15:03:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A45D43858C83 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=dominicclifton.name Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=dominicclifton.name ARC-Filter: OpenARC Filter v1.0.0 sourceware.org A45D43858C83 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=82.113.145.160 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1759676622; cv=none; b=byq7Zj6mpaR1icilVj07CrwuTWr/MXKKWsSZ9SdMDvIMisTyIi7i2U8BhTZBfKPXVY0IsRVKZffFEBWQLwlH2+DoIaVSGsGph8tMDzUFq0mG5eaWNXiIasg63SRWdj6qdZ2nElSeFvX7wAnGVzTwWSwJCDR2uXa3CF5huOXRMKQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1759676622; c=relaxed/simple; bh=1ysQo7Ywbt47rjnvZXXFQPwVQsNDmjqiupEYUDbMv7s=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=EqMobDe9Ze3E+Ne847JMUsoN3sRgCSK4cJeP20j6F2NhpTKMXvGqd2tyRbyVqApfVKYyyHbYYbLdL5PIVr8KIM6chJwDpNDam0gpPc5kfYg1R9+8KVMHLuCbJY6pQsyb5WEqgC/SSQSmFXX3W7sjWQTBvkCWsoM1iwV1rgMq8W8= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A45D43858C83 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=dominicclifton.name; s=email; h=Content-Type:MIME-Version:Message-ID:Date: Subject:To:From:Sender:Reply-To:Cc:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=aePWICr3Laxibd1dpjdKhhTdgincQHMe8P+ViXpRHHY=; b=id0Sb21WPcun6Iomhpab8/+Yhk HS8sv8+ZDw4cvMZKqkkJgy7TDFNLu25Fbj8CZtII109GjPc0nLanyLuWGvr/QyCSWq3/x7cO8lHc8 oDmZ6R09kNacH1i2kiEQQJn0ArNwVSDmSXD3BqhWilrfJqSYhNiOjxujbBWuNacjhQxc=; Received: from [45.86.185.202] (helo=HYDRA01) by mx03.hydraservices.com with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1v5QGy-00Dxti-3R for gdb-patches@sourceware.org; Sun, 05 Oct 2025 16:03:40 +0100 From: "Dominic Clifton" To: Subject: Fixing gdb crash issue when loading an elf file compiled with rust 1.87.0 Date: Sun, 5 Oct 2025 17:03:32 +0200 Message-ID: <00d101dc3609$37564b00$a602e100$@dominicclifton.name> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_00D2_01DC3619.FADFB740" X-Mailer: Microsoft Outlook 16.0 Thread-Index: Adw2CTanL7mCOAL2Q0qQeWw2GdoANw== Content-Language: en-gb X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org This is a multipart message in MIME format. ------=_NextPart_000_00D2_01DC3619.FADFB740 Content-Type: multipart/alternative; boundary="----=_NextPart_001_00D3_01DC3619.FADFB740" ------=_NextPart_001_00D3_01DC3619.FADFB740 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Problem: When starting a debugger session to an STM32H743ZI development board with the Embassy stm32h7 blinky example GDB crashes with this error: terminate called after throwing an instance of 'std::logic_error' what(): basic_string: construction from null is not valid TL;DR: missing null-pointer checking for the name and directory in the dwarf debug info, patches attached. Background: I do desktop and embedded development, for many years, in Rust and C/C++. My C/C++ is rusty though, so this patch should be checked by maintainers familiar with the code for handling dwarf files. I tried older released versions of arm-gnu-toolchain with GDB, as follows: arm-gnu-toolchain-13.3.rel1-mingw-w64-i686-arm-none-eabi = working, but too old, wasn't compiled with python arm-gnu-toolchain-14.2.rel1-mingw-w64-i686-arm-none-eabi = not working, same issue arm-gnu-toolchain-14.3.rel1-mingw-w64-x86_64-arm-none-eabi = not working, same issue $ /C/Program\ Files/JetBrains/CLion\ 2025.2.3/bin/gdb/win/x64/bin/gdb.exe -version (GNU gdb (GDB; JetBrains IDE bundle; build 216) 15.2) = not working, same issue Locally built "GNU gdb (GDB) 16.3" = not working, same issue. So down the rabbit hole I went. After enabling RustRover 2025.2 debug logging and finding the MI2 communication sequence I found this in the log: 2025-10-04 09:19:22,164 [48150271] FINE - #c.j.c.e.debugger - 32676>31-target-select remote :1337 2025-10-04 09:19:22,379 [48150486] FINE - #c.j.c.e.debugger - 32676 commands.mi2 $ gdb /ucrt64/bin/arm-none-eabi-gdb (gdb) set args D:\\Users\\Hydra\\Documents\\dev\\projects\\embassy\\examples\\stm32h7\\targ et\\thumbv7em-none-eabihf\\release\\blinky --interpreter=mi2 < commands.mi2 (gdb) catch throw (gdb) run This caused the same error again, I dumped the backtrace. (gdb) bt . #9 0x00007ff7a66e0e28 in std::__cxx11::basic_string, std::allocator >::basic_string > (__a=..., this=0x7feb80, __s=) at C:/msys64/ucrt64/include/c++/14.2.0/bits/basic_string.h:651 #10 read_file_scope (die=0x5d42d40, cu=0x5b148b0) at dwarf2/read.c:7536 #11 process_die (die=0x5d42d40, cu=cu@entry=0x5b148b0) at dwarf2/read.c:6497 #12 0x00007ff7a66e4680 in process_full_comp_unit (pretend_language=, cu=0x5b148b0) at dwarf2/read.c:6260 #13 process_queue (per_objfile=) at dwarf2/read.c:5552 #14 dw2_do_instantiate_symtab (per_cu=0x5a69e20, per_objfile=, skip_partial=) at dwarf2/read.c:1779 . After looking at the code and trying a few things, with the aid of chatgpt since I'm unfamiliar with the codebase and gdb internals, it seems some additional null-pointer checking is required when handing some debugging information for the `asm.S` file used in the build process for elf files generated by cargo/rust for the Embassy stm32 examples. I made two patches, one to find_file_and_directory and one to read_file_scope. After applying the first patch, the problem still occurred, and after further digging a second patch was made, when it was applied the debugger no-longer crashes and I'm able to step-debug the embedded rust program in RustRover 2025.2 For reference, you can generate the same elf file I was using as follows: git clone https://github.com/embassy-rs/embassy.git cd embassy git checkout e4e06ab5b136a21c98d42491ef1e31b6dc25e08e cd examples/stm32h7 cargo build --bin blinky -release the obj-dump tool can be used to dump the dwarf debugging information. arm-none-eabi-objdump.exe -h ./target/thumbv7em-none-eabihf/release/blinky -W > dwarf.txt I then checked out the latest version of gdb from the gdb git repo and build it, again on windows 11/msys2/ucrt64. I then ported the changes to the latest version and built again, re-tested, all ok, and exported two patches from git, attached. 0001-find_file_and_directory-return-empty-strings-instead.patch 0002-read_file_scope-avoid-eventual-crash-when-the-file-o.patch It's also possible that there's an issue with the tools used to create the .elf file in the first place which may also need investigating and reporting to the appropriate team (I think llvm in this case). The rust tools (cargo/rustc/llvm linker/etc) are are already in the wild, I was using stable rust 1.87.0. It would be fantastic to have these fixes, or a better one based on these patches, applied to GDB so that other developers don't have to go though a day's worth of troubleshooting and compiling of and patching gdb to be able to debug their embedded apps. Kind regards, Dominic Clifton ------=_NextPart_001_00D3_01DC3619.FADFB740 Content-Type: text/html; charset="us-ascii" Content-Transfer-Encoding: quoted-printable

Problem:

 

When = starting a debugger session to an STM32H743ZI development board with the = Embassy stm32h7 blinky example GDB crashes with this = error:

 

terminate called after throwing an instance of = 'std::logic_error'

  = what():  basic_string: construction from null is not = valid

 

 

TL;DR: = missing null-pointer checking for the name and directory in the dwarf = debug info, patches attached.

 

Background:

 

I do desktop = and embedded development, for many years, in Rust and C/C++.  My = C/C++ is rusty though, so this patch should be checked by maintainers = familiar with the code for handling dwarf files.

 

I tried = older released versions of arm-gnu-toolchain with GDB, as = follows:

 

arm-gnu-toolchain-13.3.rel1-mingw-w64-i686-arm-none-eab= i =3D working, but too old, wasn’t compiled with = python

arm-gnu-toolchain-14.2.rel1-mingw-w64-i686-arm-none-eab= i =3D not working, same issue

arm-gnu-toolchain-14.3.rel1-mingw-w64-x86_64-arm-none-e= abi =3D not working, same issue

$ = /C/Program\ Files/JetBrains/CLion\ 2025.2.3/bin/gdb/win/x64/bin/gdb.exe = –version (GNU gdb (GDB; JetBrains IDE bundle; build 216) 15.2) =3D = not working, same issue

Locally built = "GNU gdb (GDB) 16.3" =3D not working, same = issue.

 

So down the rabbit hole I went…

 

After = enabling RustRover 2025.2 debug logging and finding the MI2 = communication sequence I found this in the log:


2025-10-04 09:19:22,164 [48150271] FINE - = #c.j.c.e.debugger - 32676>31-target-select remote = :1337

2025-10-04 09:19:22,379 = [48150486] FINE - #c.j.c.e.debugger - 32676<terminate called after = throwing an instance of 'std::logic_error'

2025-10-04 09:19:22,379 [48150486] FINE - = #c.j.c.e.debugger - 32676< what(): basic_string: construction from = null is not valid

I re-created this on the command line, avoiding = the IDE entirely, built the the latest released version of gdb (16.2) = from a release tarball, on mysys2 ucrt64, and ran it though a local gdb = instance:

 

$ echo "-target-select remote :1337" > = commands.mi2

$ gdb = /ucrt64/bin/arm-none-eabi-gdb

 

(gdb) set = args = D:\\Users\\Hydra\\Documents\\dev\\projects\\embassy\\examples\\stm32h7\\t= arget\\thumbv7em-none-eabihf\\release\\blinky --interpreter=3Dmi2 < = commands.mi2

(gdb) catch = throw

(gdb) run

 

This caused = the same error again, I dumped the backtrace.

 

(gdb) = bt

#9  0x00007ff7a66e0e28 in = std::__cxx11::basic_string<char, std::char_traits<char>, = std::allocator<char> = >::basic_string<std::allocator<char> > (__a=3D..., = this=3D0x7feb80, __s=3D<optimized out>)

    at = C:/msys64/ucrt64/include/c++/14.2.0/bits/basic_string.h:651

#10 read_file_scope (die=3D0x5d42d40, = cu=3D0x5b148b0) at dwarf2/read.c:7536

#11 process_die (die=3D0x5d42d40, = cu=3Dcu@entry=3D0x5b148b0) at dwarf2/read.c:6497

#12 0x00007ff7a66e4680 in process_full_comp_unit = (pretend_language=3D<optimized out>, cu=3D0x5b148b0) at = dwarf2/read.c:6260

#13 process_queue = (per_objfile=3D<optimized out>) at = dwarf2/read.c:5552

#14 = dw2_do_instantiate_symtab (per_cu=3D0x5a69e20, = per_objfile=3D<optimized out>, skip_partial=3D<optimized = out>) at dwarf2/read.c:1779

 

After  = looking at the code and trying a few things, with the aid of chatgpt = since I’m unfamiliar with the codebase and gdb internals, it seems = some additional null-pointer checking is required when handing some = debugging information for the `asm.S` file used in the build process for = elf files generated by cargo/rust for the Embassy stm32 = examples.

 

I made two patches, one to find_file_and_directory and = one to read_file_scope.

 

After = applying the first patch, the problem still occurred, and after further = digging a second patch was made, when it was applied the debugger = no-longer crashes and I’m able to step-debug the embedded rust = program in RustRover 2025.2

 

For = reference, you can generate the same elf file I was using as = follows:

git clone https://github.com/emb= assy-rs/embassy.git

cd embassy

git checkout = e4e06ab5b136a21c98d42491ef1e31b6dc25e08e

cd = examples/stm32h7

cargo build = --bin blinky –release

 

the obj-dump = tool can be used to dump the dwarf debugging = information.

 

arm-none-eabi-objdump.exe -h = ./target/thumbv7em-none-eabihf/release/blinky -W > = dwarf.txt

 

 

I then = checked out the latest version of gdb from the gdb git repo and build = it, again on windows 11/msys2/ucrt64.

I then ported the changes to the latest version and = built again, re-tested, all ok, and exported two patches from git, = attached.

 

0001-find_file_and_directory-return-empty-strings-inste= ad.patch

0002-read_file_scope-avoid-eventual-crash-when-the-file= -o.patch

 

It’s also possible that there’s an issue = with the tools used to create the .elf file in the first place which may = also need investigating and reporting to the appropriate team (I think = llvm in this case).  The rust  tools (cargo/rustc/llvm = linker/etc) are are already in the wild, I was using stable rust = 1.87.0.

 

It would be fantastic to have these fixes, or a better = one based on these patches, applied to GDB so that other developers = don’t have to go though a day’s worth of troubleshooting and = compiling of and patching gdb to be able to debug their embedded = apps.

 

Kind regards,

 

Dominic = Clifton

 

------=_NextPart_001_00D3_01DC3619.FADFB740-- ------=_NextPart_000_00D2_01DC3619.FADFB740 Content-Type: application/octet-stream; name="0001-find_file_and_directory-return-empty-strings-instead.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="0001-find_file_and_directory-return-empty-strings-instead.patch" >From f1b1d70a13a500936e15fa32025f0624efcb5cfb Mon Sep 17 00:00:00 2001=0A= From: Dominic Clifton =0A= Date: Sun, 5 Oct 2025 12:31:47 +0200=0A= Subject: [PATCH 1/2] find_file_and_directory - return empty strings = instead of=0A= null pointers.=0A= =0A= ---=0A= gdb/dwarf2/read.c | 12 ++++++++++--=0A= 1 file changed, 10 insertions(+), 2 deletions(-)=0A= =0A= diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c=0A= index 955893c5f0c..525357f7d2e 100644=0A= --- a/gdb/dwarf2/read.c=0A= +++ b/gdb/dwarf2/read.c=0A= @@ -5942,10 +5942,18 @@ find_file_and_directory (struct die_info *die, = struct dwarf2_cu *cu)=0A= if (cu->per_cu->fnd !=3D nullptr)=0A= return *cu->per_cu->fnd;=0A= =0A= + // Ensure that nullptrs become empty strings=0A= + const char *name =3D dwarf2_string_attr(die, DW_AT_name, cu);=0A= + const char *comp_dir =3D dwarf2_string_attr(die, DW_AT_comp_dir, cu);=0A= +=0A= + if (!name)=0A= + name =3D "";=0A= + if (!comp_dir)=0A= + comp_dir =3D "";=0A= +=0A= /* Find the filename. Do not use dwarf2_name here, since the filename=0A= is not a source language identifier. */=0A= - file_and_directory res (dwarf2_string_attr (die, DW_AT_name, cu),=0A= - dwarf2_string_attr (die, DW_AT_comp_dir, cu));=0A= + file_and_directory res(name, comp_dir);=0A= =0A= if (res.get_comp_dir () =3D=3D nullptr=0A= && cu->producer_is_gcc_lt_4_3 ()=0A= -- =0A= 2.48.1=0A= =0A= ------=_NextPart_000_00D2_01DC3619.FADFB740 Content-Type: application/octet-stream; name="0002-read_file_scope-avoid-eventual-crash-when-the-file-o.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="0002-read_file_scope-avoid-eventual-crash-when-the-file-o.patch" >From d3eb6fb04c17a1a3b22a13e2b5bb2fa023b00b7d Mon Sep 17 00:00:00 2001=0A= From: Dominic Clifton =0A= Date: Sun, 5 Oct 2025 12:40:28 +0200=0A= Subject: [PATCH 2/2] read_file_scope - avoid eventual crash when the = file or=0A= directory name is null.=0A= =0A= * without this, launching the debugger results in the following error:=0A= =0A= ```=0A= terminate called after throwing an instance of 'std::logic_error' = what(): basic_string: construction from null is not valid=0A= ```=0A= ---=0A= gdb/dwarf2/read.c | 17 +++++++++++------=0A= 1 file changed, 11 insertions(+), 6 deletions(-)=0A= =0A= diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c=0A= index 525357f7d2e..287ce7b518c 100644=0A= --- a/gdb/dwarf2/read.c=0A= +++ b/gdb/dwarf2/read.c=0A= @@ -6091,28 +6091,33 @@ read_file_scope (struct die_info *die, struct = dwarf2_cu *cu)=0A= =0A= file_and_directory &fnd =3D find_file_and_directory (die, cu);=0A= =0A= + // ensure fnd.get_name() and fnd.get_comp_dir() are never null, which = they sometimes are=0A= + const char *fname =3D fnd.get_name() ? fnd.get_name() : "";=0A= + const char *compdir =3D fnd.get_comp_dir() ? fnd.get_comp_dir() : "";=0A= +=0A= /* GAS supports generating dwarf-5 info starting version 2.35. = Versions=0A= 2.35-2.37 generate an incorrect CU name attribute: it's relative,=0A= implicitly prefixing it with the compilation dir. Work around = this by=0A= prefixing it with the source dir instead. */=0A= - if (cu->header.version =3D=3D 5 && !IS_ABSOLUTE_PATH (fnd.get_name ())=0A= + if (cu->header.version =3D=3D 5 && !IS_ABSOLUTE_PATH (fname)=0A= && cu->producer_is_gas_lt_2_38 ())=0A= {=0A= attr =3D dwarf2_attr (die, DW_AT_stmt_list, cu);=0A= if (attr !=3D nullptr && attr->form_is_unsigned ())=0A= {=0A= sect_offset line_offset =3D (sect_offset) attr->as_unsigned ();=0A= - line_header_up lh =3D dwarf_decode_line_header (line_offset, cu,=0A= - fnd.get_comp_dir ());=0A= + line_header_up lh =3D dwarf_decode_line_header (line_offset, cu, = compdir);=0A= if (lh->version =3D=3D 5 && lh->include_dir_at (1) !=3D nullptr)=0A= {=0A= - std::string dir =3D lh->include_dir_at (1);=0A= - fnd.set_comp_dir (std::move (dir));=0A= + const char* dir_ptr =3D lh->include_dir_at (1);=0A= + std::string dir =3D dir_ptr ? dir_ptr : compdir;=0A= +=0A= + fnd.set_comp_dir (std::move (dir));=0A= }=0A= }=0A= }=0A= =0A= - cu->start_compunit_symtab (fnd.get_name (), fnd.intern_comp_dir = (objfile),=0A= + cu->start_compunit_symtab (fname, fnd.intern_comp_dir (objfile),=0A= lowpc);=0A= =0A= gdb_assert (per_objfile->sym_cu =3D=3D nullptr);=0A= -- =0A= 2.48.1=0A= =0A= ------=_NextPart_000_00D2_01DC3619.FADFB740--