Just as I was going to suggest Floyd's cycle-detection algorithm, rici's post beat me to it. However, the whole thing can be made more practical by speeding up comparisons of full states.
The bottleneck of the proposed algorithm would be in comparing full state. These comparisons will usually not finish, but stop early --- at the first difference.
One optimization is to remember where the past differences occurred, and check those parts of the state first. For example, maintain a list of locations, and go through this list before making a full comparison. When a location from this list exposes a difference, stop the comparison (with failure), and move the location to the front of the list.
A different (and potentially more scalable) approach is to use incremental hashing.
Pick a function of the full state such that the hash values are easy to adjust in O(1) when some part of the state changes. For example, take a weighted sum of state words mod some large prime and concatenate with the unweighted sum mod some other large prime (can also throw in a modular weighted sum of squares of words, with different weight and modulus). This way, hash updates will take O(1) time on each execution step, and comparisons will take O(1) time until you get a hit. The probability of a false positive (i.e., the hashes match while the states differ) is very low, and even if this ever happens, it will amortize over a large number of true negatives (false negatives are impossible).
Of course, in practice, it seems more likely to get into situations like generating digits of the number pi --- things keep on changing, but never end. Another frequent possibility is that the infinite loop allocates memory, in which case it quickly exhausts all available memory.
In my course on algorithms and data structures, our autograder has to deal with student submissions that sometimes get into infinite loops. This is taken care of by a 30-second time-out and a certain memory limit. Both are much looser than runtime and memory budgets we impose as part of grading. I am not sure if implementing true infinite-loop detection would make a lot of sense in this context because such programs will run quite a bit slower (this is where hardware support for state hashing could help, but again you'd need additional uses to justify this). When students know that their program timed out, they can usually find the infinite loop.
1
possible duplicate of Is it possible to solve the halting problem if you have a constrained or a predictable input?
– Juho – 2013-04-28T23:39:48.340I don't think so; there are no constraints on the input. – Kyle Strand – 2013-04-29T01:54:18.933
Is your question about a real runtime environment (like the JVM), or about a programmatically-generic manner of detecting such a loop ? – Benj – 2013-04-29T10:44:35.400
@Benj http://stackoverflow.com/q/16249785/1858225 The original question (which wasn't mine) was about real runtime environments (or rather, about OSes). That got closed, though, so I rewrote it, I shifted the focus to the theoretical side.
– Kyle Strand – 2013-04-29T13:48:49.067OK. The only way I see it is to sample some keypoints and make a hash of them (this could be the last lines of a log output, or some CPU state such as stack ptr) and store the hashes of a set of probes (a set at a given time) in a Markov Chain. Then, you will be able (by choosing the right "probes") to detect cyclic locks. I'm thinking also about hooking system libraries accesses and using their entries as probes. Enjoy ;) – Benj – 2013-04-29T14:10:32.400