ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I am developping an application for my master's degree (not in computer science/engineering, don't worry :P) and have a problem debugging a segmentation fault that happens only every once in a while (maybe after every 10 mins of use).
I have run the program in debug mode and my problem is that the I can read all variables on the line GDB reports the app to have stopped on.
I'm quite surprised since I can read all variables. I also have disabled optimizations (-O0).
The assembler directive being executed is
Code:
(gdb) x/i $pc
0x817fa7e <_ZN8Signal1DIfE4plotERN5Cairo6RefPtrINS1_7ContextEEEN3Gdk9RectangleE10ZoomStructR13_GdkRectangle+1930>: flds (%eax)
(gdb) p *(float*)$eax
Cannot access memory at address 0xaf85fff0
So the memory pointed by eax is not accessible. However, I don't understand what it's trying to do since I can read all variables that should be needed.
I'm not comfortable with x86 asm and can't really draw any conclusions about what's wrong. If anybody could help me pinpoint the problem I'd be really happy.
Also, is it possible to find what eax points to (in terms of variable), or to have some kind of memory map that would help me figure out what library/program is located in that area of the memory? I'm not yet very used to GDB
nobody is...
By the way, I think you'd better use valgrind-memcheck to this kind of problem, it will check for invalid memory use, certainly that i+j get out of f_values bounds.
And, as valgrind-memcheck has many options to set, try alleyoop, a nice gui for it really straightforward to use.
Quote:
(1.0/0.0)
I think it's really dangerous since not sure how different compiler will handle this, you can use "Inf", but can't remember if you have to get it through a function. But even that is not really a good idea, I think you can have portability issue, so take a look into float.h (or maybe limits.h?) for something like DOUBLE_MAX which is the maximum value that can be represented by a double.
I'm pretty sure these seven instructions just compute the value of the pointer f_values and store it in edx. I don't see the source for f_values, so I can't guess why that is so complicated.
But you determined that is an invalid address. It would be nice to know whether it is invalid because of an error in j (-0xe(%ebp)) or in i (-0x1c(%ebp)) or in f_values which is in edx at the point of failure.
So on the next failure, I would look at all of those things:
eax
edx
-0xe(%ebp)
-0x1c(%ebp)
i
j
f_values
Quote:
Originally Posted by dax2112rush
I can read all variables on the line GDB reports the app to have stopped on.
Never trust the values of variables reported by any debugger. If they happen to be correct, it is convenient that the debugger can display them. But when the debugger is confused, it really helps to be able to look at the register which the code just put the variable into and see what what the value really is.
Quote:
Originally Posted by jf.argentino
nobody is...
Nonsense. When I'm confused by what some C++ code really means, I look at the generated asm code. It is usually very understandable.
I think it is some kind of inheritance bug. Is f_values a member variable of a multiply inherited base class of the current class, or something like that?
The above two instructions put a pointer to an object into both eax and edx.
Code:
817fa64: 8b 00 mov (%eax),%eax
Next we get a pointer to the vtable of the object.
Code:
817fa66: 83 e8 3c sub $0x3c,%eax
Then compute a negative offset from the start of the vtable ???
I don't use bad constructs such as multiple inheritance of virtual classes enough to remember exactly which bad construct gives code like that.
Code:
817fa69: 8b 00 mov (%eax),%eax
Then we get the offset of some related class stored there (the class that f_values is a member of).
Code:
817fa6b: 8d 04 02 lea (%edx,%eax,1),%eax
Then we compute the address of the subobject of that class.
Code:
817fa6e: 8b 50 04 mov 0x4(%eax),%edx
Finally get the wrong value of f_values from that subobject.
Maybe the object simply has a wrong f_values in it, but more likely we navigated incorrectly, because the object relationship at run time wasn't the same as the object relationship at compile time (as would happen if the caller had done a static_cast to the wrong related class and the current object isn't the type it is supposed to be).
You are right, f_value is an inherited member variable. The class structure looks like that:
Code:
template <class T>
class Signal1D : public virtual SignalBase, public virtual SignalData<T>
{
public:
using SignalData<T>::f_values;
...
}
class SignalBase: public virtual PlottableAndViewable, public virtual SignalDataBase ...
class SignalDataBase ...
template <class T>
class SignalData: public virtual SignalDataBase {
public:
...
T* f_values;
};
Agreed, this is a very ugly class structure, it's my first real C++ project and I have made quite a few mistakes I would not do again. I was basically trying to achieve what I was seeing in Java where objects would implement a few interfaces and the receiver would cast to these interfaces, ie. I wanted to have vectors of "signals" or of "plottable" objects without restricting myself to one specific implementation. I know there are probably better ways to do that and I'll probably read a book on design patterns before starting my next project, but for this one, I am stuck with my errors since too much code depends on that.
Unfortunately, with my home PC (x86_64 vs x86 at research lab), I am unable to reproduce the segmentation fault. Monday, I will further investigate based on the input you guys gave me and let you know if I was able to fix it!
As for Valgrind, I use it quite often, but since the slowdown is really huge and my bug isn't happening very often, I did not manage to trigger it with valgrind monitoring it. It could be useful though.
And FYI divisions by 0 are to generate +inf and -inf. Since I had a templated type, I thought it would be the best way to do it, but I'll have a look at DOUBLE_MAX (or any other constant in std headers) since I guess DOUBLE_MAX will cast to the maximum value of integer types as well.
BTW, is there any good resource (tutorial, book, etc..) that you guys recommend to be able to learn about how those C++ constructs get translated to asm? It would be a great skill I'd like to have.
Thanks for all your replies, I'll give you feedback on Monday!
Ric
Last edited by dax2112rush; 04-18-2009 at 12:37 PM.
edx wasn't equal to f_values. I found out f_value had been modified after f_values's value was transfered to edx. I had forgotten I had a method that could grow f_values (realloc the array) and this was happenning during the call to the function it was crashing in (in 2 separate threads). A simple mutex solved the issue.
Thanks a lot!
At least I learned why values reported by GDB can't be trusted!
Ric
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.