An agent framework I built for my AI research has exactly that.
I use an additional message parameter, automatically inserted and maintained by the framework, which is a list of the messages (FIPA style operation + parameters) from the originating agent forwards to the point of debugging. This gets voluminous and is gated by debug levels.
Same here. The framework I've been building over and over for various companies for the past 20 years has extensive debugging capabilities. With the right 'messages all the way down' mindset, it gets extremely powerful.
Message passing in the OOP sense does not imply there's no call stack. Whether or not there's a call stack is an implementation detail.
The same holds true if you actually pass async messages on a bus - nothing stops you from attaching call details to the message. In fact, we have one very prominent async messaging system that does exactly that: E-mail (via "Received:" headers). (And yes, I've used e-mail as a message bus for applications before - Qmail worked great for that)
That's a big down side of a framework for asynchronous message passing (object-oriented or not). E.g. "Flow based programming".
Message passing OOP doesn't necessarily imply that type of message passing. That is to say, the "send" call doesn't have to return until the target object has processed the message.
Also, method calls (that return) are really two calls, in a way: the call which passes the arguments along with a continuation, and then the call to the continuation which returns the value. :)
I use an additional message parameter, automatically inserted and maintained by the framework, which is a list of the messages (FIPA style operation + parameters) from the originating agent forwards to the point of debugging. This gets voluminous and is gated by debug levels.