Opened 6 weeks ago

Closed 3 weeks ago

#19309 closed bug (fixed)

[Debugger] Stack traces inside Gecko are completely wrong

Reported by: waddlesplash Owned by: anevilyak
Priority: normal Milestone: R1/beta6
Component: Applications/Debugger Version: R1/beta5
Keywords: Cc:
Blocked By: Blocking:
Platform: All

Description

For example, on a fork call, this is the stack trace I get from Debugger:

	thread 5250: IPC Launch #1
		0x7fa5b31363d0	0x1d6abfb852b	fork + 0x1b
		0x7fa5b3136460	0x26b036aa24	js::frontend::GeneralParser<js::frontend::SyntaxParseHandler, mozilla::Utf8Unit>::bindingIdentifierOrPattern(js::frontend::DeclarationKind, js::frontend::YieldHandling, js::frontend::TokenKind) + 0x12c
		0x7fa5b31364b0	0x26b039e906	js::frontend::Parser<js::frontend::FullParseHandler, char32_t>::globalBody(js::frontend::GlobalSharedContext*) + 0xee
		0x7fa5b3136520	0x26b039d618	js::frontend::Parser<js::frontend::FullParseHandler, char32_t>::evalBody(js::frontend::EvalSharedContext*) + 0x240
		0x7fa5b3136550	0x26b03a6e8a	CompileStandaloneFunction(JSContext*, JS::ReadOnlyCompileOptions const&, JS::SourceText<char32_t>&, mozilla::Maybe<unsigned int> const&, js::frontend::FunctionSyntaxKind, js::GeneratorKind, js::FunctionAsyncKind, JS::Handle<js::Scope*>) + 0x4f2
		0x7fa5b31365d0	0x26afd919bf	content_analysis::sdk::ContentAnalysisRequest::_InternalParse(char const*, google::protobuf::internal::ParseContext*) + 0x477
		0x7fa5b31366c0	0x26afda3918	mozilla::ExtensionPolicyService::GetCoreByHost(nsTSubstring<char> const&) + 0x70
		0x7fa5b3136780	0x26afd9f38a	mozilla::IdentityCredentialStorageService::DeleteLightweightData(mozIStorageConnection*, mozilla::dom::IPCIdentityCredential const&) + 0x212
		0x7fa5b31367b0	0x26afda2147	mozilla::OriginAttrsPatternMatchOriginSQLFunction::OnFunctionCall(mozIStorageValueArray*, nsIVariant**) + 0x17f
		0x7fa5b31367f0	0x26b03b11a2	js::frontend::BytecodeEmitter::emitDestructuringOpsArray(js::frontend::ListNode*, js::frontend::DestructuringFlavor) + 0x74a
		0x7fa5b3136820	0x26b036f2f4	js::frontend::GeneralParser<js::frontend::FullParseHandler, char32_t>::continueStatement(js::frontend::YieldHandling) + 0xbc
		0x7fa5b3136a00	0x26afd9d21e	mozilla::IdentityCredentialStorageService::BlockShutdown(nsIAsyncShutdownClient*) + 0x86
		0x7fa5b3136a40	0x79fe1a2fc9	_pt_root + 0xb9
		0x7fa5b3136a60	0x1d6abf43a35	pthread_thread_entry(void*, void*) + 0x15
		00000000	0x7fa5d487c2b0	commpage_thread_exit + 0

And this is the stack trace I get from GDB:

1  fork                                                                                                                                                                                                                                                                                               0x5677d4a420   
2  base::LaunchApp(std::vector<std::string> const&, base::LaunchOptions&&, int *)                                                                                                                                                                                                                     0x1ddf3049a29  
3  mozilla::ipc::PosixProcessLauncher::DoLaunch()                                                                                                                                                                                                                                                     0x1ddf307d90b  
4  mozilla::ipc::BaseProcessLauncher::PerformAsyncLaunch()                                                                                                                                                                                                                                            0x1ddf307c61b  
5  mozilla::detail::ProxyRunnable<mozilla::MozPromise<mozilla::ipc::LaunchResults, mozilla::ipc::LaunchError, true>, RefPtr<mozilla::MozPromise<mozilla::ipc::LaunchResults, mozilla::ipc::LaunchError, true>> (mozilla::ipc::BaseProcessLauncher:: *)(), mozilla::ipc::BaseProcessLauncher>::Run()   0x1ddf3085e8c  
6  mozilla::TaskQueue::Runner::Run()                                                                                                                                                                                                                                                                  0x1ddf2a709c2  
7  nsThreadPool::Run()                                                                                                                                                                                                                                                                                0x1ddf2a8291b  
8  nsThread::ProcessNextEvent(bool, bool *)                                                                                                                                                                                                                                                           0x1ddf2a7e38d  
9  NS_ProcessNextEvent(nsIThread *, bool)                                                                                                                                                                                                                                                             0x1ddf2a8114d  
10 mozilla::ipc::MessagePumpForNonMainThreads::Run(base::MessagePump::Delegate *)                                                                                                                                                                                                                     0x1ddf30901a7  
11 MessageLoop::Run()                                                                                                                                                                                                                                                                                 0x1ddf304e2f6  
12 nsThread::ThreadFunc(void *)                                                                                                                                                                                                                                                                       0x1ddf2a7c223  
13 _pt_root                                                                                                                                                                                                                                                                                           0x1d74a9ccfcc  
14 pthread_thread_entry(void *, void *)                                                                                                                                                                                                                                                               0x5677cd5948   
15 ??                                                                                                                                                                                                                                                                                                 0x7fff3184d2b0 
16 ??                                                                                                                                                                                                                                                                                                                

Change History (7)

comment:1 by waddlesplash, 6 weeks ago

Meanwhile the kernel debugger doesn't even try, it stops at "fork" and prints no more stack frames after that.

comment:2 by waddlesplash, 6 weeks ago

#8877 may be related?

comment:3 by anevilyak, 6 weeks ago

In the case where no frame information is available (.debug/eh_frame), both the user and kernel debugger currently assume the simple case of stack frames delineated by the stack/frame pointer registers. This worked fine back in the day but with newer gcc having made fomit-frame-pointer the default will break spectacularly in the latter case as ebp/rbp will instead contain application data. Handling this correctly requires a significantly more sophisticated algorithm that starts from the beginning of the function to figure out how to get to the current instruction pointer in order to correctly reconstruct the frame and where the return address is. On the plus side this would have the side effect of being able to completely discover all register values for unassisted frames though.

comment:4 by waddlesplash, 6 weeks ago

Well, this file (libxul.so) does appear to contain an .eh_frame:

 13 .eh_frame_hdr 00201674  00000000024c2c7c  00000000024c2c7c  024c2c7c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 14 .eh_frame     00bb96b8  00000000026c42f0  00000000026c42f0  026c42f0  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA

So why is it failing in this case then?

comment:5 by anevilyak, 6 weeks ago

Its presence doesn't guarantee it covers all compilation units ; the compiler will only emit unwind info for functions that are called in a context where an exception handler might need to deal with them.

comment:6 by waddlesplash, 5 weeks ago

There's an interesting comment at the top of this thread: https://news.ycombinator.com/item?id=35592446

Implementing the algorithm described there as a "first pass" sounds worthwhile. But if this is also related to #19022 and others, maybe there is something else wrong here.

comment:7 by waddlesplash, 3 weeks ago

Milestone: UnscheduledR1/beta6
Resolution: fixed
Status: newclosed

Fixed in hrev58524.

Note: See TracTickets for help on using tickets.