CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 15 of 21

Hybrid View

  1. #1
    Join Date
    Sep 2011
    Posts
    13

    Exclamation Segmentation Fault ??

    Hi, i have a very weird fatal exception happening very rarely on my application (compiled under gcc - Ubuntu linux)

    it seems that this this function :

    Code:
    bool GetConnect( ) {return m_Connected;}
    causes a Segmentation Fault sometimes (not all the times)

    No the instance of the class is not deleted when i call that function.
    I tried declaring m_Connected as volatile bool m_Connected but still the error happens.
    several different threads also access the function that calls this function.

    Code:
    bool CPDC :: CBoolExpr(Clients *client)
    {
    	if(!client)
    	{
    		return false;
    	}
    	
    	if(client->m_Deleting) // before we delete our instance of Clients* we set this flag. the instance is deleted 240 seconds later.
    	{
    		
    		return false;
    	}
    	
    	if( !client->m_Socket )
    	{
    	    return false;
    	}
    	
    	cout << "CBE4" << endl;
    	if( !client->m_Socket->GetConnected() )
    	{
    		return false;
    	}
    
    	cout << "CBE5" << endl;
    	if(client->m_Socket->HasError() )
    	{
    		return false;
    	}
    
    	cout << "CBEE" << endl;
    	return true;
    }
    it always crashes when it outputs CBE4.
    to make sure that another thread doesnt crash the application i also tried creating the other threads in completely different timings. It crashes every time on the same line. Although it makes no sense at all..

    Did i miss anything?

  2. #2
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Segmentation Fault ??

    Quote Originally Posted by JacobNax View Post
    Hi, i have a very weird fatal exception happening very rarely on my application (compiled under gcc - Ubuntu linux)

    it seems that this this function :

    Code:
    bool GetConnect( ) {return m_Connected;}
    causes a Segmentation Fault sometimes (not all the times)
    There is nothing weird about these errors. When you corrupt memory, use pointers incorrectly, or other errors that cause memory corruption, then the behaviour of the application is undefined. It could work all the time, fail sometimes, work on one machine and fail on another. So nothing is "weird".
    No the instance of the class is not deleted when i call that function.
    Great, but how are we, persons who know nothing about the rest of your code, the state of your program at the time of the crash, what really happened before the problem occurred, can confirm this? Too many times, we get persons taking oaths that they are doing this or that, and when it comes time to actually see their code in action, they are not doing what they say they are doing.
    I tried declaring m_Connected as volatile bool m_Connected but still the error happens.
    several different threads also access the function that calls this function.
    So are you or do you use proper synchronization in this multithreaded program? The usage of "volatile" is not a substitute for proper thread synchronization (mutexes, semaphores, etc.).
    to make sure that another thread doesnt crash the application i also tried creating the other threads in completely different timings. It crashes every time on the same line.
    First, does your program run correctly using one thread? If not, then you need to correct that first.

    After that, use proper synchronization objects in your code. Trying to outguess when to create a thread by using "different timings" (whatever that is), or using "volatile" as a poor man's synchronization object isn't going to get the job done.
    Although it makes no sense at all
    If this indeed a threading problem, and you are not familiar with what parts of the code are not thread safe, then anything can happen that may not seem to make sense. Racing conditions, re-entrancy issues, etc. are all of the things that a programmer must be aware of when writing or maintaining multithreaded applications, and little to no experience in these issues will make a seemingly OK looking multithreaded program into one that will fail.

    Regards,

    Paul McKenzie

  3. #3
    Join Date
    Sep 2011
    Posts
    13

    Re: Segmentation Fault ??

    I use multiple threads for mysql operations such as inserting rows, updating rows, deleting rows etc.

    i am aware of synchronization methods such as mutexes. i use boost::thread mutexes.
    but i'm keeping my code clean of object sharing because mutexes with mysql can lead to really bad performance (tested before)

    so instead i just use volatile booleans to check the state of something which worked just fine in most of my applications.


    again i'm not some expert in c++ , i taught myself over the past 2 years and it's my first programming language, but i have experimented a long time with this stuff and i never state anything if i haven't experienced it firsthand.
    the application fails at some point when i compile it in gcc (linux) but works just fine with the VC compiler on windows (based on a 24 hour runtime) so debugging all this has become a real pain in the arse as i have to wait at least 24 hours for it to ''crash'' with that segmentation fault.

    i will try to make the function non-virtual and run it again tonight for another 24 hours...
    just wondered if anyone experienced the same annoying problem.

  4. #4
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Segmentation Fault ??

    Quote Originally Posted by JacobNax View Post
    the application fails at some point when i compile it in gcc (linux) but works just fine with the VC compiler on windows (based on a 24 hour runtime) so debugging all this has become a real pain in the arse as i have to wait at least 24 hours for it to ''crash'' with that segmentation fault.
    That is the issue with multithreaded programs. If you have a threading issue, you may never have it come up when you compile with one compiler as opposed to another. You can't even predict if you change compiler settings in Visual C++, the error won't shows up. As a matter of fact, even if it isn't a threading issue, you shouldn't be fooled into thinking your program is OK if it runs on a compiler but fails to run with another compiler. That other compiler where it is not working is giving you the red flag that your program has a bug and you need to fix it.

    And as I stated earlier, any corruption bugs leads to undefined behaviour. This means the application may seem to work, but as soon as you change compiler options, or add/remove code, or use another version or brand of compiler, or you run the program on a different machine, all sorts of "weird" bugs could crop up at runtime (I put "weird" in quotes, since as I stated, there are no weird bugs in C++, unless the compiler itself is producing broken code, and the possibility of that happening is fairly remote).
    just wondered if anyone experienced the same annoying problem.
    Yes, it's called "debugging multithreaded programs". Again, any issue with threading will occur at random times, times that you cannot predict. Every programmer who has worked with multithreaded programs has encountered this issue.
    I use multiple threads for mysql operations such as inserting rows, updating rows, deleting rows etc. i am aware of synchronization methods such as mutexes. i use boost::thread mutexes.
    but i'm keeping my code clean of object sharing because mutexes with mysql can lead to really bad performance (tested before)
    You never mentioned anything about racing conditions, reentrancy, etc. Just because you used synchronization objects doesn't mean you used them correctly.

    Proper usage of synchronization objects, and the usage of the correct synchronization objects is not a trivial topic. When you write the code, you have to identify before even running the program where the potential problems may exist.

    Just to let you know, in the industry, if a company uses multithreading heavily, they will not hire a programmer if they have little to no experience in multithreaded applications, regardless of how much C++ they've done, 2 years or 20 years. A 24-hour wait time before a crash is generated would be considered unacceptable -- you need to identify in the code all of the issues that could occur, and then write the proper code to overcome these issues. If you missed anything, then you go through the code again and attempt to see what parts of the code are using the corrupted variable(s) and identify what could cause the corruption.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; September 24th, 2011 at 04:38 PM.

  5. #5
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Segmentation Fault ??

    Quote Originally Posted by JacobNax View Post
    so instead i just use volatile booleans to check the state of something which worked just fine in most of my applications.
    But now it doesn't work. You get what you pay for -- the usage of volatile is IMO a poor substitute for real multithreaded synchronization.

    Just this line alone is suspect:
    Code:
    if(client->m_Deleting) // before we delete our instance of Clients* we set this flag. the instance is deleted 240 seconds later.
    Reading that comment, it seems you're relying on specific timings to do certain things. That is not the way to write a multithreaded program. What is 240 seconds on one machine may be 2 seconds on another.

    You cannot predict anything in terms of timing -- you have to write code that works, regardless if it's 240 seconds or 0.2 seconds later (or before). That requires you to look at your code, and determine if there is any potential for a racing condition or re-entrancy issues.

    Regards,

    Paul McKenzie

  6. #6
    Join Date
    Sep 2011
    Posts
    13

    Re: Segmentation Fault ??

    Like you can see in the function, the instance of that class is never ever used/referred/dereferred if the flag DeleteMe is set because every time we wanna see or change data or anything on that instance we call the CBoolExpr( ) function that checks the flag.

    2 seconds / 240 seconds / 1200 seconds it doesnt matter. It's just a precaution method of dereferrencing memory in 1 thread out of the multiple and safely.
    i already solved the problem by making the function non-virtual and volatile.

    thanks for the feedback however, it helped me solve some other problems i had.
    knowledge once again is infinite, we keep on learning. best regards.

  7. #7
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: Segmentation Fault ??

    Quote Originally Posted by JacobNax View Post
    Like you can see in the function, the instance of that class is never ever used/referred/dereferred if the flag DeleteMe is set because every time we wanna see or change data or anything on that instance we call the CBoolExpr( ) function that checks the flag.
    And what happens if that function is called after the object has been deleted? What do you think the value of m_Deleting will be?

    Regardless of when you actually call delete, at the moment you decide that an object should be destroyed, you should consider the object to be invalid. That means no part of your code should access that object. You cannot check this inside the object, because it is invalid. At best, you could use the m_Deleting flag as a debugging tool, i.e. you assert that it is false. However, the only way to assure that assertion would work properly is to prevent any CPDC from being deleted (for debugging purposes only).
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  8. #8
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Segmentation Fault ??

    Quote Originally Posted by JacobNax View Post
    Like you can see in the function, the instance of that class is never ever used/referred/dereferred if the flag DeleteMe is set because every time we wanna see or change data or anything on that instance we call the CBoolExpr( ) function that checks the flag.
    So is JohnE and D_Drmmr correct in that you're deleting the instance, and then checking a member of this deleted instance for a value? If that's the case, then that is undefined behaviour.

    When you delete an instance of an object, you cannot use that object any longer.
    Code:
    #include <iostream>
    
    class foo
    {
        public:
              bool m_bDeleting;
    };
    
    int main()
    {
        foo *pFoo = new foo;
        pFoo->m_bDeleting = true;
        delete pFoo;
        std::cout << pFoo->m_bDeleting;  // behaviour is undefined
    }
    That last line of code, where the m_bDeleting flag is being checked, has undefined behaviour. You cannot point to a deleted object and assume you can use its remains for anything.

    Regards,

    Paul McKenzie

  9. #9
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: Segmentation Fault ??

    Quote Originally Posted by JacobNax View Post
    the application fails at some point when i compile it in gcc (linux) but works just fine with the VC compiler
    That's quite interesting. If anything I'd expect it to be the other way around. I use VC++ as well as gcc and one thing I've noticed about VC++ is that it will almost never allow you to access memory you've deleted. This is especially true for Debug builds. gcc unfortunately is a different kettle of fish. In my experience, it seems perfectly happy to let you to carry on using deleted pointers until the memory gets re-used for something else - at which point you get a sudden and apparently inexplicable crash.

    As Paul described, corrupted pointers give you exactly this kind of problem. Your app works perfectly most of the time but crashes at random for no obvious reason. Or the app works fine on your machine but not on somebody else's.

    If you're confident that this isn't a synchronisation issue, the other most likely cause is that Clients.m_socket is getting overwritten by garbage. Is there a buffer in front of it that's too small? Maybe the buffer is 10 bytes but somewhere, you're writing 11 bytes of data into it. Because of structure packing, this is the kind of problem that might show up in one compiler but not the other.

    Try building the gcc version with the --mms-bitfields flag. This forces your gcc app to use the same structure packing as VC++. It's not a fix but if that causes the problem to go away, it might indicate a data member getting overwritten somehow.

    Of course if you had access to a decent debugger you could track this problem down in a few minutes. Sadly, you're stuck with gdb.
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  10. #10
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Segmentation Fault ??

    I have not taken a really good look at your code, but just a warning: the CSocket destructor should be declared virtual. Declaring the destructor of its derived class as virtual is not enough.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  11. #11
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: Segmentation Fault ??

    One other thing.... how does your program know that the object will need to be deleted in precisely 4 minutes' time? Generally speaking, you delete an object when you no longer need it and you don't normally know this, four minutes in advance.

    The 4 minute delay suggests to me that some other process is somehow still using the object and you're just making a guess about how long it might need it for.

    Or to put it another way, try re-instating the virtual function from yesterday but increase 240 to 360. My guess is that this will also make the problem magically go away. So will a lot of other arbitrary changes. You need to look for the kind of thing that Laserlight suggested. It'll end up being something like that or a pointer corruption problem.

    It's a great shame that you can't reproduce the problem in VC++ because it's much better for debugging this kind of problem than gdb.
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  12. #12
    Join Date
    Sep 2011
    Posts
    13

    Re: Segmentation Fault ??

    thanks Paul
    your version looks neat and well written
    i haven't studied much the algorithms, just how the sort() and shuffling works.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured