Closed Bug 533055 Opened 16 years ago Closed 16 years ago

IPDL: Add an RPCChannel::DumpStack() method to help with debugging

Categories

(Core :: IPC, enhancement)

x86
Windows XP
enhancement
Not set
normal

Tracking

()

RESOLVED FIXED
Tracking Status
status1.9.2 --- .4-fixed

People

(Reporter: cjones, Assigned: cjones)

References

Details

(Whiteboard: [fixed-lorentz])

Attachments

(3 files, 1 obsolete file)

Apparently the MSVC debugger isn't able to navigate up the stack through plugins compiled in a certain way (~= -fomit-frame-pointer?). This makes debugging RPC errors harder, because although the RPC stack was designed to directly map to the C++ stack, that's of no use when much of the C++ stack is chomped. This should be moderately easy. The best solution would be adding a virtual |PrintDebugInfo()| method to Message, but we can't do that without changing a lot of code that has direct references to Message's. So I think an acceptable intermediate solution is to add a |const char* const debug_desc_| field to Message that's set by IPDL-generated code to the literal name of the message, like "CallFooCtor". This should be cheap enough to leave on in opt builds. Then RPCChannel just needs to keep around enough breadcrumbs to allow it to print both in-calls and out-calls (currently it only tracks out-calls). It would probably be nice to print deferred messages in the stack as well. Something like --------- [2] in async PStream::Notify(actorID=3) --------- [1] out rpc PScriptableObject::GetProperty(actorId=-2) --------- [0] in rpc PScriptableObject::Invoke(actorId=-2) (deferred out rpc PScriptableObject::SetProperty(actorId=4)) --------- ought to do the trick. We could log more information in debug builds.
I implemented the following interface and output format (gdb) p this->mChannel.DumpRPCStack(stdout, "") RPCChannel 'backtrace': [(0) in rpc PTestSyncWakeup::Msg_StackFrame(actor=2147483647) ] [(1) out rpc PTestSyncWakeup::Msg_StackFrame(actor=2147483647) ] [(2) in sync PTestSyncWakeup::Msg_Sync2(actor=2147483647) ] $1 = void (gdb) pvector this->mChannel.mCxxStackFrames elem[0]: $3 = { mDirection = mozilla::ipc::RPCChannel::IN_MESSAGE, mMsg = 0x7fffffffe260 } elem[1]: $4 = { mDirection = mozilla::ipc::RPCChannel::OUT_MESSAGE, mMsg = 0x7fffe0002900 } elem[2]: $5 = { mDirection = mozilla::ipc::RPCChannel::IN_MESSAGE, mMsg = 0x7fffffffdf00 } Vector size = 3 Vector capacity = 4 Element type = mozilla::ipc::RPCChannel::RPCFrame * (gdb) p this->mChannel.DebugAbort("", 0, "", "test", "test", false) ###!!! [RPCChannel][Parent][:0] Assertion () failed. test (triggered by test) RPCChannel 'backtrace': [(0) in rpc PTestSyncWakeup::Msg_StackFrame(actor=2147483647) ] [(1) out sync PTestSyncWakeup::Msg_StackFrame(actor=2147483647) ] [(2) in sync PTestSyncWakeup::Msg_Sync2(actor=2147483647) ] remote RPC stack guess: 1 deferred stack size: 0 out-of-turn RPC replies stack size: 0 Pending queue size: 0, front to back: (The "actor=2147483647" stuff just means "toplevel".)
Assignee: nobody → jones.chris.g
Attachment #429942 - Flags: review?(bent.mozilla)
I went ahead and left this code on in debug and opt. It should be quite cheap, and is easy enough to disable anyway.
Attachment #429945 - Flags: review?(bent.mozilla)
Attachment #429942 - Flags: review?(bent.mozilla) → review+
Attachment #429943 - Flags: review?(bent.mozilla) → review+
Comment on attachment 429945 [details] [diff] [review] Part 3: Track |Message|s being processed on the C++ stack and offer a DumpRPCStack() method to print them >+ mCxxStackFrames() You can just remove that can't you? >+RPCChannel::DumpRPCStack(FILE* outfile, const char* const pfx) >+{ >+ fprintf(outfile, "%sRPCChannel 'backtrace':\n", pfx); It's kinda tough to tell msvc to use stdout manually when you break in the debugger. You've currently got the default set to stdout in the header, but I don't think that helps. Let's make the default be null and then set to stdout within the function. Also, calling this off the worker thread could be trouble... Maybe warn or something? >+ void Describe(int32* id, >+ const char** dir, const char** sems, const char** name) Nit: Weird wrapping? >+ CxxStackFrame(RPCChannel& that, >+ Direction direction, const Message* msg) : mThat(that) { And again.
Attachment #429945 - Flags: review?(bent.mozilla) → review+
Updated per comments, and fixed the use-after-free bug that was leading to corrupted "RPC stack frames". Just looking for an interdiff re-affirmation r?.
Attachment #429945 - Attachment is obsolete: true
Attachment #432972 - Flags: review?(bent.mozilla)
Attachment #432972 - Flags: review?(bent.mozilla) → review+
Blanket approval for Lorentz merge to mozilla-1.9.2 a=beltzner for 1.9.2.4 - please make sure to mark status1.9.2:.4-fixed
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: