Skip to main content
Topic: [r2972] Crash when building tunnel entrance (Read 3181 times) previous topic - next topic

[r2972] Crash when building tunnel entrance

When attempting to build an entrance for a tunnel with ctrl+click, I get the following crash:

Program received signal SIGSEGV, Segmentation fault.
tunnelbauer_t::baue (welt=0xaad6e0, sp=0xaae4f0, pos=<value optimized out>,
    besch=0x1040e90) at bauer/tunnelbauer.cc:269
269         if(welt->lookup(end)  ||  welt->lookup_kartenboden(pos+zv)->get_hoehe()<=end.z) {


The triggering factor seems to be the road I had already prepared where I later was going to build the tunnel exit one level lower. See attached screenshot for how to reproduce.

64-bit Linux, SDL, pak64 r244. Using modified simgraph16.cc, but I do not think that should affect this.



Since posting this, I have noticed other possibly related problems with tunnels. I tried to build a straight tunnel by just using the tunnel tool normally (without holding down ctrl), but it failed when I tried building it from south to north. It did not crash, but told me that no tunnel could be built there. When I clicked on the northern end, the tunnel was built as it should. The southern end did have an artificial slope.

Futhermore, when trying to reproduce this bug, the game crashed when I tried to remove the second tunnel built in the same place. I could reproduce this by building a tunnel, removing it, rebuilding it and then attempting to remove it again. bauer/tunnelbauer.cc line 541.

Re: [r2972] Crash when building tunnel entrance

Reply #1
I could not reproduce any of these problems :(

It should not be possible to build tunnels that end on a vertical slope. Otherwise it would be a bug.
Parsley, sage, rosemary, and maggikraut.

Re: [r2972] Crash when building tunnel entrance

Reply #2
Have you tried it on a hill with exactly the same form as the one in the image I posted? It is very sensitive to terrain. It does not crash if I leave out the extra raised land on the northern side.

As for the second bug, I did not mean a vertical wall, but a slope. I have attached screenshots showing how to reproduce that one.

Re: [r2972] Crash when building tunnel entrance

Reply #3
I cannot reproduce either of the problems with exactly the same landscape.

Re: [r2972] Crash when building tunnel entrance

Reply #4
So it's one of those bugs...

I cranked up the debug level for tunnelbauer.cc from 1 to 2, so that it would be easier to debug. That drastically reduced my ability to reproduce the crash, but I am still able to trigger it by trying again and again until I succeed. According to gdb, the immediate cause of the crash is wrong data in zv. In the debugging session I have open now, it contains x = 3176 and y = 348, which obviously is bad for a 1024x1024 map. These values were fetched, already corrupted, from koord::from_hang[12]. They differ from crash to crash. Something seems to be writing where it should not, but what and why only to koord::from_hang[12]? I'll try to dig deeper.



According to gdb, freelist_t::putback_node is the culprit. For some reason list ends up pointing to koord::from_hang[12]. Comparing putback_node with gimme_node, I noticed the following difference that I think is to blame:

gimme_node:
Code: [Select]
size = max( min_size, size );
size = (size+3)>>2;
size <<= 2;

// hold return value
nodelist_node_t *tmp;
if(size>MAX_LIST_INDEX) {
switch(size) {

putback_node:
Code: [Select]
size = max( min_size, size );
size = ((size+3)>>2);

if(size>MAX_LIST_INDEX) {
switch(size) {

In gimme_node, size is shifted right then left, while in putback_node, it is just shifted right. But both compare it against the same constants afterwards. As far as I can tell, gimme_node does it right, while putback_node ends up going beyond the end of the all_lists array.

 

Re: [r2972] Crash when building tunnel entrance

Reply #5
That is indeed wrong. Check in next revision back.

Re: [r2972] Crash when building tunnel entrance

Reply #6
Hi Prissi,


In putback_node(),
Quote
   // all sizes should be dividable by 4
   size = max( min_size, size );
   size = ((size+3)>>2);
   size <<= 2;

   if(size>MAX_LIST_INDEX) {
      switch(size) {
         case message_node_size:
            list = &message_nodes;
            break;
         default:
            free( p );
            return;
      }
   }
   else {
      list = &(all_lists[size]);
   }
the expression in green should be "size>>2" after you have added back the left shift statement in blue.

BTW, Line 88 in gimme_node() may be changed from "size/4" to "size>>2" for consistency :
Quote
      list = &(all_lists[size/4]);


Knightly

Re: [r2972] Crash when building tunnel entrance

Reply #7
After checking out revision 2982 and fixing the lingering part of the bug mentioned by Knightly, it appears that all three problems I mentioned, are gone. I never got around to debugging the second one, since the third problem came in my way, so I ****ume the same underlying problem was to blame.