Pursuant to the post, Standalone functions/data in C++, I proceeded to put my "common data" in an anonymous namespace as below and everything worked great on Windows (Vista 64 bit) on VS 2005/2008/2010
namespace {
...
static std::string mystrings[] = {
str1,
str2,
...,
strN
};
...
}
namespace mynamesp {
...
use mystrings[] here..
...
}
But on Linux (so far tested RHEL5 built with GCC-4.1.2) I promptly got a segmentation fault.
$>myprog
Segmentation fault
$>gdb myprog
GNU gdb Fedora (6.8-27.el5)
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu"...
(gdb) r
Starting program: <path/to>/myprog
[Thread debugging using libthread_db enabled]
[New Thread 0x2b8901a9da60 (LWP 32710)]
Program received signal SIGSEGV, Segmentation fault.
0x0000003e4ce9c928 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string ()
from /usr/lib64/libstdc++.so.6
(gdb) bt
#0 0x0000003e4ce9c928 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string ()
from /usr/lib64/libstdc++.so.6
#1 0x00002b88ffde482b in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535)
at <path/to>/mysource.cpp:140
#2 0x00002b88ffde4d65 in global constructors keyed to _ZN91_GLOBAL__N__underscore_separated_path_to_mysource.cpp_00000000_6994A7DA2_1E () at <path/to>/mysource.cpp:12139
#3 0x00002b890011a296 in __do_global_ctors_aux ()
from <path/to/libs>/debug/libmylibd.so
#4 0x00002b88ffcd7f33 in _init () from <path/to/libs>/debug/libmylibd.so
#5 0x00002b8901672e40 in ?? ()
#6 0x000000326940d22b in call_init () from /lib64/ld-linux-x86-64.so.2
#7 0x000000326940d335 in _dl_init_internal () from /lib64/ld-linux-x86-64.so.2
#8 0x0000003269400aaa in _dl_start_user () from /lib64/ld-linux-x86-64.so.2
#9 0x0000000000000001 in ?? ()
#10 0x0000000000000000 in ?? ()
(gdb)
Line 140 in the backtrace call stack item #1 basically points to the end of my array of strings definition. I've seen some others get this error; but no obvious fixes. Appreciate any thoughts/ideas/corrections as always. Thanks!
Your problem could be releated to a static initialization order fiasco.
This happens when you initialize a static variable using another static variable. When the latter one has not been initialized yet, then the first one is using a non-initialized variable for its initialization.
The root cause is that the order, in which static variables are initialized, is undefined.
Further reading:
https://isocpp.org/wiki/faq/ctors#static-init-order
A typical workaround would be to wrap the static variables inside a function. Example:
T& GetStaticA() {
T static_var_A; // <--initialization here
return A;
}
T static_var_B = GetStaticA(); // <-- static_var_A is guaranteed to be initialized
I had this problem and it turned out that in my compiling line I had missed the final output file in the linking.
g++ main.o logger.o timer.o keyboard.o -o main -lSDL -lSDL_image -lSDL_ttf -Wall
should have been
g++ main.o logger.o timer.o keyboard.o drawer.o -o main -lSDL -lSDL_image -lSDL_ttf -Wall
(Notice the now inclusion of drawer.o?)
It was easy to miss because my actual bash compilation script had many more lines to it.
Related
When I attempt to use std::filesystem::path as a function argument, it segfaults on my machine. Here is a minimal example:
#include <filesystem>
void thing(const std::filesystem::path& p) {
return;
}
int main() {
thing("test");
return 0;
}
This snippet results in the following backtrace from gdb:
#0 0x0000563a5a3814b3 in std::vector<std::filesystem::__cxx11::path::_Cmpt, std::allocator<std::filesystem::__cxx11::path::_Cmpt> >::~vector (this=0x23, __in_chrg=<optimized out>) at /usr/include/c++/8/bits/stl_vector.h:567
#1 0x0000563a5a38132c in std::filesystem::__cxx11::path::~path (this=0x3, __in_chrg=<optimized out>) at /usr/include/c++/8/bits/fs_path.h:208
#2 0x0000563a5a381f74 in std::filesystem::__cxx11::path::_Cmpt::~_Cmpt (this=0x3, __in_chrg=<optimized out>) at /usr/include/c++/8/bits/fs_path.h:643
#3 0x0000563a5a381f8f in std::_Destroy<std::filesystem::__cxx11::path::_Cmpt> (__pointer=0x3) at /usr/include/c++/8/bits/stl_construct.h:98
#4 0x0000563a5a381e3f in std::_Destroy_aux<false>::__destroy<std::filesystem::__cxx11::path::_Cmpt*> (__first=0x3, __last=0x0) at /usr/include/c++/8/bits/stl_construct.h:108
#5 0x0000563a5a381ab0 in std::_Destroy<std::filesystem::__cxx11::path::_Cmpt*> (__first=0x3, __last=0x0) at /usr/include/c++/8/bits/stl_construct.h:137
#6 0x0000563a5a3817c1 in std::_Destroy<std::filesystem::__cxx11::path::_Cmpt*, std::filesystem::__cxx11::path::_Cmpt> (__first=0x3, __last=0x0) at /usr/include/c++/8/bits/stl_construct.h:206
#7 0x0000563a5a3814c9 in std::vector<std::filesystem::__cxx11::path::_Cmpt, std::allocator<std::filesystem::__cxx11::path::_Cmpt> >::~vector (this=0x7ffd198df8a0 = {...}, __in_chrg=<optimized out>) at /usr/include/c++/8/bits/stl_vector.h:567
#8 0x0000563a5a38132c in std::filesystem::__cxx11::path::~path (this=0x7ffd198df880<error reading variable: Cannot access memory at address 0x2b>, __in_chrg=<optimized out>) at /usr/include/c++/8/bits/fs_path.h:208
#9 0x0000563a5a381247 in main () at /home/user/CLionProjects/test/main.cpp:8
#10 0x00007fd6bb96ab6b in __libc_start_main (main=0x563a5a381200 <main()>, argc=1, argv=0x7ffd198df9b8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7ffd198df9a8) at ../csu/libc-start.c:308
#11 0x0000563a5a38113a in _start ()
I am using GCC 8.3 on Ubuntu 19.10, I had someone else compile and run this code with no issues on Windows so it could potentially be a bug in libstdc++
I think the problem is that Ubuntu mixes GCC versions in a single installation. On Ubuntu the default GCC is version 8, but the libstdc++.so.6 library comes from GCC 9. With GCC 8 the std::filesystem definitions are in a separate library, libstdc++fs.a, which must be linked to explicitly. In GCC 9 the std::filesystem symbols are in the main libstdc++.so library. Because of the mixed up Ubuntu installation it's possible for the GCC 9 symbols in libstdc++.so to satisfy the undefined references in code compiled with GCC 8 which should be satisfied by libstdc++fs.a. Because the std::filesystem symbols in GCC 9 are incompatible with the experimental versions of those symbols in GCC 8, it appears to link OK but crashes at runtime.
It should work correctly if you make sure you link with -lstdc++fs and make sure that option comes after all your object files, e.g. this should work:
g++ foo.o bar.o -lstdc++fs
But this will not work:
g++ -lstdc++fs foo.o bar.o
There is supposed to be an update to the Ubuntu gcc-8 packages to fix this, by ensuring the -lstdc++fs option comes after all the other input files. For more details see https://bugs.launchpad.net/ubuntu/+source/gcc-8/+bug/1824721
Compiling with gcc-9 also works, because when using GCC 9 to compile there is no need to link to -lstdc++fs for std::filesystem (with GCC 9 it's only needed for std::experimental::filesystem symbols).
I was able to fix this issue by installing GCC and G++ 9 from this PPA: https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test
Please link -lstdc++fs library, let's consider source file is fileSys.cpp then compile it as follows,
g++ -std=c++17 fileSys.cpp -lstdc++fs -o fs
I am using GCC 8.1.0 and Ubuntu 16.04.1 LTS.
There is already a similar question on this topic, you can find it at filesystem linker error
Code (m1.cpp):
#include <iostream>
using namespace std;
int main (int argc, char *argv[])
{
cout << "running m1" << endl;
return 0;
}
GDB Version: GNU gdb (GDB) 7.6.2
Built using: g++ -g m1.cpp
Command line history:
(gdb) b main
Breakpoint 1 at 0x40087b: file m1.cpp, line 6.
(gdb) r
Starting program: .../a.out
Program received signal SIGSEGV, Segmentation fault.
0x00002aaaaaac16a0 in strcmp () from /lib64/ld-linux-x86-64.so.2
(gdb) c
Continuing.
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
(gdb)
When I run without setting any breakpoints, it runs without errors.
As requested:
(gdb) bt
#0 strcmp () from /lib64/ld-linux-x86-64.so.2
#1 in check_match.12104 () from /lib64/ld-linux-x86-64.so.2
#2 in do_lookup_x () from /lib64/ld-linux-x86-64.so.2
#3 in _dl_lookup_symbol_x () from /lib64/ld-linux-x86-64.so.2
#4 in _dl_relocate_object () from /lib64/ld-linux-x86-64.so.2
#5 in dl_main () from /lib64/ld-linux-x86-64.so.2
#6 in _dl_sysdep_start () from /lib64/ld-linux-x86-64.so.2
#7 in _dl_start () from /lib64/ld-linux-x86-64.so.2
#8 in _start () from /lib64/ld-linux-x86-64.so.2
#9 in ?? ()
I was able to replicate the OP's observed behavior (using the same compile and getting the same backtrace). The behavior was persistent across a range GDBs and GCCs. I noticed that the symptom goes away when I unset SHELL. In my normal environment I use tcsh (version 1.15.00). If SHELL is set, then (I believe) gdb launches using tcsh. If I unset SHELL, gdb launches using sh. This is enough for me to make forward progress. I don't have a crisp explanation for what would be different in tcsh to manifest the issue but if others have the same behavior, it may shed more light on the issue.
I checked that in my GNU gdb version 7.11.1. It worked really fine in it.
I first compiled the same program and built it using:
g++ -g m1.cpp
Then, ran the executable in the gdb as follows:
gdb -q ./a.out
And did the same things you mentioned. It worked fine.
Update your gdb, and check that again and let know.
I am working on some rather large C++ app, with most of the code being stored in a static library, and some programs that use that code.
I have what looks like a memory corruption run-time crash:
*** Error in `build/bin/myapp': malloc(): memory corruption (fast): 0x00000000021f62a0 ***
I want to check where that happens. GDB seems the right tool (OS: Ubuntu 14.04).
My makefiles handles both debug and release with a makefile command-line switch.
With the switch on, the -g flag is added and the .a library is 23.8 MB, while the app is 519 kB.
Without, its 1.6 MB and 486kB (so I'm pretty sure the debugging symbols are there).
My (partial) CFLAGS, as suggested by the gcc manual:
CFLAGS = -std=c++11 -g -Wall -O0 -fno-inline
I run gdb with:
gdb --args build/bin/myapp datafile.dat -a -b (...and more arguments)
My problem is that even in the debug build, gdb keeps telling me that it can't find any symbols:
Reading symbols from build/bin/myapp...(no debugging symbols found)...done.
If I run it from within gdb, it crashes with:
Program received signal SIGABRT, Aborted.
0x00007ffff5298cc9 in __GI_raise (sig=sig#entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
And the backtrace command shows indeed that symbols are missing: frames 10 to 18 have missing information, and are probably related to my code:
(gdb) bt
#0 0x00007ffff5298cc9 in __GI_raise (sig=sig#entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1 0x00007ffff529c0d8 in __GI_abort () at abort.c:89
#2 0x00007ffff52d5394 in __libc_message (do_abort=do_abort#entry=1, fmt=fmt#entry=0x7ffff53e3b28 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175
#3 0x00007ffff52e00f7 in malloc_printerr (action=<optimized out>, str=0x7ffff53e3ec8 "malloc(): memory corruption (fast)", ptr=<optimized out>) at malloc.c:4996
#4 0x00007ffff52e2e04 in _int_malloc (av=0x7ffff5620760 <main_arena>, bytes=36) at malloc.c:3359
#5 0x00007ffff52e47b0 in __GI___libc_malloc (bytes=36) at malloc.c:2891
#6 0x00007ffff5babe68 in operator new(unsigned long) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#7 0x00007ffff5c03e69 in std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#8 0x000000000045a7a5 in char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) ()
#9 0x00007ffff5c05bd6 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) ()
from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#10 0x000000000042df7f in ?? ()
#11 0x000000000042eef6 in ?? ()
#12 0x0000000000421dab in ?? ()
#13 0x0000000000422223 in ?? ()
#14 0x0000000000422cfe in ?? ()
#15 0x0000000000423393 in ?? ()
#16 0x0000000000424600 in ?? ()
#17 0x000000000040fd50 in ?? ()
#18 0x000000000040566d in ?? ()
#19 0x00007ffff5283ec5 in __libc_start_main (main=0x4053c0, argc=6, argv=0x7fffffffddf8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>,
stack_end=0x7fffffffdde8) at libc-start.c:287
#20 0x000000000040604f in ?? ()
I did check some of the many questions about this topic, but none of any help (most of these relate to a forgotten -g flag, or an added -s, stripping down the symbols).
Question: what can the next step be to find out why/where my crash happens?
Additional info:
gcc --version: 5.3.0
gdb --version: 7.7.1
code dependencies: boost and opencv
but none of any help (most of these relate to a forgotten -g flag, or an added -s, stripping down the symbols).
It is almost certain that you either have a stray -s somewhere on your link line, or you run stip on the binary during installation.
Look at your link command line and install command carefully, there is strip somewhere in there.
P.S. As Tom Tromey already said, GDB is rarely effective in helping with a problem like this. Using Valgrind or Address Sanitizer will likely get you to the root cause much faster.
here is my CPP program
#include <iostream>
int main(int argc, char *argv[]){
return 0;
}
compiling and executing this, causes a seg fault:
[18:08 ~] > g++ test.cpp
[18:09 ~] > ./a.out
Segmentation fault
Does anybody have an idea about this issue please?
Thanks a lot for your help.
Here are some details that might be useful:
[18:13 ~] > ldd a.out
linux-vdso.so.1 => (0x00007fff3fdff000)
libstdc++.so.6 => /usr/lib/gcc/x86_64-redhat-linux/3.4.6/libstdc++.so.6 (0x00007fc8f4a53000)
libm.so.6 => /lib64/libm.so.6 (0x00007fc8f47ce000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fc8f45b8000)
libc.so.6 => /lib64/libc.so.6 (0x00007fc8f4225000)
/lib64/ld-linux-x86-64.so.2 (0x00007fc8f4ca5000)
and also gdb:
[18:15 ~] > gdb ./a.out
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-60.el6)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from ...done.
(gdb) run
Starting program: a.out
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7bd48ec in std::ios_base::Init::Init() () from /usr/lib/gcc/x86_64-redhat-linux/3.4.6/libstdc++.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.107.el6.x86_64 libgcc-4.4.7-3.el6.x86_64
(gdb) bt
#0 0x00007ffff7bd48ec in std::ios_base::Init::Init() () from /usr/lib/gcc/x86_64-redhat-linux/3.4.6/libstdc++.so.6
#1 0x0000000000400831 in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at /usr/lib/gcc/x86_64-redhat-linux/3.4.6/../../../../include/c++/3.4.6/iostream:77
#2 0x0000000000400873 in global constructors keyed to main() () at test.cpp:7
#3 0x0000000000400976 in __do_global_ctors_aux ()
#4 0x00000000004005a3 in _init ()
#5 0x00007fffffffe448 in ?? ()
#6 0x0000000000400905 in __libc_csu_init ()
#7 0x00007ffff7385c70 in __libc_start_main () from /lib64/libc.so.6
#8 0x0000000000400659 in _start ()
(gdb)
g++
[10:14 ~] > g++ -v
Reading specs from /usr/lib/gcc/x86_64-redhat-linux/3.4.6/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-languages=c,c++,f77 --disable-libgcj --host=x86_64-redhat-linux
Thread model: posix
gcc version 3.4.6 20060404 (Red Hat 3.4.6-19.el6)
and last thing
[10:25 ~] > ls /usr/lib/gcc/x86_64-redhat-linux
3.4.6
Thank you.
So apparently your problem is that your g++ installation is broken. I see from the messages that you have RHEL6, but somehow have version 3.4.6 of libstdc++.
My RHEL6 system has version 4.4.6 of gcc, libstdc++, etc. I assume that this older version of libstdc++ is related to your problem.
What versions do you have installed of gcc, g++, and libstdc++? From the other messages, it looks like you have 4.4.7, but do you happen to have multiple versions or mixed versions?
rpm -q gcc g++ libstdc++
Also, what other directories do you have under /usr/lib/gcc/x86_64-redhat-linux?
ls /usr/lib/gcc/x86_64-redhat-linux
i think that you miss something while installing g++
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.107.el6.x86_64 libgcc-4.4.7-3.el6.x86_64
Is possible to recover the exact values of argv and argc parameters of a main after the application crashed?
I need to use only the application core-dump and gdb debugger on Linux.
Yes, if application was compiled with debug info. Open core dump in gdb and find frame containing main function. Then go to this frame and print values of argv and argc. Here is sample gdb session.
[root#localhost ~]# gdb ./a.out core.2020
GNU gdb (GDB) 7.2
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/a.out...done.
[New Thread 2020]
warning: Can't read pathname for load map: Input/output error.
Reading symbols from /usr/lib/libstdc++.so.6...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libstdc++.so.6
Reading symbols from /lib/libm.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libm.so.6
Reading symbols from /lib/libgcc_s.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/libgcc_s.so.1
Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/ld-linux.so.2
Core was generated by `./a.out'.
Program terminated with signal 6, Aborted.
#0 0x0027b424 in __kernel_vsyscall ()
(gdb) bt
#0 0x0027b424 in __kernel_vsyscall ()
#1 0x00b28b91 in raise () from /lib/libc.so.6
#2 0x00b2a46a in abort () from /lib/libc.so.6
#3 0x007d3397 in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib/libstdc++.so.6
#4 0x007d1226 in ?? () from /usr/lib/libstdc++.so.6
#5 0x007d1263 in std::terminate() () from /usr/lib/libstdc++.so.6
#6 0x007d13a2 in __cxa_throw () from /usr/lib/libstdc++.so.6
#7 0x08048940 in main (argv=1, argc=0xbfcf1754) at test.cpp:14
(gdb) f 7
#7 0x08048940 in main (argv=1, argc=0xbfcf1754) at test.cpp:14
14 throw std::runtime_error("123");
(gdb) p argv
$1 = 1
(gdb) p argc
$2 = (char **) 0xbfcf1754
(gdb)
Looks like you need to start from the basics..!!
compiler your application code with -g flag, make sure you dont strip it.
Say if I wanted to compile hello.c
gcc -c -g hello.c -o hello.o
gcc hello.o -o hello
now if you dont want to debug
ulimit -c unlimited
./hello
when the application crashes a core file wiil be generated.
To examine the core file
"gdb ./hello core.$$$" this will list you your stack.
you can also choose to debug the image
gdb hello
There are a lot of stuffs over the internet about GDB, do go through them.