gdb automatically steps into inline functions - c++

I'm debugging a running program with gdb 6.6 on solaris, and noticed that sometimes gdb steps into (inline) functions, even though I issued a next command.
My development host was recently reinstalled with a slightly newer build of solaris 10, and I know for sure the auto-stepping was not present before the host was reinstalled. The code is compiled with the same options since the makefiles and all the source code is unchanged since host reinstallation.
Is there any setting/new default option which influences gdb's debugging behaviour that I can check? Does anyone know why my gdb now auto-steps? Its a pain really ...
[edit] to clarify: I did not mean the inline keyword, but rather methods/functions which are implemented in the header file. Example:
header.hpp:
class MyClass
{
public:
void someFunc() { ... does something }
}
source.cc:
{
MyClass instance;
instance.someFunc(); // doing NEXT in gdb will actually STEP into header.hpp
}

Your new version of Solaris may have included a new version of the C or C++ compiler. The new compiler may be optimizing more aggressively than it did before. Check your optimization flags. If you are using GCC, you can disable inlining with -fno-inline (note that methods that are implemented in the class in header files are inlined by default which can be disabled with -fno-default-inline). If you are using the native Solaris compiler, you will need to check its documentation.
A similar problem was reported here. In the comment, the poster mentioned changing the debug symbol to use STABS resolved the issue.
You mentioned in a comment to my answer that STABS works, but is not acceptable. Also, you mentioned that you are unable to reproduce the issue with a simple example. It will be difficult to trouble shoot this issue if you have to recompile your entire project each time to perform a test. Try to isolate the problem to a few source files in your project. See what they have in common (do they include a common header file, do they use a pragma, are the compilation options a little different from the other source fies, etc.), and try to create a small example with the same problem. This will make it easier to identify the root cause of your issue and determine how to resolve it. Without this data, we are just the blind leading the blind.

Related

Improper execution in Xcode 7.3.1 and later

I have an existing application, which uses several static libraries (all of which I am compiling). I am compiling on the command line, with make and clang, not using the IDE. Previous to Xcode 7.3, all compiled and executed as I expect. With Xcode 7.3, in my release build (which adds -O2) I am getting strange behaviour with virtual inline functions - sometimes they return completely garbage values. This seems to happen in classes which have only virtual inline methods, eg:
class MyClass
{
public:
virtual ~MyClass() { }
virtual int foo() { return 1; }
};
In my investigation of the issue (trying several related compile flags), it appears adding -fno-inlines and/or -fvisibility-inlines-hidden works around the issue, and the program executes as expected. However, from my understanding, these are simply hints on how to optimize, and should not affect program execution (specifically, the second should only affect DSOs, which I am not using). This leads me to several questions:
Searching Apple support forums, I could not find any reference to similar errors. Is this an known issue?
Is this code somehow malformed? If so, is there some way I can get feedback from the compiler (eg. via a diagnostic) about the problem?
Why do the compiler flags I mentioned fix the issue? Am I misinterpreting their meaning?

-mimplicit-it compiler flag not recognized

I am attempting to compile a C++ library for a Tegra TK1. The library links to TBB, which I pulled using the package manager. During compilation I got the following error
/tmp/cc4iLbKz.s: Assembler messages:
/tmp/cc4iLbKz.s:9541: Error: thumb conditional instruction should be in IT block -- `strexeq r2,r3,[r4]'
A bit of googling and this question led me to try adding -mimplicit-it=thumb to CMAKE_CXX_FLAGS, but the compiler doesn't recognize it.
I am compiling on the tegra with kernal 3.10.40-grinch-21.3.4, and using gcc 4.8.4 compiler (thats what comes back when I type c++ -v)
I'm not sure what the initial error message means, though I think it has something to do with the TBB linked library rather than the source I'm compiling. The problem with the fix is also mysterious. Can anyone shed some light on this?
-mimplicit-it is an option to the assembler, not to the compiler. Thus, in the absence of specific assembler flags in your makefile (which you probably don't have, given that you don't appear to be using a separate assembler step), you'll need to use the -Wa option to the compiler to pass it through, i.e. -Wa,-mimplicit-it=thumb.
The source of the issue is almost certainly some inline assembly - possibly from a static inline in a header file if you're really only linking pre-built libraries - which contains conditionally-executed instructions (I'm going to guess its something like a cmpxchg implementation). Since your toolchain could well be configured to compile to the Thumb instruction set - which requires a preceding it (If-Then) instruction to set up conditional instructions - by default, another alternative might be to just compile with -marm (and/or remove -mthumb if appropriate) and sidestep the issue by not using Thumb at all.
Adding compiler option:
-wa
should solve the problem.

How to make sure code (c++) written in Xcode can compile on other platforms?

I am a beginner was trying to do some C++ programming on Xcode. It works fine, but when I try to compile the same c++ file on my windows pc using VS, there were some errors. After I look at my code closely, there are really some stupid mistakes that I have made which caused the errors, but Xcode seemed to have ignored them...
My question is that is there any setting that I need to change to prevent Xcode from being so smart?
For example, the following code can actually compile in xcode:
#include <iostream>
using namespace std;
int main() {
if (true or false){
cout << "How is this possible? \n";
}
return 0;
}
There are also other cases where the code is actually wrong, but it can compile just fine is Xcode which is the annoying part and I want to disable that.
As far as I can see there is nothing wrong with your code.
The ISO C++ standard does not specify which standard headers are included by other standard headers. So, it is entirely possible that the version of iostream used by Xcode directly or indirectly includes ciso646. Whereas Visual Studio's version of iostream does not include ciso646. There are many similar cases with other headers. You just need to read the error messages and realize that your error (when you move your file to a different platform) is due to a missing header file.
It would be nice if writing portable code meant writing code in accordance with the C++ standard specification, but unfortunately that's not the case. Although there are various compiler options on various implementations which can help bring different implementations closer together, in general you will just have to bring the code into the target environment and actually test it there.
So ultimately writing portable code means you'll have to learn some subset of C++ that is accepted by all the implementations you want to target.
or is an 'alternative token' in C++, and VS is incorrect to reject it. There's no option in Xcode to disable support for alternative tokens. However VS has non-standard support for or as a macro using the header <ciso646>, and Xcode does have a header <ciso646> which does nothing (as the standard specifies). So you can write code which uses or and which works in both Xcode and VS by including this header.
#include <iostream>
#include <ciso646> // does nothing in Xcode, allows `or` in VS
using namespace std;
int main() {
if (true or false){
cout << "How is this possible? \n";
}
return 0;
}
Unfortunately VS can't support all of the alternative tokens through macros and so Xcode will still support some that VS doesn't.
There are also other cases where the code is actually wrong, but it can compile just fine is Xcode which is the annoying part and I want to disable that.
If you give specific examples then I can provide additional advice on how to write portable code.
Rather than changing your Xcode settings, I suggest cross-checking your code using another development environment.
If you're looking for something cheap and full-proof. Download a VirtualBox Windows VM, and run download Dev C++ (bloodhshed)
VS does not support or: you need to use || instead.
You can include some special files but it doesn't inject or sufficiently well into the language for it to work in all instances.
If you want to suppress use of or (and your compiler supports no better way)
#define it to something that emits a compiler error, for example
#define or OR
This at least means that the nature of the compilation errors will be identical on Xcode and VC.

ImageMagick pthread.h multiple definition

When trying to compile more recent versions of ImageMagick (v6.8.7-2 or later, v6.8.7-1 is fine), I get a bunch of:
CCLD magick/libMagickCore-6.Q16.la
magick/.libs/magick_libMagickCore_6_Q16_la-animate.o: In function `__pthread_cleanup_routine':
/usr/include/pthread.h:581: multiple definition of `__pthread_cleanup_routine'
magick/.libs/magick_libMagickCore_6_Q16_la-accelerate.o:/usr/include/pthread.h:581: first defined here
magick/.libs/magick_libMagickCore_6_Q16_la-annotate.o: In function `__pthread_cleanup_routine':
/usr/include/pthread.h:581: multiple definition of `__pthread_cleanup_routine'
magick/.libs/magick_libMagickCore_6_Q16_la-accelerate.o:/usr/include/pthread.h:581: first defined here
magick/.libs/magick_libMagickCore_6_Q16_la-artifact.o: In function `__pthread_cleanup_routine':
/usr/include/pthread.h:581: multiple definition of `__pthread_cleanup_routine'
magick/.libs/magick_libMagickCore_6_Q16_la-accelerate.o:/usr/include/pthread.h:581: first defined here
magick/.libs/magick_libMagickCore_6_Q16_la-attribute.o: In function `__pthread_cleanup_routine':
/usr/include/pthread.h:581: multiple definition of `__pthread_cleanup_routine'
magick/.libs/magick_libMagickCore_6_Q16_la-accelerate.o:/usr/include/pthread.h:581: first defined here
... goes on for quite a bit longer, all the same.
The pertinent area of /usr/include/pthread.h (from glibc-headers 2.5-118.el5_10.2) is:
/* Function called to call the cleanup handler. As an extern inline
function the compiler is free to decide inlining the change when
needed or fall back on the copy which must exist somewhere else. */
extern __inline void
__pthread_cleanup_routine (struct __pthread_cleanup_frame *__frame)
{
if (__frame->__do_it) // <======= this is :581
__frame->__cancel_routine (__frame->__cancel_arg);
}
I've been posting on ImageMagick's forum without response.
Even if you can't say exactly what's happening, how do I start figuring out whether the issue is with ImageMagick or pthread.h? Where do I go from there?
grep pthread_cleanup_routine -r * only shows matches against the binary object files -- none of ImageMagick's source code has pthread_cleanup_routine in it. A few of the sources include "pthread.h" of course.
That's leading me to believe that this is a glibc issue, not an ImageMagick issue... but, again, previous versions of ImageMagick compile just fine. (I have diff'ed the svn sources between versions where it broke. Lots of configuration/makefile changes, but nothing sticks out to me as to why it would cause this.)
I'm on CentOS 5, kernel 2.6.18-308.24.1.el5, gcc v4.9.0, ld v2.24, glibc-headers 2.5-118.el5_10.2
I've seen a lot of people posting similar issues with other packages than ImageMagick. Hopefully others will find this useful.
Changing pthread.h, just before __pthread_cleanup_routine :
extern __inline void
to
if __STDC__VERSION__ < 199901L
extern
#endif
__inline void
Fixes the issue. Older versions of glibc had an issue when -fexceptions was used, and inline non-C99 conformance (see http://gcc.gnu.org/ml/gcc-patches/2006-11/msg01030.html.) More recent glibc's would fix the issue too, but this should be a temp fix for those who don't want to / shouldn't upgrade it.
ImageMagick svn 13539 (which later became v6.8.7-2) began using -fexceptions.
I faced this error with a newer gcc compiler (4.9.3)
The ImageMagick(6.8.9_7) configure script was checking if compiler supports gnu99 standard. If yes, the configure script sets standard to gnu99 and also enables openmp.
Inline semantics change with C standard gnu99 causing multiple definition of the extern inline function
https://gcc.gnu.org/onlinedocs/gcc-4.9.3/gcc/Inline.html#Inline.
So, I added compiler flag -fgnu89-inline to use older semantics for inline and it fixed the issue.

gdb unable to set breakpoint

I am using g++ 4.1.2 and gdb 7.2
I am debugging code that uses Xerces, which I built using the same tools, though presumably without debugging.
GDB steps through my code just fine, but of course does NOT step through Xerces because it probably doesn't have debugging information, and definitely does not know where the source directory is. But all I want is to set a breakpoint when Xerces (a callback parser) calls a callback object.
Their base class is DefaultHandler
I have a class ContentHandlerBase : public DefaultHandler
Then leaf classes inherit from ContentHandlerBase. These leaf classes are inside namespace A, for example
in gdb I try to set a breakpoint.
b A::LeafContentHandler::LeafContentHandler
b A::LeafContentHandler::endElement
The first breakpoint works because the code is inline (defined in the header).
The second breakpoint does not work, meaning gdb claims that no such symbol exists, even though it obviously does. It is a virtual function defined in the Xerces library, if that makes a difference. Before I recompiled Xerces, it was built with g++3.4.6 and I could not find the symbol in gdb. Now, gdb finds the symbol (I can hit tab) but then it says it doesn't exist, should I wait for a library to load.
Can anyone tell me what I have to do to make it work? I'd prefer not to build all of xerces with debugging.
Note that in some cases, with the constructor in the .cpp file, it also worked for some reason, and then, because it was in the same file, I could set a subsequent breakpoint at linenumber, and that worked.
Try gdb 7.1 - it seems there are some problems in setting breakpoint by function name in gdb 7.2