• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 285
  • Last Modified:

Persisting / Serializing the entire state of an object including the call stack

I wish to serialize or somehow persist the entire state of an instance of a class, my object as it were. But not only that, I wish to persist the state of the call stack including all the local variables' values in every function call in the stack. So that when I de-serialize or restore my object, I can resume the exact state of the object including where I am in the call stack and resume program execution from there.

I have tried using IFormatter and BinaryFormatter, but these seem only to store the member data of the object.

Is it possible to achieve what I'm after? The persisting of the object is to take place during a function call within the object itself (using 'this' as the object to serialize) and the whole object is running across two threads (a main thread on which it was created and a worker thread created by it). Although, this can easily be changed so that the object to be serialized is just on a worker thread on which it was created.

Thanks in advance for any help you can give me with this.
0
Xtreem
Asked:
Xtreem
  • 5
  • 5
  • 3
2 Solutions
 
gregoryyoungCommented:
No its not persistence only saves the data associated with an object...but if you were to implement your logic as a finite state machine then you could as all of the ifrmation would be in the data of the object:)
0
 
multithreadingCommented:
Yes, it is possible, but it is clear from your question that this is not practical for the problem you are trying to solve. This is the wrong road for what you are trying to achieve.
0
 
XtreemAuthor Commented:
Ok... can you elaborate? How is it possible, firstly? And secondly, why am I going about it the wrong way?
0
NFR key for Veeam Backup for Microsoft Office 365

Veeam is happy to provide a free NFR license (for 1 year, up to 10 users). This license allows for the non‑production use of Veeam Backup for Microsoft Office 365 in your home lab without any feature limitations.

 
gregoryyoungCommented:
multithreading it is not possible using any included formatter to serialize call stacks an resume ...

The concept of serialization is only to serialize an objects state (the data it contains).

"So that when I de-serialize or restore my object, I can resume the exact state of the object including where I am in the call stack and resume program execution from there."

If you have a way of doing this without architecting to be a finite state machine I would love to hear it. How exactly do you intend to rebuild the heap on deserialization? Simple example ... one of the items on the call stack is a reference to something in the heap (do you intend to serialize the entire heap (or atleast the entire graph pointed to by any reference on the callstack?). What if you aren't in managed code? What about the state of those objects on the heap like whether or not they are pinned (which isn't even stored with the object on the heap). There is no way to serialize a call stack and resume well unless you dump a full memory dump of the app.

There is no support for anything like this in serialization...



With some rearchitecture you could make the object a finite state machine (which would end up in a way making it so you can deserializing and continuing) but you can't just save an IP/call stack and resume.
0
 
multithreadingCommented:
gregory, yes, of course, you can't do it "using the standard formatters". I didn't read the problem so much as "how can I do this exactly as I am asking to have it done" so much as just "can I do this". There was no point in citing errors in the original statement of the problem, when it was clear to me (as it was to you) that this is the wrong road in the first place.

xtreem, I know this is not the right road for you because of the way you worded the question. It implicitly underestimates the complexity of this approach, in order to achieve an unstated objective that is highly likely acheivable in a much simpler way. A state machine, as suggested by gregory, is a good place to look first. Had you made reference to writing a debugger or something of that nature, then I would have answered differently. Also, by asking how to serialize your "object" and bring the stack along as an afterthought, I know you are looking at this backwards. Without knowing anything else, I am 99% certain this isn't the correct road to solving your true underlying objective.

With that said, what IS your objective? What is the underlying problem you are trying to solve?
0
 
XtreemAuthor Commented:
Ok guys, looks like I might've looked at all this the wrong way round from what you're both saying. However, to let you in on the particular problem, basically it is this:

I am calling a function which takes a parameter, and then calls itself recursively. A particular call of the function could call itself anything from 0 to 1024 times (in a loop).  And the recursing can go up to 256 levels deep.  The function has some local variables in it to keep track of the loop state.

Work this out, and you have a BIG maximum number of function calls, n! x 4^n, where n = 256, to be exact, or 1.15 x 10^661, more than there are atoms in the universe. But that's by the by; needless to say, it takes a long time, and if my computer crashes, I want to recover from where it left off, with the recursive call stack intact and the loop state inside of all the function calls all the way up the call stack, and, of course, also the value of the parameter passed in.
0
 
gregoryyoungCommented:
can you put up your current looping? I reckon its no problem to set back u your call stack (one key would be to use a Stack object instead of relying on the call stack) then you can just serialize it out :)
0
 
XtreemAuthor Commented:
I've stripped it down for brevity but here it is

    List<MyClass1> myArray = new List<MyClass1>(256);
    private void MyFunction(MyClass2 obj)
    {
        foreach (MyClass1 element in myArray)
        {
            if (element.Process)
            {
                MyFunction(new MyClass2());
            }
        }
    }

Obviously, if my computer crashes, I want to save the call stack of where I am in MyFunction() and all the previous calls to MyFunction() retaining the value of obj and which element I am up to in myArray in the foreach loop for every call of MyFunction() in the call stack.
0
 
gregoryyoungCommented:
you weren't doing anything with MyClass2 so I wasnt sure on any processing ... I just see a full depth first traversal ... so here is a full depth first traversal of every possible combination. You can watch it resume after the thread is killed .... by serializing the object it would also continue after serialization ...

Cheers,

Greg


    public class PositionSavingTraversal<T>
    {
       
        private List<T> m_Data;
        private int[] m_Positions;
        public PositionSavingTraversal(IEnumerable<T> _Data)
        {
            m_Data = new List<T>(_Data); //copy to our local list
            m_Positions = new int[m_Data.Count];
        }

        public void Recurse()
        {
            RecurseInternal(0);
            Console.WriteLine("Recursion completed");
        }

        public void RecurseInternal(int _CurrentDepth)
        {
            if (_CurrentDepth == m_Data.Count)
            {
                return;
            }
            if (m_Positions[_CurrentDepth] == m_Data.Count)
            {
                m_Positions[_CurrentDepth] = 0;
            }
            while (m_Positions[_CurrentDepth] < m_Data.Count)
            {
                if (m_Data.Count - _CurrentDepth > 7)
                {
                    Console.WriteLine(new string('\t', _CurrentDepth) + m_Positions[_CurrentDepth]);
                }
                RecurseInternal(_CurrentDepth + 1);
                m_Positions[_CurrentDepth]++;
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            int[] test = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
            PositionSavingTraversal<int> foo = new PositionSavingTraversal<int>(test);
            while (true)
            {
                Thread t = new Thread(new ThreadStart(foo.Recurse));
                t.Start();
                Console.WriteLine("Thread started, press enter to kill thread");
                Console.ReadLine();
                t.Abort();
                Console.WriteLine("press enter to start new thread and resume");
                Console.ReadLine();
            }
        }
    }

0
 
multithreadingCommented:
Now we are getting somewhere, but to jump back into this loop, we need to save the complete state, including any heap objects that get created etc. From the looks of it that isn't an issue, hopefully not just because that part was elided.

You need to put in a little more state transformation in your stripped down example, because there is obviously some critcially important state change that got left out. The example loop is an endless loop. Does MyFunction turn off the "Process" flag when it is done processing (and, if so, does anything else, your other thread for example,  ever change the flag back to true?

For this to work, the state changes on myArray are going to have to be deterministic, such that a subsequent run would have gotten to the same place, had it run through the steps that will be skipped at restart.

Does "myArray", and the recursion depth and position contain the entire state for your algorithm (factoring in your other thread)?

Also, is this strictly a CPU bound cituation? I'm asking this because you will end up with a solution that could run MyFunction twice on the last element processed on the prior run with the approach that we are advocating here? Is that going to work? (It may not without additional considerations if you are dealing with anything outside, like a file, etc.)
0
 
gregoryyoungCommented:
Using my example ... so long as it maintains a reference to all objects it needs it will work fully (including for serialization)
0
 
XtreemAuthor Commented:
No, this Question wasn't abandoned, I was saving this till I got round to implementing gregoryyoung's 'full depth first traversal' solution.  Please leave this Question open for the time being...
0
 
XtreemAuthor Commented:
Ok, I agree. It looks like it's going to be a while before I get round to this. So I'll accept gregoryyoung's answer with an assisted answer from multithreading. Thanks for your help guys!
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 5
  • 5
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now