[Bug other/100446] New: GDB has problems reading GCC's debugging info level -g3
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100446 Bug ID: 100446 Summary: GDB has problems reading GCC's debugging info level -g3 Product: gcc Version: 10.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: other Assignee: unassigned at gcc dot gnu.org Reporter: rdiezmail-gcc at yahoo dot de Target Milestone: --- GDB has excessive CPU load and memory usage with -g3 debug info. Sometimes it makes GDB unusable. There are problems with debug (non LTO) builds, but most issues come with when building with LTO, like for example missing or weird C++ symbols. The release ELF seems to have lost most C++ symbols, and there are many entries like this: 00010d6b l .debug_info 00010d6b l .debug_info 00010d6b l .debug_info 00010d6b l .debug_info More details about this problem are here: https://sourceware.org/bugzilla/show_bug.cgi?id=27754 It looks like a GCC issue, and not a GDB issue. I asked in the mailing list but got no answer at all: https://gcc.gnu.org/pipermail/gcc-help/2021-April/140221.html
[Bug debug/100446] GDB has problems reading GCC's debugging info level -g3
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100446 --- Comment #3 from R. Diez --- Regarding "shifting the blame", no worries, I am grateful for any help. I suspect that there is more than 1 issue here. Could you take a look at the following aspect mentioned in the GDB bug? 8<8< In fact, I do not understand why StartOfUserCode is not defined in the release build, because it is the same source code after all. The same routine is used in the same way. I dumped all symbols like this and I compared them: arm-none-eabi-objdump --syms firmware-debug-non-lto.elf arm-none-eabi-objdump --syms firmware-release-lto.elf 8<8< That particular symbol, StartOfUserCode, among many others, should be in the release build too. And there is no GDB involved there at all. I have not got experience with clang or lldb at all, and I have read that lldb is not ready yet for debugging bare metal firmware (at least off the shelf).
[Bug debug/100446] GDB has problems reading GCC's debugging info level -g3
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100446 --- Comment #5 from R. Diez --- In a nutshell: "objdump --syms" does not show that symbol, probably because the routine was inlined, but "readelf --debug-dump" does show it. Thanks for your help.
[Bug c/42579] [PATCH] support for obtaining file basename
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=42579 R. Diez changed: What|Removed |Added CC||rdiezmail-gcc at yahoo dot de --- Comment #11 from R. Diez --- What is the target GCC version for __FILE_NAME__? GCC 12.1?
[Bug preprocessor/77488] Proposal for __FILENAME_ONLY__
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77488 R. Diez changed: What|Removed |Added Resolution|--- |DUPLICATE Status|UNCONFIRMED |RESOLVED --- Comment #10 from R. Diez --- This issue has been fixed in 42579. *** This bug has been marked as a duplicate of bug 42579 ***
[Bug c/42579] [PATCH] support for obtaining file basename
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=42579 --- Comment #12 from R. Diez --- *** Bug 77488 has been marked as a duplicate of this bug. ***
[Bug bootstrap/60160] Building with -flto in CFLAGS_FOR_TARGET / CXXFLAGS_FOR_TARGET
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60160 R. Diez changed: What|Removed |Added CC||rdiezmail-gcc at yahoo dot de --- Comment #6 from R. Diez --- I am experimenting with a GCC 11.2 cross-compiler for bare-metal embedded software. There is no operating system, so no shared libraries or anything fancy. But there is a static libc (Newlib or Picolibc). I wanted to build everything with LTO, including libc, libstdc++ and libgcc. This is the makefile I am using: https://github.com/rdiez/JtagDue/blob/master/Toolchain/Makefile Search for "-ffat-lto-objects" in that makefile. As soon as I enable the LTO flags, I get linker errors. They are documented in the makefile next to the LTO options, and look similar to those reported in this bug. I tried -fno-builtin with varying degrees of success. I also tried building only the application and libc with LTO, but not libstdc++ etc., to no avail. LTO only works for the user application. As soon as libc or the other GCC libraries are compiled with LTO, it fails. Is it unfortunate, because I believe that a full LTO build for a bare-metal environment would be rather beneficial. The patch and information referenced in this bug report look dated. Is there a way to make LTO work now, at least for my configuration?
[Bug target/68605] Add -mno-crt0 to disable automatic crt0 injection
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68605 --- Comment #4 from R. Diez --- That is certainly a way to fix the crt0 nuisance. But it requires some specs file black magic, so yet another thing to learn. And then you have to keep up with GCC in case something changes around the specs files. It is not a user-friendly solution.
[Bug libstdc++/68606] Reduce or disable the static emergency pool for C++ exceptions
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68606 --- Comment #11 from R. Diez --- > Has a solution been found for embedded systems with very limited resources? > In this case for example, C++ exceptions can be disabled and this > emergency pool not needed. Contrary to popular belief, C++ exception handling does not need many resources. I have been generating dynamic error messages in readable English using C++ exceptions on microcontrollers with as little as 16 KiB SRAM for years, with 'plenty' of memory to spare. To that effect, I have been using the patch that I mentioned above. Here is an updated URL for it: https://github.com/rdiez/JtagDue/blob/master/Toolchain/Patches/GccDisableCppExceptionEmergencyBuffer-GCC-5.3.0.patch
[Bug libstdc++/68606] Reduce or disable the static emergency pool for C++ exceptions
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68606 --- Comment #13 from R. Diez --- It is hard to automatically tell whether nobody else is using such a statically-allocated emergency buffer. In my case, I am using C++ exceptions, so the linker will probably always include the buffer. My patch makes sure that no emergency buffer is allocated. As long as your firmware does not run out of malloc RAM, C++ exceptions continue to work fine. About implementing a proper solution (my patch is just a workaround): There are probably guys who want to control the size of the emergency buffer, but for really constrained environments, I would like an option to disable it completely. As a bonus, the code that allocates and uses the emergency buffer could be optimised away too, but that is not critical for me. RAM / SRAM is often tight, but Flash/program memory (where the code resides) tends to be much bigger. So optimising the buffer away from RAM would be enough in most scenarios.
[Bug libstdc++/104299] New: Doc: stdio is not the only option in --enable-cstdio=XXX
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104299 Bug ID: 104299 Summary: Doc: stdio is not the only option in --enable-cstdio=XXX Product: gcc Version: 11.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: rdiezmail-gcc at yahoo dot de Target Milestone: --- File libstdc++-v3/doc/html/manual/configure.html states for "--enable-cstdio=OPTION": "At the moment, the only choice is to use 'stdio', a generic "C" abstraction." That is no longer true. According to this snippet from libstdc++-v3/acinclude.m4: AC_DEFUN([GLIBCXX_ENABLE_CSTDIO], [ AC_MSG_CHECKING([for underlying I/O to use]) GLIBCXX_ENABLE(cstdio,stdio,[[[=PACKAGE]]], [use target-specific I/O package], [permit stdio|stdio_posix|stdio_pure]) Options "stdio_posix" and "stdio_pure" are also available.
[Bug bootstrap/104301] New: --enable-cstdio=stdio_pure not passed down to libstdc++-v3
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104301 Bug ID: 104301 Summary: --enable-cstdio=stdio_pure not passed down to libstdc++-v3 Product: gcc Version: 11.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: bootstrap Assignee: unassigned at gcc dot gnu.org Reporter: rdiezmail-gcc at yahoo dot de Target Milestone: --- I have been using the following makefile for years to build a cross-compiler GCC toolchain with Newlib: https://github.com/rdiez/JtagDue/blob/master/Toolchain/Makefile Now I would like to optionally replace Newlib with Picolibc. Picolibc needs this option for libstdc++-v3: --enable-cstdio=stdio_pure So I tried to pass it to GCC's top-level 'configure' script, but libstdc++-v3's 'configure' script is not run at that time, it runs later on, when you invoke 'make' at GCC's top level. Then I see this line in the 'make' output: checking for underlying I/O to use... stdio So it seems that the "--enable-cstdio=stdio_pure" option is not passed down from the top-level 'configure' to libstdc++-v3's 'configure'. I guess this is a bug in the top-level 'configure' logic. It has probably gone unnoticed for a long time because it is only recently that you can specify options other than 'stdio' in --enable-cstdio=xxx . Or is the GCC user expected to delve down and configure GCC's components separately?
[Bug bootstrap/98324] [11 Regression] bootstrap broken with a LTO build configured with --enable-default-pie
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98324 R. Diez changed: What|Removed |Added CC||rdiezmail-gcc at yahoo dot de --- Comment #7 from R. Diez --- I have been building cross-compiler toolchains for years with makefiles similar to this one: https://github.com/rdiez/JtagDue/blob/master/Toolchain/Makefile I am trying to upgrade that makefile from GCC 10.2 to GCC 11.2, and I am getting exactly the same problem that this bug describes. I checked, and the fix linked from this bug is included in version 11.2 . However, I have never used option "--enable-default-pie" in the past, and I was able build cross-toolchains with many GCC versions without it for years. The target is actually an embedded ARM Cortex-M3 microcontroller with fixed memory addresses (a "bare metal" firmware without OS), so I guess that I do not really need PIE. It may even cost some performance, if I understand what PIE does. I am guessing that bootstrapping a cross-compiler GCC is still broken with its default PIE setting.
[Bug c++/107500] New: Useless atexit entry for ~constant_init in eh_globals.cc
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107500 Bug ID: 107500 Summary: Useless atexit entry for ~constant_init in eh_globals.cc Product: gcc Version: 12.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: rdiezmail-gcc at yahoo dot de Target Milestone: --- I have this embedded firmware project of mine, which uses Newlib: https://github.com/rdiez/DebugDue It is the template for other similar bare-metal projects I have. Even though some targets have very little SRAM (like 16 KiB), I am still using C++ and exceptions. The project above documents how I configure GCC to that effect. Up until GCC 11.2, I have been doing this check: if ( _GLOBAL_ATEXIT != nullptr ) { Panic( "Unexpected entries in atexit table." ); } On devices with very little RAM and without an operating system, initialisation and destruction can be tricky. With the check above, I am making sure that nothing unexpected comes up in that respect. I am initialising all static objects manually anyway, to prevent any ordering surprises (the initialisation order of C++ static objects can be problematic too). The check above fails with GCC 12.2. Apparently, a destructor called constant_init::~constant_init() gets added to the atexit table on start-up. Because of the way that Newlib works, that wastes 400 bytes of SRAM, which corresponds to sizeof( _global_atexit0 ). The structure has room for 32 atexit calls (because of some ANSI conformance), but we are only using 1 entry. The interesting thing is that the destructor is supposed to be empty, see: https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/eh_globals.cc ~constant_init() { /* do nothing, union member is not destroyed */ } GCC generates the following code for that empty destructor: 0008da68 <(anonymous namespace)::constant_init::~constant_init()>: 8da68: b580 push {r7, lr} 8da6a: af00 add r7, sp, #0 8da6c: bd80 pop {r7, pc} That does not make any sense. Is there a way to prevent GCC from registering such an empty atexit function? Failing that, is there a way to prevent GCC from registering a particular atexit function, even if it is not empty? I find surprising that GCC emits such code. My project is building its own GCC/Newlib toolchain with optimisation level "-Os", so I would expect at least the "add r7, sp, #0" to be optimised away.
[Bug c++/107500] Useless atexit entry for ~constant_init in eh_globals.cc
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107500 --- Comment #4 from R. Diez --- The 'constant_init' wrapper with the 'union' inside is a contrived hack, isn't it? We may as well use a different hack then. How about a combination of '__attribute__ constructor' and 'placement new' like this? uint8_t some_buffer[ sizeof( __cxa_eh_globals ) ]; // All objects with an init_priority attribute are constructed before any // object with no init_priority attribute. #define SOME_INIT_PRIORITY 200 // Priority range [101, 65535]. static __attribute__ ((constructor (SOME_INIT_PRIORITY))) void MyHackForInitWithoutAtExitDestructor ( void ) throw() { // Placement new. new ( some_buffer ) __cxa_eh_globals(); } You would then need a 'get_eh_globals()' wrapper to return a pointer or a reference to a '__cxa_eh_globals' object from 'some_buffer', by doing a type cast. Everybody should then use the wrapper to access that singleton object.
[Bug c++/107500] Useless atexit entry for ~constant_init in eh_globals.cc
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107500 --- Comment #5 from R. Diez --- I know very little about GCC, but it is a very smart compiler, so I am having a hard time understanding how GCC could miss so many optimisations. After all, even when compiling with little optimisation, GCC seems able to discard unused code rather well. In my project, I am building my own toolchain with this makefile: https://github.com/rdiez/DebugDue/blob/master/Toolchain/Makefile I haven't verified it this time around, but I believe that Newlib is being built with '-Os' optimisation. Search for COMMON_CFLAGS_FOR_TARGET in that makefile, which eventually gets passed to Newlib in CFLAGS_FOR_TARGET. First of all, GCC seems unable to generate an empty routine or destructor, or at least flag it as being effectively empty. The caller should then realise that it is empty, so it is not worth generating an atexit call for it. Secondly, I am not ARM Thumb assembly expert either, but shouldn't "add r7, sp, #0" be optimised away? After all, nobody is really using R7 in that routine. And finally, what is the point of generating a function prolog and epilog which saves and restores context from the stack? If the routine is pretty much empty, but cannot be really empty, shouldn't some kind of RET instruction suffice?
[Bug c++/107500] Useless atexit entry for ~constant_init in eh_globals.cc
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107500 --- Comment #8 from R. Diez --- Why does this 'eh_globals' object have to use a constexpr constructor? How does the current code avoid the "static initialization order fiasco"? If the user defines his/her own static C++ objects, how is it guaranteed now that 'eh_globals' is initialised before all other user code? Isn't using the "__attribute__ constructor" trick safer anyway? With it, you can document what priority levels libstdc++ uses. The user may even want to run a few routines before libstdc++ initialises. Flexibility in the initialisation order is often important in embedded environments. Portability is not really an issue. You can just "#ifdef GCC" around the "better" hack. Is GCC not using "__attribute__ constructor" internally anyway to implement such static constructors? So anybody using C++ with GCC must support that mechanism already. And about saving a few bytes, 400 bytes is no small amount in tightly-embedded environments. But it is not just the amount of memory. As I mentioned, my code is checking that nothing unexpected registers an atexit() destructor. If libstdc++ does that on start-up, it becomes hard to tell whether something unexpected has been added recently. I can surely put up with yet another little annoyance with this new GCC version. But bear in mind that flexibility and attention to detail in the embedded world is one of GCC's few remaining bastions. If GCC starts dropping the ball here too, even more people will consider moving to clang.
[Bug c++/107500] Useless atexit entry for ~constant_init in eh_globals.cc
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107500 --- Comment #9 from R. Diez --- > [...] > not just "turn on -Os and all the code gets removed". I am sure that the solution is not as trivial as "turn on -Os". But, as an outsider, it is hard to believe that it "takes non-trivial analysis of the destructor body". The destructor is empty! I am not talking about the GCC optimiser realising afterwards that the code is generating an atexit() entry that does nothing. I am saying that GCC should not generate so much code for an empty function for starters, and that GCC should not generate the destructor registration at all if the destructor is empty. I would imagine that those steps come before the optimiser gets to see the generated code.
[Bug libstdc++/105880] eh_globals_init destructor not setting _M_init to false
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105880 R. Diez changed: What|Removed |Added CC||rdiezmail-gcc at yahoo dot de --- Comment #17 from R. Diez --- For the record, this fix introduces a call to atexit() for a static destructor, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107500
[Bug c++/107500] Useless atexit entry for ~constant_init in eh_globals.cc
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107500 R. Diez changed: What|Removed |Added Resolution|DUPLICATE |FIXED --- Comment #13 from R. Diez --- >From your comments about "constexpr constructor" and "constinit", I gather that the "eh_globals" singleton is guaranteed then to be initialised very early, earlier than anything else that might use it, right? But that does not guarantee that it will be destroyed later than anything that wants to use it, is that correct? That is why we need the hack, to make it outlive all potential users. I am now trying to understand the implications of not destroying "__cxa_eh_globals obj" inside the "eh_globals" singleton, at least in the case of single-threaded (bare metal) embedded software. Hopefully, I can learn a little more along the way about how C++ exception handling works. As far as I can see, "struct __cxa_eh_globals" in unwind-cxx.h has 1 or 2 pointers and no destructor: struct __cxa_eh_globals { __cxa_exception *caughtExceptions; unsigned int uncaughtExceptions; #ifdef __ARM_EABI_UNWINDER__ __cxa_exception* propagatingExceptions; #endif }; Therefore, destroying this object should have real no effect. I wonder why there was a problem to fix in 'eh_globals' then. I am guessing that some static analyser, or checker instrumentation, may now complain that static object 'eh_globals', or at least its member 'obj', has not been properly destroyed upon termination. Normally, that would mean a risk of leaking some memory, but I am guessing that the last thread can never have any such 'caughtExceptions' or 'propagatingExceptions' left upon termination, right? So, theoretically, instead of leaving the destructor for the singleton empty, we could add asserts that those 2 pointers are nullptr. Or am I missing something? This all feels iffy. If I understand this correctly, it is impossible for GCC to guarantee the correct construction and destruction order of such global objects, and that is why we are hacking our way out. The reason is mainly, that not all targets support "__attribute__ constructor", so there is no way to implement a deterministic initialisation and destruction order for everybody. Is that right?
[Bug c++/107500] Useless atexit entry for ~constant_init in eh_globals.cc
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107500 --- Comment #16 from R. Diez --- I am slowly arriving at a different conclusion. "struct __cxa_eh_globals" has neither a constructor nor a destructor. Its members are pointers or integers, so GCC will not have automatically generated any constructor or destructor for this structure. Therefore, variable "static __cxa_eh_globals eh_globals" in the past was already initialised before any users (probably because static memory being zeroed on start-up). The situation has not changed now. This static variable already outlived anything else, as there was no destructor changing anything on termination. Your patch introduced wrapper "struct constant_init" around it, which makes GCC generate a constructor for the wrapper solely to register an empty destructor with atexit(). Otherwise, the wrapper does nothing else useful. Your patch also changes '__eh_globals_init::_M_init' (a different global object) to a static member. Is that not enough to fix the original problem?
[Bug c++/107500] Useless atexit entry for ~constant_init in eh_globals.cc
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107500 --- Comment #20 from R. Diez --- I had to modify the patch slightly. I guess that union member "unsigned char unused;" was removed after GCC 12.2 was released. But otherwise, the patch does work, at least in my bare-metal scenario. The atexit entry is no longer being generated, and I haven't seen any other side-effects yet.
[Bug c++/107500] Useless atexit entry for ~constant_init in eh_globals.cc
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107500 --- Comment #23 from R. Diez --- Many thanks for the fix. If you backport it to GCC 12.x, I won't be able to complain so much. ;-)
[Bug c++/107500] Useless atexit entry for ~constant_init in eh_globals.cc
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107500 --- Comment #24 from R. Diez --- In case somebody else wants to patch their GCC 12.2, here is the slightly-modified patch for convenience: https://github.com/rdiez/DebugDue/blob/master/Toolchain/Patches/Gcc12EhGlobalsAtexit.patch
[Bug c++/98992] attribute malloc error associating a member deallocator with an allocator
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98992 R. Diez changed: What|Removed |Added CC||rdiezmail-gcc at yahoo dot de --- Comment #1 from R. Diez --- I have been using the following up to GCC 11.3: struct MyClass { static void FreeMemory ( const void * pMem ) throw(); #if __GNUC_PREREQ(11, 0) __attribute__ (( malloc, malloc( MyClass::FreeMemory, 1 ) )) #else __attribute__ (( malloc )) #endif static void * AllocMemory ( size_t Size ) throw(); [...] }; However, GCC 12.1 does not want to accept it anymore: error: 'malloc' attribute argument 1 does not name a function I tried placing the attribute outside the class, like this: __attribute__ (( malloc, malloc( MyClass::FreeMemory, 1 ) )) void * MyClass::AllocMemory ( size_t Size ) throw() { return malloc( Size ); } But then I got 2 errors: error: 'static void MyClass::FreeMemory(const void*)' is protected within this context 710 | __attribute__ (( malloc, malloc( MyClass::FreeMemory, 1 ) )) | ^~ error: 'malloc' attribute argument 1 does not name a function That cannot be right. GCC should not insist that the deallocator is public. After all, the allocator AllocMemory is not public.