After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 395447 - gnobots2 uses 100% CPU
gnobots2 uses 100% CPU
Status: RESOLVED FIXED
Product: gnome-games-superseded
Classification: Deprecated
Component: gnobots2
2.16.x
Other All
: Normal major
: ---
Assigned To: GNOME Games maintainers
GNOME Games maintainers
Depends on:
Blocks:
 
 
Reported: 2007-01-11 16:19 UTC by Simon Gustafsson
Modified: 2007-07-13 01:05 UTC
See Also:
GNOME target: ---
GNOME version: 2.15/2.16



Description Simon Gustafsson 2007-01-11 16:19:26 UTC
Please describe the problem:
gnubots uses 100% of the CPU untill killed/closed without achieving anything.
Guess that this happens when there are no safe teleporting destinations available,  and some routine randomly tries to reposition repeatedly without ever detecting that no options are available. Maybe a check for this condition should be added.

Steps to reproduce:
1. Play the game
2. When there are no safe teleporting locations, click on "Teleport"
3. 


Actual results:
gnubots2 uses 100% of the CPU, and nothing happens. (Desktop and other programs still responsive). Don't remember if I had to kill gnubots2, or if it was possible to close it normally.

Expected results:
1) Newer use 100% cpu indefinitely, when all positions tried and no safe found, bail out.
2) Current score should at least be saved to highscore if it belongs there (not the case currently)
3) EITHER a message ("There are no safe teleporting locations, you have run out of luck") OR possibility to retry that level

Does this happen every time?
Yes (when steps for reproduction followed, but that could take weeks)
No (during normal usage, has only occured once for me so far).

Other information:
Screenshot of playing field when it happend:
http://www.simong.se/short-term-storage/delete-june-2007/robots-hang-cpu100.png
Comment 1 Simon Gustafsson 2007-01-12 02:57:08 UTC
100% CPU usage happened again. I have to revise the "could take weeks" to reproduce into "problem occurs several times a week".

I can also add that it's not possible to quit the program at all, it has to be killed (either kill or "Force Quit" in the "program not responding" dialog).

This time I installed relevant debuginfo-packages, and attached gdb to the running gnobots2. Can attach a stack trace, core dump, and another screen shot if wanted, but the problem was clearest when stepping around with gdb, so I'll start there.

Playing in gdb shows that the code is stuck in an infinite loop at lines 1243-1266 in game.c (see excerpt at bottom). To get there, one has to pass the check at lines 1212-1225. That check is newer even executed when "super safe moves" isn't selected. But I had "super safe moves" enabled, so the check at lines 1212-1225 didn't detect that there are no safe moves, and one then gets stuck in the "while (1) {" beginning at line 1243. 

Proposed solutions:
(if problem still persists in newest version)
Alternative 1)
Write a working check at lines 1212-1225, and add an additional check when "super safe moves" isn't selected. This feels like a proper solution, but harder to verify.

Alternative 2)
in the source, change

1243      while (1) {
<SNIP>
1255          break;
<SNIP>
1266      }

into something more like this

1243a     int success=0;
1243b     do {
<SNIP>
1255a         success=1;
1255b         break;
<SNIP>
1266a     } while( (ixp!=xp) && (iyp!=yp) );
1266b     if( !success ){
1266c       message_box (_("You have run out of safe moves - the robots have won!"));
1266d       kill_player ();
1266e       return FALSE;
1266f     }

This would give up looking for safe teleport locations when all has been tried, and might be useful as an additional check even if the first solution is attempted (this is simple, catches this 100% cpu usage problem, as well as notifies the user and permits saving of the high score)

I don't have time to write a proper patch (something i'we newer done before) especially when there is a new version out there which I don't have time / motivation to debug as well, but if there still is no check preventing the infinite lock at all when "super safe moves" are disabled (see line 1212), this issue should be handled by somebody.

Excerpt from game.c for gnobots2 version 2.16.0
1197    /**
1198     * safe_teleport
1199     *
1200     * Description:
1201     * teleports the player to safe location
1202     *
1203     * Returns:
1204     * TRUE if player can be teleported, FALSE otherwise
1205     **/
1206    static gboolean
1207    safe_teleport (void)
1208    {
1209      gint xp, yp, ixp, iyp;
1210      gint i, j;
1211
1212      if (properties_super_safe_moves () && !safe_teleport_available ()) {
1213        /* FIXME: This code is untested - in normal play you have to get to 
1214         * about level 61. */
1215        if (!safe_move_available ()) {
1216          message_box (_("You have run out of safe moves - the robots have won!"));
1217          kill_player ();
1218          return FALSE;
1219        } else if (safe_teleports > 0) {
1220          message_box (_("There are no safe locations to teleport to!!"));
1221          return FALSE;
1222        } else {
1223          return random_teleport ();
1224        }
1225      }
1226
1227      if (safe_teleports <= 0)
1228        return random_teleport ();
1229
1230      for (i = 0; i < GAME_WIDTH; ++i) {
1231        for (j = 0; j < GAME_HEIGHT; ++j) {
1232          if (arena[i][j] != OBJECT_PLAYER) {
1233            temp_arena[i][j] = arena[i][j];
1234          } else {
1235            temp_arena[i][j] = OBJECT_NONE;
1236          }
1237        }
1238      }
1239
1240      ixp = xp = rand () % GAME_WIDTH;
1241      iyp = yp = rand () % GAME_HEIGHT;
1242
1243      while (1) {
1244
1245        if ((temp_arena[xp][yp] == OBJECT_NONE) && check_safe (xp, yp)) {
1246          player_xpos = xp;
1247          player_ypos = yp;
1248          temp_arena[player_xpos][player_ypos] = OBJECT_PLAYER;
1249
1250          reset_player_animation ();
1251
1252          safe_teleports -= 1;
1253
1254          update_arena ();
1255          break;
1256        }
1257
1258        ++xp;
1259        if (xp >= GAME_WIDTH) {
1260          xp = 0;
1261          ++yp;
1262          if (yp >= GAME_HEIGHT) {
1263            yp = 0;
1264          }
1265        }
1266      }
1267      
1268      remove_splat_bubble ();
1269      play_sound (SOUND_TELEPORT);
1270
1271      return TRUE;
1272    }

BTW Ctrl-w to cut lines in xemacs don't blend well with mozilla - had to rewrite most of this when I accidentally closed the browser-tab.
Comment 2 Simon Gustafsson 2007-01-12 10:35:20 UTC
Took a quick look at the latest CVS version, and it seems like the check at lines 1212-1225 (se comment above) might be working in the newest version because of changes to resolve bug #353303 (havn't confirmed that thou).

BUT the check at lines 1212-1225 (in both the 2.16.0 version and current CVS version) to avoid the infinite loop is still bypassed if "super safe moves" isn't selected, so the application would still stuck at 100% cpu usage if one would manage to play long enough with "super safe moves" disabled.
Comment 3 Thomas Andersen 2007-07-13 01:05:26 UTC
This was fixed in bug #438829 by simply killing the player if no safe teleport locations are available.