g++ "value temporarily unavailable, due to optimizations" - debugging

I'm getting some "value temporarily unavailable, due to optimizations" problems, but I am compiling with debug enabled, as far as I know.
I.e. I'm using -g -O0 -fno-inline flags, so I'm not sure why is this still happening. Is it some flag I missed?
Compiler is g++-mp-4.6 (GCC) 4.6.3, OS is OSX 10.6 Darwin Palace-of-the-Nine-Moons.local 10.8.0 Darwin Kernel Version 10.8.0: Tue Jun 7 16:33:36 PDT 2011; root:xnu-1504.15.3~1/RELEASE_I386 i386
Full compile options are g++-mp-4.6 -Wall -Werror -Wno-unused -g -O0 -fno-inline -I/usr/local/include -I../allig -std=c++0x -c src/Toolbox.cpp -o o/Toolbox.o for every file.
gdb session:
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000021
[Switching to process 23874]
0x0000000100035d64 in al_get_bitmap_width ()
(gdb) bt
#0 0x0000000100035d64 in al_get_bitmap_width ()
#1 0x0000000100005e47 in Icon::resize (this=0x101244530, w=<value temporarily unavailable, due to optimizations>, h=<value temporarily unavailable, due to optimizations>) at ../allig/Icon.cpp:24
#2 0x0000000100005e1f in Icon::create_icon (this=0x101244530, _icon_size=<value temporarily unavailable, due to optimizations>) at ../allig/Icon.cpp:20
#3 0x000000010000ae24 in Icontainer::add_icon (this=0x101244210, tt=0x101244530) at ../allig/Icontainer.cpp:18
#4 0x0000000100002d58 in _al_mangled_main (argc=1, argv=0x7fff5fbff600) at src/mapedit.cpp:202
#5 0x000000010009ff17 in +[AllegroAppDelegate app_main:] ()
#6 0x00007fff82d45114 in __NSThread__main__ ()
#7 0x00007fff81f4afd6 in _pthread_start ()
#8 0x00007fff81f4ae89 in thread_start ()
(gdb) up
#1 0x0000000100005e47 in Icon::resize (this=0x101244530, w=<value temporarily unavailable, due to optimizations>, h=<value temporarily unavailable, due to optimizations>) at ../allig/Icon.cpp:24
24 ow=al_get_bitmap_width(icon);
Current language: auto; currently c++
[...]
(gdb) up
#2 0x0000000100005e1f in Icon::create_icon (this=0x101244530, _icon_size=<value temporarily unavailable, due to optimizations>) at ../allig/Icon.cpp:20
20 resize(_icon_size,_icon_size);
(gdb) print _icon_size
$2 = <value temporarily unavailable, due to optimizations>
(gdb) up
#3 0x000000010000ae24 in Icontainer::add_icon (this=0x101244210, tt=0x101244530) at ../allig/Icontainer.cpp:18
18 tt->create_icon(icon_size);
(gdb) print icon_size
$3 = 32 ' '
(gdb) quit
code snippets:
void Icon::resize (unsigned char w, unsigned char h) {
unsigned short ow,oh;
ow=al_get_bitmap_width(icon);
up
void Icon::create_icon (unsigned char _icon_size) {
resize(_icon_size,_icon_size);
}
up
int Icontainer::add_icon (Icon *tt) {
int ret=icons.size();
tt->tool=TOOL_TILE;
tt->create_icon(icon_size);
finally here the icon size was available.

Related

Why does macOS kill static executables created by clang?

I have a minimal c program for the m1 arm cpu that returns 42:
void _start() {
asm("mov x0, #42;");
asm("mov x16, #1;");
asm("svc 0x80;");
}
This code compiles after telling clang to use the _start symbol and returns the correct value.
clang -Wl,-e, -Wl,__start test.c -o dyn.out
./dyn.out ; echo $?
42
However this binary still has dynamic links according to otool:
otool -L ./dyn.out
./dyn.out:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.100.3)
After telling clang to produce a unsigned static binary however macOS then immediately kills the binary when trying to run.
clang -Wl,-e, -Wl,__start -static -nostdlib test.c -o static_no_sign.out
zsh: killed ./static_no_sign.out
Signing the binary before running also produces the same problem.
clang -Wl,-e, -Wl,__start -static -nostdlib test.c -o static_sign.out
codesign -s - static_sign.out
./static_sign.out
zsh: killed ./static_sign.out
The following messages are produced in Console:
taskgated: UNIX error exception: 3
taskgated: no signature for pid=93166 (cannot make code: UNIX[No such process])
But codesign can verify the signature
codesign -v -v static_sign.out
static_sign.out: valid on disk
static_sign.out: satisfies its Designated Requirement
Can anyone clarify why macOS is deciding to kill the clang produced binaries?
Because static binaries are explicitly disallowed on any architecture other than x86_64.
XNU contains this code piece in the Mach-O loader:
case MH_EXECUTE:
if (depth != 1 && depth != 3) {
return LOAD_FAILURE;
}
if (header->flags & MH_DYLDLINK) {
/* Check properties of dynamic executables */
if (!(header->flags & MH_PIE) && pie_required(header->cputype, header->cpusubtype & ~CPU_SUBTYPE_MASK)) {
return LOAD_FAILURE;
}
result->needs_dynlinker = TRUE;
} else if (header->cputype == CPU_TYPE_X86_64) {
/* x86_64 static binaries allowed */
} else {
/* Check properties of static executables (disallowed except for development) */
#if !(DEVELOPMENT || DEBUG)
return LOAD_FAILURE;
#endif
}
break;
If you do the exact same thing on x86_64, it works:
void _start()
{
__asm__ volatile
(
".intel_syntax noprefix\n"
"mov eax, 0x2000001\n"
"mov edi, 42\n"
"syscall"
);
}
% clang -Wl,-e,__start -static -nostdlib t.c -o t -arch x86_64
% ./t
% echo $?
42

Program received SIGSEGV - invalid memory reference

I wrote a small linker in fortran-cpp to read a file with some numbers.
$cat mainProg.f
program fprogram
real*8 c(30)
do i=1,30
c(i) = i * 1.0
end do
print*,"Before calling cpp function"
c PASS ARRAY "C" TO CPP
call pass_to_cpp(c)
print*,"After calling cpp function"
do i=1,30
print*,' c =',c(i)
end do
print*,"I'm done here ..!!"
c stop
end
and,
$cat cprog.C
#include<iostream>
#include<cmath>
#include<fstream>
using namespace std;
extern "C" {
void pass_to_cpp_(double *c);
}
void pass_to_cpp_(double *c)
{
ifstream myfile ("example.txt");
for(int i=0; i<30; i++)
{
myfile >> c[i];
cout <<"called = " << i << "\n";
}
}
I am building this on ubuntu 16.04 to be run on a windows machine. I am usin mingw for compiling.
Here is the error on windows:
called = 0
Program received a signal SIGSEGV: Segmentation fault - invalid memory reference
Backtrace for this error:
#0 ffffffffffffff
#1 ffffffffffffff
#2 ffffffffffffff
#3 ffffffffffffff
#4 ffffffffffffff
#5 ffffffffffffff
#6 ffffffffffffff
#7 ffffffffffffff
#8 ffffffffffffff
#9 ffffffffffffff
#10 ffffffffffffff
#11 ffffffffffffff
#12 ffffffffffffff
#13 ffffffffffffff
#14 ffffffffffffff
#15 ffffffffffffff
File 'example.txt' is a simple file with 30 numbers.
Any suggestions on what is the cause of the error?
I compiled with this:
$ x86_64-w64-mingw32-gfortran -c main_read.f
$ x86_64-w64-mingw32-g++ -c cread.C
$ x86_64-w64-mingw32-gfortran -o read.exe main_read.o cread.o -lstdc++ -static
If I dont use -static, it complains 'libgfortran3.dll not found'.

Linker error using gcc and clang together on macos sierra

I have to compile c++ code with g++ 6.4.0 (Homebrew g++-6) to a static lib, which is then wrapped into a C static lib (Homebrew gcc-6) and linked to a clang++ (clang 8.1.0) app on macos sierra. So the picture is:
c++ (gcc) wrapped in c (gcc) linked to clang app.
As a testcase I use shared-lib.cpp:
#include <iostream>
using namespace std;
void foo()
{
cerr << "Hi from the shared lib" << endl;
}
together with shared-lib.h
extern void foo();
and wrapper-lib.c
#include "shared-lib.h"
int wrapper()
{
foo();
return 123;
}
along with wrapper-lib.h
#ifdef __cplusplus
extern "C"
{
#endif
extern int wrapper();
#ifdef __cplusplus
}
#endif
The main.cpp that uses all the libs looks like
#include <iostream>
#include <string>
#include "shared-lib.h"
#include "wrapper-lib.h"
using namespace std;
int main()
{
auto s = "Hello world from main";
cout << s << endl;
foo(); // from c++ lib
int result = wrapper(); // from c wrapper lib
cout << "wrapper returned " << result << endl;
return 0;
}
My test built script is
g++-6 --version
echo -----------------------
echo build shared-lib .o with g++
g++-6 -c -Wall -fpic -std=c++11 shared-lib.cpp
echo build a wrapper library in C with gcc
gcc-6 -c -Wall -fpic wrapper-lib.c
echo build static libshared-lib.a
ar rcs libshared-lib.a shared-lib.o
echo build static libwrapper-lib.a
ar rcs libwrapper-lib.a wrapper-lib.o
echo build main with clang
clang++ --version
echo ----------------------
clang++ -v -L/Users/worker -Wall -std=c++11 -stdlib=libstdc++ -lwrapper-lib -lshared-lib main.cpp -o main
echo start the app
./main
If I only call the gcc c++ function foo() then everything works fine.
If I call the C wrapper function wrapper(), then clang comes up with:
Undefined symbols for architecture x86_64:
"_foo", referenced from:
_wrapper in libwrapper-lib.a(wrapper-lib.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Maybe someone can simply spot, what's wrong with my workflow?
Note, for completeness the whole build script output
Note2, since ar in the gcc#6 toolchain does not work (liblto_plugin.so missing) I use clang's ar tool...
mac-mini:~ worker$ ./build-test.sh
g++-6 (Homebrew GCC 6.4.0) 6.4.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-----------------------
build shared-lib .o with g++
build a wrapper library in C with gcc
build static libshared-lib.a
build static libwrapper-lib.a
build main with clang
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 8.1.0 (clang-802.0.41)
Target: x86_64-apple-darwin16.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
----------------------
Apple LLVM version 8.1.0 (clang-802.0.41)
Target: x86_64-apple-darwin16.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
clang: warning: libstdc++ is deprecated; move to libc++ [-Wdeprecated]
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" -cc1 -triple x86_64-apple-macosx10.12.0 -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -discard-value-names -main-file-name main.cpp -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -masm-verbose -munwind-tables -target-cpu penryn -target-linker-version 278.4 -v -dwarf-column-info -debugger-tuning=lldb -resource-dir /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/8.1.0 -stdlib=libstdc++ -Wall -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /Users/worker -ferror-limit 19 -fmessage-length 166 -stack-protector 1 -fblocks -fobjc-runtime=macosx-10.12.0 -fencode-extended-block-signature -fcxx-exceptions -fexceptions -fmax-type-align=16 -fdiagnostics-show-option -fcolor-diagnostics -o /var/folders/18/m18t0kxx03d7__31kg3wrsr40000gq/T/main-337db7.o -x c++ main.cpp
clang -cc1 version 8.1.0 (clang-802.0.41) default target x86_64-apple-darwin16.7.0
ignoring nonexistent directory "/usr/include/c++/4.2.1/i686-apple-darwin10/x86_64"
ignoring nonexistent directory "/usr/include/c++/4.0.0"
ignoring nonexistent directory "/usr/include/c++/4.0.0/i686-apple-darwin8/"
ignoring nonexistent directory "/usr/include/c++/4.0.0/backward"
#include "..." search starts here:
#include <...> search starts here:
/usr/include/c++/4.2.1
/usr/include/c++/4.2.1/backward
/usr/local/include
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/8.1.0/include
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
/usr/include
/System/Library/Frameworks (framework directory)
/Library/Frameworks (framework directory)
End of search list.
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld" -demangle -lto_library /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/libLTO.dylib -no_deduplicate -dynamic -arch x86_64 -macosx_version_min 10.12.0 -o main -L/Users/worker -lwrapper-lib -lshared-lib /var/folders/18/m18t0kxx03d7__31kg3wrsr40000gq/T/main-337db7.o -lstdc++ -lSystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/8.1.0/lib/darwin/libclang_rt.osx.a
Undefined symbols for architecture x86_64:
"_foo", referenced from:
_wrapper in libwrapper-lib.a(wrapper-lib.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
You compile shared-lib.cpp with:
g++-6 -c -Wall -fpic -std=c++11 shared-lib.cpp
And you compile wrapper-lib.c with:
gcc-6 -c -Wall -fpic wrapper-lib.c
Have a look at the symbol table of shared-lib.o. It's something like:
$ readelf -s shared-lib.o
Symbol table '.symtab' contains 24 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS shared-lib.cpp
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1
3: 0000000000000000 0 SECTION LOCAL DEFAULT 3
4: 0000000000000000 0 SECTION LOCAL DEFAULT 4
5: 0000000000000000 0 SECTION LOCAL DEFAULT 5
6: 0000000000000000 1 OBJECT LOCAL DEFAULT 5 _ZStL19piecewise_construc
7: 0000000000000000 1 OBJECT LOCAL DEFAULT 4 _ZStL8__ioinit
8: 0000000000000032 73 FUNC LOCAL DEFAULT 1 _Z41__static_initializati
9: 000000000000007b 21 FUNC LOCAL DEFAULT 1 _GLOBAL__sub_I_shared_lib
10: 0000000000000000 0 SECTION LOCAL DEFAULT 6
11: 0000000000000000 0 SECTION LOCAL DEFAULT 9
12: 0000000000000000 0 SECTION LOCAL DEFAULT 10
13: 0000000000000000 0 SECTION LOCAL DEFAULT 8
14: 0000000000000000 50 FUNC GLOBAL DEFAULT 1 _Z3foov
15: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND _GLOBAL_OFFSET_TABLE_
16: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND _ZSt4cerr
17: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND _ZStlsISt11char_traitsIcE
18: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND _ZSt4endlIcSt11char_trait
19: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND _ZNSolsEPFRSoS_E
20: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND _ZNSt8ios_base4InitC1Ev
21: 0000000000000000 0 NOTYPE GLOBAL HIDDEN UND __dso_handle
22: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND _ZNSt8ios_base4InitD1Ev
23: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND __cxa_atexit
(I'm working on Ubuntu, not OS X.)
Note that there is only one global function defined in this object file and
its name is _Z3foov.
That's the mangled name of the C++ function called foo in shared-lib.cpp. That's
the name the linker sees.
Now the symbol table of wrapper-lib.o:
Symbol table '.symtab' contains 11 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS wrapper-lib.c
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1
3: 0000000000000000 0 SECTION LOCAL DEFAULT 3
4: 0000000000000000 0 SECTION LOCAL DEFAULT 4
5: 0000000000000000 0 SECTION LOCAL DEFAULT 6
6: 0000000000000000 0 SECTION LOCAL DEFAULT 7
7: 0000000000000000 0 SECTION LOCAL DEFAULT 5
8: 0000000000000000 21 FUNC GLOBAL DEFAULT 1 wrapper
9: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND _GLOBAL_OFFSET_TABLE_
10: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND foo
This object file makes an undefined reference to foo, because wrapper-lib.c
is a C source file and you compiled it as such. C does not mangle names. No definition
of foo is provided by any object file in your linkage, so it fails with that
symbol unresolved.
To avoid this and accomplish your linkage, you can direct the C++ compiler
not to mangle the name foo, when compiling shared-lib.cpp. You do so like:
shared-lib.cpp
#include <iostream>
using namespace std;
extern "C" {
void foo()
{
cerr << "Hi from the shared lib" << endl;
}
} //extern "C"
Enclosing the definition of foo in extern "C" {...} has no effect on
C++ compilation except the one you want: the symbol foo will be emitted
as a C symbol; not mangled.
Having done that, you must of course follow suit in shared-lib.h:
shared-lib.h
#ifndef SHARED_LIB_H
#define SHARED_LIB_H
#ifdef __cplusplus
extern "C" {
#endif
void foo();
#ifdef __cplusplus
}
#endif
#endif
With those corrections, let's try again:
$ g++-6 -c -Wall -fpic -std=c++11 shared-lib.cpp
and check the symbol table:
$ readelf -s shared-lib.o | grep foo
14: 0000000000000000 50 FUNC GLOBAL DEFAULT 1 foo
Now the one global function defined is foo, not _Z3foov, and your
linkage will succeed.
If you want to write a C++ library that exports a C++ API and not a C API to
the linker, then you cannot call its API from C except by discovering the
mangled names of the API (with readelf, nm, objdump) and explicitly
calling those mangled names from C. Thus without those extern "C" fixes,
your linkage would also succeed with:
wrapper-lib.c
extern void _Z3foov(void);
int wrapper()
{
_Z3foov();
return 123;
}

GCC linker ignores symbols in a .a library that I have confirmed are present

I have a really perplexing problem in GCC.
I get the following error:
gcc -Wall -Werror -L/Users/red_angel/chorebox_sys/lib -o products/chbc2c -lchorebox ofiles/main.o
Undefined symbols for architecture x86_64:
"_chbclib_flushout", referenced from:
_main in main.o
"_chorebox_argc", referenced from:
_chorebox_command_line in libchorebox.a(chorebox_command_line.o)
"_chorebox_argv", referenced from:
_chorebox_command_line in libchorebox.a(chorebox_command_line.o)
"_chorebox_env", referenced from:
_chorebox_command_line in libchorebox.a(chorebox_command_line.o)
"_mn_command_options", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [products/chbc2c] Error 1
What's wrong with this error? I have confirmed that the _chorebox_argc symbol is indeed present in "libchorebox.a".
I confirmed it by running the command:
nm /Users/red_angel/chorebox_sys/lib/libchorebox.a | cat -n | chodo -_chorebox_argc flip
As the "chodo" command is an command I wrote that you may not be familiar - I will explain what it does. It reads from Standard Input, and forward to Standard Output every line that matches the search pattern. In this case (to make a long story short) it outputs every line containing the "_chorebox_argc" string.
I get the following output:
3 0000000000000004 C _chorebox_argc
55 U _chorebox_argc
To get a closer look at the relevant part of the file, I type the same command, only this time omitting the "chodo" command at the end of the piped series of commands --- and hereby will copy/paste to you the relevant part of that file:
1
2 /Users/red_angel/chorebox_sys/lib/libchorebox.a(vars.o):
3 0000000000000004 C _chorebox_argc
4 0000000000000008 C _chorebox_argv
5 0000000000000008 C _chorebox_env
6
7 /Users/red_angel/chorebox_sys/lib/libchorebox.a(chorebox_mlc.o):
8 00000000000000c8 s EH_frame0
9 0000000000000075 s L_.str
10 U ___stderrp
11 U _chorebox_argv
12 0000000000000000 T _chorebox_mlc
13 00000000000000e0 S _chorebox_mlc.eh
14 U _exit
15 U _fflush
16 U _fprintf
17 U _malloc
18
19 /Users/red_angel/chorebox_sys/lib/libchorebox.a(chorebox_apend_string.o):
20 0000000000000078 s EH_frame0
21 0000000000000000 T _chorebox_apend_string
22 0000000000000090 S _chorebox_apend_string.eh
23 U _chorebox_join_string
24 U _free
25
Needless to say ---- the symbol is definitely present in the "libchorebox.a" file ----- so why is the GCC linker complaining that it is not found?
After some discussion in chat, we discovered that the problem lay in 'common' definitions. A simplified version of the code causing trouble follows. The system is Mac OS X (Mavericks and Yosemite).
With common definitions only
vars.h
extern int chorebox_argc;
extern char **chorebox_argv;
extern char **chorebox_envp;
vars.c
#include "vars.h"
int chorebox_argc;
char **chorebox_argv;
char **chorebox_envp;
main.c
#include "vars.h"
int main(int argc, char **argv, char **envp)
{
chorebox_argc = argc;
chorebox_argv = argv;
chorebox_envp = envp;
return argc;
}
Compilation 1
$ gcc -c vars.c
$ nm vars.o
0000000000000004 C _chorebox_argc
0000000000000008 C _chorebox_argv
0000000000000008 C _chorebox_envp
$ ar rv libvars.a vars.o
ar: creating archive libvars.a
a - vars.o
$ ranlib libvars.a
warning: ranlib: warning for library: libvars.a the table of contents is
empty (no object file members in the library define global symbols)
$ gcc -c main.c
$ gcc -o program main.o vars.o
$ gcc -o program main.o -L. -lvars
Undefined symbols for architecture x86_64:
"_chorebox_argc", referenced from:
_main in main.o
"_chorebox_argv", referenced from:
_main in main.o
"_chorebox_envp", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
$
Note the C in the output from nm. That indicates a 'common' definition of the variables. It isn't enough, on its own, to make them into variable definitions — witness the message from ranlib.
I'm not sure if this is new behaviour in Mac OS X or not. However, it seems that having a source file that only defines uninitialized variables isn't sufficient when the variables are defined in a library, though it is sufficient when the object file is linked directly.
With variable definitions
vardefs.c
#include "vars.h"
int chorebox_argc = 0;
char **chorebox_argv = 0;
char **chorebox_envp = 0;
This has explicitly initialized versions of the variables. The initializer values are the same as the default values, but the explicit initialization makes all the difference.
Compilation 2
$ rm libvars.a
$ gcc -c vardefs.c
$ ar rv libvars.a vardefs.o
ar: creating archive libvars.a
a - vardefs.o
$ gcc -o program main.o -L. -lvars
$
The explicitly initialized variables are picked up from the library without problem.
With one variable definition
vars.h
extern int chorebox_argc;
extern char **chorebox_argv;
extern char **chorebox_envp;
extern int make_believe;
vars.c
#include "vars.h"
int chorebox_argc;
char **chorebox_argv;
char **chorebox_envp;
int make_believe = 59;
main.c
#include "vars.h"
int main(int argc, char **argv, char **envp)
{
chorebox_argc = argc;
chorebox_argv = argv;
chorebox_envp = envp;
make_believe = 1;
return argc;
}
Compilation 3
$ gcc -c vars.c
$ ar rv libvars.a vars.o
ar: creating archive libvars.a
a - vars.o
$ nm vars.o
0000000000000004 C _chorebox_argc
0000000000000008 C _chorebox_argv
0000000000000008 C _chorebox_envp
0000000000000000 D _make_believe
$ gcc -c main.c
$ gcc -o program main.o -L. -lvars
$
Note that adding the initialized make_believe is sufficient to pull the object file from the library, and the common definitions for the other variables are then sufficient to satisfy the linker.
Lessons
Although the linking order was part of the problem, it was not the whole problem.
Providing uninitialized global variables in a library doesn't always work, especially if there are no other definitions in the same source file.
As I noted in the chat, it is generally not a good idea to provide direct access to global variables. It would be better to provide functional interfaces to access (get and set) the variables.
Put the -l option after the file that needs it (ofiles/main.o)
See this question for more information on link order.

Program freezes under gdb when exception occurs

I compiled with g++ a simple test program:
int main()
{
try
{
printf("before\n");
throw 1;
}
catch(int i)
{
printf("catched int\n");
}
catch(...)
{
printf("catched(...)\n");
}
}
Normally works ok with or without debug info included.
But when debugged with gdb it always hangs on "throw 1;" line so I'm not able to debug programs, that normally throws exceptions.
The last information from debugger is:
Catchpoint 1 (exception thrown), 0x00007ffff7b8f9e0 in __cxa_throw () from /usr/lib/libstdc++.so.6
My compilation and linking options:
g++ -Wshadow -Wunreachable-code -Wswitch-enum -Wswitch-default -Wextra -Wall -pg -g -m64 -c main.cpp
g++ -o exec/exception_problem obj/main.o -pg
My environment:
ubuntu 10.10, 64bit;
g++/gcc 4.4.5;
gdb 7.2;
debugged under codeblocks svn rev 7440
Any ideas what is the problem?
Additional info:
Last two lines of gdb log are:
Catchpoint 1 (exception thrown), 0x00007ffff7b8f9e0 in __cxa_throw () from /usr/lib/libstdc++.so.6
>>>>>>cb_gdb:
The last character in log is colon.
gdb commandline:
/usr/bin/gdb -nx -fullname -quiet -args exec/exception_problem
I did not found any *gdbinit* in my home directory; global gdbinit is empty. Is it possible that codeblocks prepares specific gdbinit and puts it to gdb?
Best regards for all.
Catchpoint 1 (exception thrown) ...
Is there something in your .gdbinit that you haven't told us about? (Perhaps catch throw ?)
Is the Catchpoint 1 really the last line that GDB prints? Here is what I see:
Reading symbols from /tmp/a.out...done.
Catchpoint 1 (throw)
(gdb) run
before
Catchpoint 1 (exception thrown), __cxxabiv1::__cxa_throw (obj=0x602090, tinfo=0x601060, dest=0) at ../../../../src/libstdc++-v3/libsupc++/eh_throw.cc:70
70 ../../../../src/libstdc++-v3/libsupc++/eh_throw.cc: No such file or directory.
in ../../../../src/libstdc++-v3/libsupc++/eh_throw.cc
(gdb) c
catched int
[Inferior 1 (process 16008) exited normally]
(gdb) q

Resources