Inheritance: ISerializable
Example #1
0
        private void handleRestartsAndBlacklist(OrganismWrapper currentAnimal, bool blacklist)
        {
            if (DetectDeadlock && blacklist)
            {
                Debug.WriteLine(string.Format("Permanently blacklisting: {0}",
                                              ((Species)currentAnimal.Organism.State.Species).AssemblyInfo.FullName));

                // Mark the animal in a magic file on disk so when we restart we will blacklist them.  We can't do it now
                // because the assembly is locked.
                _currentEngine.Pac.LastRun = ((Species)currentAnimal.Organism.State.Species).AssemblyInfo.FullName;

                throw new MaliciousOrganismException();
            }
        }
Example #2
0
        private void RunAnimalWithDeadlockDetection(OrganismWrapper currentAnimal)
        {
            Int64 kernelStart;
            Int64 userStart;
            var tries = 0;
            var blacklist = false;
            var shutdownWithoutBlacklist = false;

            // Hand the activationThread an animal and kick off processing
            _bug = currentAnimal;
            var validTime = getAnimalThreadTime(out kernelStart, out userStart);
            _animalDone.Reset();
            _animalReady.Set();

            // Now we spin in a loop and periodically check to see if the animal returned the thread to us.
            while (true)
            {
                // If the animal returns, _animalDone will get set on the activation thread and we'll continue.
                // if not, this will timeout.
                var executionDone = _animalDone.WaitOne(AnimalDeadlockCheckMSec, false);

                if (!executionDone)
                {
                    Trace.WriteLine(string.Format("Animal thread not stopped after {0} mSec, checking kernel time.",
                                                  AnimalDeadlockCheckMSec));

                    if (DetectDeadlock)
                    {
                        // If we were unable to retreive the time from getAnimalThreadTime() above, just wait
                        // for the full number of tries
                        if (validTime)
                        {
                            // Only permanently blacklist the animal if we are first trying to threadabort them
                            // (PenalizeForTime == true) Otherwise, animals that really won't hang the machine will
                            // get permanently blacklisted even though they could have been stopped with a threadabort.
                            // PenalizeForTime is only false when the tracewindow is up since it affects animal timings
                            if (PenalizeForTime)
                            {
                                Int64 kernelStop;
                                Int64 userStop;
                                validTime = getAnimalThreadTime(out kernelStop, out userStop);
                                if (validTime)
                                {
                                    var totalTime = (kernelStop - kernelStart) + (userStop - userStart);

                                    // Give the animal a bunch of time since lots of things can happen on their thread
                                    // that is actually reflected as time their thread actually got in the kernel like
                                    // GCs, Jitting, etc.
                                    if (totalTime > AnimalDeadlock100NSec)
                                    {
                                        Trace.WriteLine(string.Format(
                                                            "Thread overtime: {0} seconds, Blacklist and exit",
                                                            ((totalTime)/(double) 10000000)));
                                        blacklist = true;
                                        break;
                                    }
                                }
                                else
                                {
                                    Debug.WriteLine("Invalid Time From GetThreadTimes()");
                                }
                            }
                            else
                            {
                                Debug.WriteLine("Not penalizing for time -- don't permanently blacklist.");
                            }
                        }
                        else
                        {
                            Debug.WriteLine("Invalid Time From GetThreadTimes()");
                        }

                        tries++;

                        if (tries >= AnimalDeadlockRetries)
                        {
                            // If we've tried this many times and got to this point, either the animal never got
                            // a lot of actual kernel time, or we're not penalizing for time (the user has the debugger attached,
                            // or trace window open, for example). Don't blacklist them, but go ahead and restart the game
                            Trace.WriteLine(
                                string.Format(
                                    "Tried accessing animal thread {0} times, but not blacklisted yet -- restart.",
                                    tries));
                            shutdownWithoutBlacklist = true;
                            break;
                        }
                    }
                    else
                    {
                        Debug.WriteLine("Deadlock detection off");
                    }
                }
                else
                {
                    break;
                }
            }

            handleRestartsAndBlacklist(currentAnimal, blacklist);
            handleRestartWithoutBlacklist(blacklist, shutdownWithoutBlacklist);
        }
Example #3
0
        private void handleRestartsAndBlacklist(OrganismWrapper currentAnimal, bool blacklist)
        {
            if (DetectDeadlock && blacklist)
            {
                Debug.WriteLine(string.Format("Permanently blacklisting: {0}",
                                              ((Species) currentAnimal.Organism.State.Species).AssemblyInfo.FullName));

                // Mark the animal in a magic file on disk so when we restart we will blacklist them.  We can't do it now
                // because the assembly is locked.
                _currentEngine.Pac.LastRun = ((Species) currentAnimal.Organism.State.Species).AssemblyInfo.FullName;

                throw new MaliciousOrganismException();
            }
        }
Example #4
0
        private void RunAnimalWithDeadlockDetection(OrganismWrapper currentAnimal)
        {
            Int64 kernelStart;
            Int64 userStart;
            var   tries     = 0;
            var   blacklist = false;
            var   shutdownWithoutBlacklist = false;

            // Hand the activationThread an animal and kick off processing
            _bug = currentAnimal;
            var validTime = getAnimalThreadTime(out kernelStart, out userStart);

            _animalDone.Reset();
            _animalReady.Set();

            // Now we spin in a loop and periodically check to see if the animal returned the thread to us.
            while (true)
            {
                // If the animal returns, _animalDone will get set on the activation thread and we'll continue.
                // if not, this will timeout.
                var executionDone = _animalDone.WaitOne(AnimalDeadlockCheckMSec, false);

                if (!executionDone)
                {
                    Trace.WriteLine(string.Format("Animal thread not stopped after {0} mSec, checking kernel time.",
                                                  AnimalDeadlockCheckMSec));

                    if (DetectDeadlock)
                    {
                        // If we were unable to retreive the time from getAnimalThreadTime() above, just wait
                        // for the full number of tries
                        if (validTime)
                        {
                            // Only permanently blacklist the animal if we are first trying to threadabort them
                            // (PenalizeForTime == true) Otherwise, animals that really won't hang the machine will
                            // get permanently blacklisted even though they could have been stopped with a threadabort.
                            // PenalizeForTime is only false when the tracewindow is up since it affects animal timings
                            if (PenalizeForTime)
                            {
                                Int64 kernelStop;
                                Int64 userStop;
                                validTime = getAnimalThreadTime(out kernelStop, out userStop);
                                if (validTime)
                                {
                                    var totalTime = (kernelStop - kernelStart) + (userStop - userStart);

                                    // Give the animal a bunch of time since lots of things can happen on their thread
                                    // that is actually reflected as time their thread actually got in the kernel like
                                    // GCs, Jitting, etc.
                                    if (totalTime > AnimalDeadlock100NSec)
                                    {
                                        Trace.WriteLine(string.Format(
                                                            "Thread overtime: {0} seconds, Blacklist and exit",
                                                            ((totalTime) / (double)10000000)));
                                        blacklist = true;
                                        break;
                                    }
                                }
                                else
                                {
                                    Debug.WriteLine("Invalid Time From GetThreadTimes()");
                                }
                            }
                            else
                            {
                                Debug.WriteLine("Not penalizing for time -- don't permanently blacklist.");
                            }
                        }
                        else
                        {
                            Debug.WriteLine("Invalid Time From GetThreadTimes()");
                        }

                        tries++;

                        if (tries >= AnimalDeadlockRetries)
                        {
                            // If we've tried this many times and got to this point, either the animal never got
                            // a lot of actual kernel time, or we're not penalizing for time (the user has the debugger attached,
                            // or trace window open, for example). Don't blacklist them, but go ahead and restart the game
                            Trace.WriteLine(
                                string.Format(
                                    "Tried accessing animal thread {0} times, but not blacklisted yet -- restart.",
                                    tries));
                            shutdownWithoutBlacklist = true;
                            break;
                        }
                    }
                    else
                    {
                        Debug.WriteLine("Deadlock detection off");
                    }
                }
                else
                {
                    break;
                }
            }

            handleRestartsAndBlacklist(currentAnimal, blacklist);
            handleRestartWithoutBlacklist(blacklist, shutdownWithoutBlacklist);
        }
        // This is our last line of defense to deal with animals that try to hang the game (deadlock).
        // (the first line of defense is ThreadAborting the thread with our timer, see description in ActivateBug()).
        // Thus, it must have robust code that can always fail in some graceful way, and should blacklist
        // any animal that hangs. Because blacklisting an animal is very drastic, we go through great pains
        // to do it fairly, which means that we want to ensure that the animal is getting actual time to run
        // in the OS kernel, and the elapsed time isn't simply because the system is starving its thread
        // or something.  If the animal got plenty of kernel time and didn't come back, we restart the game
        // and blacklist them permanently.  If they aren't getting kernel time but it still taking way too long
        // we simply restart the game.
        void RunAnimalWithDeadlockDetection(OrganismWrapper currentAnimal)
        {
            Int64 kernelStart, userStart, kernelStop, userStop;
            bool validTime = false;
            int tries = 0;
            bool blacklist = false;
            bool shutdownWithoutBlacklist = false;

            // Hand the activationThread an animal and kick off processing
            bug = currentAnimal;
            validTime = GetAnimalThreadTime(out kernelStart, out userStart);
            animalDone.Reset();
            animalReady.Set();

            // Now we spin in a loop and periodically check to see if the animal returned the thread to us.
            while (true)
            {
                // If the animal returns, animalDone will get set on the activation thread and we'll continue.
                // if not, this will timeout.
                bool executionDone = animalDone.WaitOne(animalDeadlockCheckMSec, false);

                if (!executionDone)
                {
                    Trace.WriteLine("Animal thread not stopped after " + animalDeadlockCheckMSec + " mSec, checking kernel time.");

                    if (DetectDeadlock)
                    {
                        // If we were unable to retreive the time from GetAnimalThreadTime() above, just wait
                        // for the full number of tries
                        if (validTime)
                        {
                            // Only permanently blacklist the animal if we are first trying to threadabort them
                            // (PenalizeForTime == true) Otherwise, animals that really won't hang the machine will
                            // get permanently blacklisted even though they could have been stopped with a threadabort.
                            // PenalizeForTime is only false when the tracewindow is up since it affects animal timings
                            if (PenalizeForTime)
                            {
                                validTime = GetAnimalThreadTime(out kernelStop, out userStop);
                                if (validTime)
                                {
                                    Int64 totalTime = (kernelStop - kernelStart) + (userStop - userStart);

                                    // Give the animal a bunch of time since lots of things can happen on their thread
                                    // that is actually reflected as time their thread actually got in the kernel like
                                    // GCs, Jitting, etc.
                                    if (totalTime > animalDeadlock100NSec)
                                    {
                                        Trace.WriteLine("Thread overtime: " + ((double) (totalTime) / (double) 10000000).ToString() + " seconds, Blacklist and exit");
                                        blacklist = true;
                                        break;
                                    }
                                }
                                else
                                {
                                    Debug.WriteLine("Invalid Time From GetThreadTimes()");
                                }
                            }
                            else
                            {
                                Debug.WriteLine("Not penalizing for time -- don't permanently blacklist.");
                            }
                        }
                        else
                        {
                            Debug.WriteLine("Invalid Time From GetThreadTimes()");
                        }

                        tries++;

                        if (tries >= animalDeadlockRetries)
                        {
                            // If we've tried this many times and got to this point, either the animal never got
                            // a lot of actual kernel time, or we're not penalizing for time (the user has the debugger attached,
                            // or trace window open, for example). Don't blacklist them, but go ahead and restart the game
                            Trace.WriteLine("Tried accessing animal thread " + tries + " times, but not blacklisted yet -- restart.");
                            shutdownWithoutBlacklist = true;
                            break;
                        }
                    }
                    else
                    {
                        Debug.WriteLine("Deadlock detection off");
                    }
                }
                else
                {
                    break;
                }
            }  // end timing while loop

            // Restart and Blacklist
            if (DetectDeadlock && blacklist)
            {
                Debug.WriteLine("Permanently blacklisting: " + ((Species) currentAnimal.Organism.State.Species).AssemblyInfo.FullName);

                // Mark the animal in a magic file on disk so when we restart we will blacklist them.  We can't do it now
                // because the assembly is locked.
                currentEngine.Pac.LastRun = ((Species) currentAnimal.Organism.State.Species).AssemblyInfo.FullName;
                throw new MaliciousOrganismException();
            }

            // Restart, but don't blacklist anyone
            // also check for blacklist here in case DetectDeadlock changed values after blacklist was set
            if (shutdownWithoutBlacklist || blacklist)
            {
                throw new MaliciousOrganismException();
            }
        }