Bug 18629 - global variable
Summary: global variable
Status: NEW
Alias: None
Product: gdb
Classification: Unclassified
Component: gdb (show other bugs)
Version: 7.9
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-07-06 23:37 UTC by Roger Davis
Modified: 2015-07-07 21:18 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Roger Davis 2015-07-06 23:37:56 UTC
Hi all,

I am having problems with gdb being unable to recognize the type of primitive global variables within an executable compiled from multiple source files under MacOS Yosemite 10.10.4 and Xcode 6.4 (6E35b). The same problem occurs whether I compile with either /usr/bin/cc or /usr/bin/gcc, both of which appear to be using Apple LLVM version 6.1.0 (clang-602.0.53) based on LLVM 3.6.0svn. (I have not tried with a self-built gcc compiled from gcc source.) I first noticed this a few days ago after a MacPorts update which installed gdb 7.9.1, but the same problem occurred when I deactivated MacPorts gdb 7.9.1 and reverted to MacPorts gdb 7.7.1. I also tried building gdb 7.7.1 from source, and also get the same problem. (Also note that MacPorts 7.9.1 gdb has a startup problem which may be related to this issue, see the end of this message.)

You can reproduce this bug by creating the following two files m0.c and m1.c:

% cat m0.c
#include <stdio.h>
float gf;
extern void func();
int main() {
        gf= 1.23;
        printf("gf: %4.2f\n", gf);
        func();
}

% cat m1.c
#include <stdio.h>
extern float gf;
void func() {
        float lf;
        lf= 4.56;
        printf("lf: %4.2f\n", lf);
}

Then compile as follows:

% cc -g -c m0.c -o m0.o
% cc -g -c m1.c -o m1.o
% cc -g -o m m0.o m1.o

When you debug with gdb, the type of the global float gf is unknown to gdb from within main():

% /usr/local/bin/gdb m
GNU gdb (GDB) 7.7.1
...
Reading symbols from m...done.
(gdb) break main
Breakpoint 1 at 0x100000eee: file m0.c, line 5.
(gdb) break func
Breakpoint 2 at 0x100000f27: file m1.c, line 5.
(gdb) run
Starting program: /private/tmp/m
Breakpoint 1, main () at m0.c:5
5               gf= 1.23;
(gdb) s
6               printf("gf: %4.2f\n", gf);
(gdb) s
gf: 1.23
7               func();
(gdb) ptype gf
type = <data variable, no debug info>
(gdb) print gf
$1 = 1067282596

However, the type of local float lf within func() is known:

(gdb) continue
Continuing.
Breakpoint 2, func () at m1.c:5
5               lf= 4.56;
(gdb) s
6               printf("lf: %4.2f\n", lf);
(gdb) s
lf: 4.56
7       }
(gdb) ptype lf
type = float
(gdb) print lf
$2 = 4.55999994

The type of the global float gf is also unknown to gdb from within func():

(gdb) ptype gf
type = <data variable, no debug info>
(gdb) print gf
$3 = 1067282596

If instead of using two source files m[01].c you combine them into the single file s.c with the contents

#include <stdio.h>
float gf;
int main() {
        void func();
        gf= 1.23;
        printf("gf: %4.2f\n", gf);
        func();
}

void func() {
        float lf;
        lf= 4.56;
        printf("lf: %4.2f\n", lf);
}

and compile with

% cc -o s -g s.c

then gdb works perfectly well, recognizing the type of gf and correctly printing its floating point value within either main() or func().

Naturally, the actual program I am having a problem with is much larger and really needs to be in multiple files, but I think this example shows the problem about as succinctly as possible. The problem is not limited to float variables -- a global int variable shows the same issue of unknown type.

I have noticed that when I compile the above single-file s.c code, a directory s.dSYM is created. This is supposedly done when a dsymutil symbol utility is implictly run by cc. I have read that dsymutil is *not* run when the source files are separately compiled into .o files and the latter are then linked with a separate command (as in my multi-file cc command sequence shown above). Perhaps this has some bearing on the problem?

With regard to MacPorts gdb 7.9.1, I am also seeing the following startup problem (as noted at the end of the first paragraph of this message) when the executable is actually run in gdb. Note the references to the various missing files "/BinaryCache/coreTLS/...". There is no /BinaryCache directory on my system.

% gdb m
GNU gdb (GDB) 7.9.1
...
(gdb) break main
Breakpoint 1 at 0x100000eee: file m0.c, line 5.
(gdb) run
Starting program: /private/tmp/m
warning: `/BinaryCache/coreTLS/coreTLS-35.30.2~2/Objects/coretls.build/coretls.build/Objects-normal/x86_64/system_coretls_vers.o': can't open to read symbols: No such file or directory.
warning: Could not open OSO archive file "/BinaryCache/coreTLS/coreTLS-35.30.2~2/Symbols/BuiltProducts/libcoretls_ciphersuites.a"
warning: Could not open OSO archive file "/BinaryCache/coreTLS/coreTLS-35.30.2~2/Symbols/BuiltProducts/libcoretls_handshake.a"
warning: Could not open OSO archive file "/BinaryCache/coreTLS/coreTLS-35.30.2~2/Symbols/BuiltProducts/libcoretls_record.a"
warning: Could not open OSO archive file "/BinaryCache/coreTLS/coreTLS-35.30.2~2/Symbols/BuiltProducts/libcoretls_stream_parser.a"

Thanks,

Roger Davis
Univ. of Hawaii
Comment 1 Keith Seitz 2015-07-07 00:27:54 UTC
Re: the "missing" global, this sounds a lot like gdb/18436. Does the workaround listed in comments #9 and #10 in that bug work for you?

As for the warnings about "could not open OSO archive", well that's in Mac-specific code, and I haven't any real idea if one should be worried about it. Since they were coded as warnings, I'd say that you're safe to ignore them. Should you need their debug info, you can always add-symbol-file them from their real locations in your file system, e.g.
Comment 2 Roger Davis 2015-07-07 01:34:49 UTC
Hi Keith,

You are correct, this sounds very much like 18436. I did do a prior search but did not turn that one up, sorry. I'll hazard a very confident guess that this has nothing to do with a dynamically allocated array, however, and everything to do with non-local variable declaration. The compile-methodology workarounds posted in comments #9-10 of 18436 do not work for me, and I'll hazard an equally confident guess that it's because my case involves multiple source files -- probably compilation of a single source file with those particular commands yields the program.dSYM symbol table directory that seems to make global variable type recognition in gdb work at this particular moment in the MacOS/Xcode/gdb universe. Compiling separate object files and linking them in yet another separate step does *not* result in the implicit call to dsymutil which creates this .dSYM directory (or so I've read in another forum).

I have discovered a very half-assed partial workaround -- for simple float variables I can successfully print them with

(gdb) p/f myglobalfloatvar

However, I've got lots of global instantiations of complex struct typedefs, plus doubles, long doubles, etc. Yuck. And as I mentioned earlier, it's just not practical for me to cram everything into a single source file. I think I need an actual fix for this or I'm seriously hosed, and I expect anyone else writing programs of any non-trivial size for MacOS will be too.

Thanks,

Roger
Comment 3 Pedro Alves 2015-07-07 09:23:10 UTC
Ideally GDB would be taught about automatically looking for debug info in the separate dSYM files, but I'm not aware of anyone working on that.  Apple's gdb fork has built in dSYM support that was never merged upstream.  (grep for dSYM in the Apple sources).

You could try loading the dSYM files manually, with:

 (gdb) add-symbol-file /path/to/whatever.dSYM

I don't know if that works.  Worth a try.

This page:

 http://stackoverflow.com/questions/584825/dsym-directories-while-compiling-c-code-in-macos

seems to mention the quirk you stumbled on, and seems to suggest that it's possible to disable separate dSYMs in Xcode, and I assume there are corresponding llvm/gcc switches for that.
Comment 4 Roger Davis 2015-07-07 21:12:22 UTC
Thanks Pedro, but unfortunately when I compile multiple source files separately and then link them later, there are *NO* .dSYM directories created and thus nothing else available to manually load into gdb as you suggested.

After thrashing around a bit more today I have discovered a workaround, but it strikes me as uncomfortably shaky and prone to future collapse. I have been using the MacPorts gdb beginning with the Mavericks release because at that time gdb was removed from Xcode. I have always just used the standard MacPorts 'gdb' port since Mavericks and until now it has worked just fine without the global variable problem, but looking through some other discussion threads I am now aware of the MacPorts 'gdb-apple' port, which I would assume to be somehow related to the pre-Mavericks Xcode gdb and/or the Apple gdb fork you mentioned. I just installed gdb-apple and it seems to work fine so far, although it produces even more warnings of the form

  warning: Could not find object file "/BinaryCache/coreTLS...

than does the current MacPorts 7.9.1 standard gdb port. The gdb-apple port seems pretty old, however (6.3), which makes me very nervous about counting on its continued viability.

What's still a mystery to me is why the previous MacPorts gdb 7.7.1 port did not exhibit this bug under Xcode 6.3 but now also fails under the new Xcode 6.4 just like the current MacPorts gdb 7.9.1. At this point I think I probably need to find someone at MacPorts to explain (and hopefully fix!) things.

Thanks,

Roger
Comment 5 Roger Davis 2015-07-07 21:18:01 UTC
PS: Pedro, I did go grubbing around through Xcode preferences settings and cc command options, but found nothing useful. cc has a very small number of -gXXX command options, e.g., -gdwarf-2, etc., but I tried them all and nothing made this problem go away. I was not able to locate any Xcode preferences setting that seemed remotely related to debugger symbol table generation. I know little about Xcode, however, as the only parts of it that I use are the command-line tools make, cc, etc.