1

I have the following stack trace on a core:

#1 0x..... in raise()
#2 0x..... in abort()
#3 0x..... in xehInterpretSavedSigaction()
#4 0x..... in xehExceptionHandler()
#5 <signal handler called>
#6 0x..... in QMap<int, myClass#1>::freeData(QMapData*) ()
#7 0x..... in myClass#2::myClass#2Method()
#8 0x..... so on and so forth

The code that uses the QMap looks like this:

     foreach (myClass::sturct1 conn, myClass3->getMap())
     {
         if (conn == x)
         {
             return conn;
         }
     }

The foreach line is where the QMap is retrieved with the getter method. Anyone know what QMap::freeData() does? The only references I can find anywhere on the internet are the actual QMap.h source. It looks like the method is used in the QMap destructor. The method name leads me to believe it is freeing up data. Anyway, I think if I knew more about freeData() I might be able to figure out and fix this core.

demonplus
  • 5,613
  • 12
  • 49
  • 68
Qman
  • 131
  • 1
  • 1
  • 8

1 Answers1

0

You don't need to know anything about freeData. The contents of the map field within myClass3 are corrupt, and getMap() shallow-copies a map instance that has been damaged. freeData works fine as long as the object it works with has not been damaged by errant code.

Since you're trying to access data from multiple threads, you must either:

  1. Operate from a separate instance of the shared data structure in each thread. The key point is: you have to create a copy in the thread that "owns" the source. You can then pass the copy to another thread and use it there. See this answer for example code.

  2. Protect the access to the data structure with a mutex.

Community
  • 1
  • 1
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • OK so I think I get it. Is the idea here to access the Map at the end of (or beginning and end of) every method and that way I'll end up with a different stack trace which will help me to hone in on where the corruption took place? What good is the .detatch()? – Qman Sep 25 '14 at 21:41
  • apparently we've been solving this issue over the past year in a number of places. As I understand it, the Map contains a c structure that doesn't have a clearly defined destructor and somehow the shallow copy of this thing is the issue. We keep fixing this issue in one of two ways. We make a local (deep) copy of the map and iterate over it. That's one way. The other is to change the foreach loop to iterate over the map.keys(), thus never making a shallow copy of the map itself. Ever heard of such a thing? – Qman Oct 03 '14 at 16:54
  • Sure about that? It's a struct defined inside of a C++ class. The sturct has 2 ints, 5 Strings, and a bool. That's it. – Qman Oct 06 '14 at 17:05
  • Sorry, 7 strings. But ya, 2 ints, 7 strings, and a bool. The struct is declared inside of the class that contains the map that we do a getMap() on and the struct is the value part of the map. The key is an int. We (not me yet since I'm trying to understand it) theorize that the destruction of the struct isn't clearly defined (or something along those lines) combined with the shallow copy cause the problem. Apparently doing one of those two things makes the core vanish. – Qman Oct 07 '14 at 18:28
  • Strings are QStrings. – Qman Oct 07 '14 at 23:58
  • I mistyped the code above. We do not return conn. We do a returnConn = conn; and then follow that with a break; and then return returnConn. The explanation I read from the developer who fixed it says that the shallow copied map is destroyed before it's data can be destroyed. This makes no sense to me because the returnConn variable is declared in the method with the first line of code. – Qman Oct 08 '14 at 00:05
  • OK so it turns out that one of the fixes doesn't work. The making of a local copy of the Map and then iterating through it doesn't fix it. – Qman Oct 14 '14 at 17:25
  • Kuba Ober, thanks for your comments. We have tried differing methods to fix this issue and none seem to work. We went from a foreach on the map to an iterator on the map to a foreach on the map keys. Same problem. One thing that I do know for sure is that the original map is being modified as the shallow copy of it is being used. Why would this cause the core? – Qman Dec 11 '14 at 17:03
  • yes and we're wondering if that is a player. What happens now is that we do a foreach(int i, getMap.keys()) and iterate through that. We iterate through the map looking for a value and we return that value. What I have seen in logging is that the map is taking on updates when we do the getMap() and I believe the updates are happening in another thread. – Qman Dec 12 '14 at 00:13
  • @Qman Aside: You really should have mentioned it on top of the post. I now know exactly what you're doing wrong. – Kuba hasn't forgotten Monica Dec 12 '14 at 14:24
  • Sorry Kuba, I didn't know this in my initial posting. This was all new to me at the time. It wasn't til I started logging two days ago that I figured it out. I did not write the code but I've been given the task to fix it this time. Until now, it was not my assignment to fix but I was trying to understand and help out. What is being done wrong? – Qman Dec 12 '14 at 17:57