PageSourceSearch

https://www.electronjs.org/assets/js/8d169b99.33830fa6.js

js electronjs.org collected 2026-09-24 07:05:09 UTC 11,989 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkelectronjs=self.webpackChunkelectronjs||[]).push([["32866"],{66213(e,n,t){t.r(n),t.d(n,{metadata:()=>o,default:()=>u,frontMatter:()=>s,contentTitle:()=>a,toc:()=>c,assets:()=>l});var o=JSON.parse('{"id":"latest/development/debugging-on-macos","title":"Debugging on macOS","description":"If you experience crashes or issues in Electron that you believe are not caused by your JavaScript application, but instead by Electron itself, debugging can be a little bit tricky especially for developers not used to native/C++ debugging. However, using lldb and the Electron source code, you can enable step-through debugging with breakpoints inside Electron\'s source code. You can also use XCode for debugging if you prefer a graphical interface.","source":"@site/docs/latest/development/debugging-on-macos.md","sourceDirName":"latest/development","slug":"/latest/development/debugging-on-macos","permalink":"/docs/latest/development/debugging-on-macos","draft":false,"unlisted":false,"editUrl":"https://github.com/electron/electron/edit/main/docs/development/debugging-on-macos.md","tags":[],"version":"current","frontMatter":{"title":"Debugging on macOS","description":"If you experience crashes or issues in Electron that you believe are not caused by your JavaScript application, but instead by Electron itself, debugging can be a little bit tricky especially for developers not used to native/C++ debugging. However, using lldb and the Electron source code, you can enable step-through debugging with breakpoints inside Electron\'s source code. You can also use XCode for debugging if you prefer a graphical interface.","slug":"debugging-on-macos","hide_title":false},"sidebar":"docs","previous":{"title":"Electron Debugging","permalink":"/docs/latest/development/debugging"},"next":{"title":"Debugging on Windows","permalink":"/docs/latest/development/debugging-on-windows"}}'),r=t(74848),i=t(28453);let s={title:"Debugging on macOS",description:"If you experience crashes or issues in Electron that you believe are not caused by your JavaScript application, but instead by Electron itself, debugging can be a little bit tricky especially for developers not used to native/C++ debugging. However, using lldb and the Electron source code, you can enable step-through debugging with breakpoints inside Electron's source code. You can also use XCode for debugging if you prefer a graphical interface.",slug:"debugging-on-macos",hide_title:!1},a="Debugging on macOS",l={},c=[{value:"Requirements",id:"requirements",level:2},{value:"Attaching to and Debugging Electron",id:"attaching-to-and-debugging-electron",level:2},{value:"Setting Breakpoints",id:"setting-breakpoints",level:3},{value:"Further Reading",id:"further-reading",level:3}];function d(e){let n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"debugging-on-macos",children:"Debugging on macOS"})}),"\n",(0,r.jsxs)(n.p,{children:["If you experience crashes or issues in Electron that you believe are not caused\nby your JavaScript application, but instead by Electron itself, debugging can\nbe a little bit tricky especially for developers not used to native/C++\ndebugging. However, using ",(0,r.jsx)(n.code,{children:"lldb"})," and the Electron source code, you can enable\nstep-through debugging with breakpoints inside Electron's source code.\nYou can also use ",(0,r.jsx)(n.a,{href:"/docs/latest/development/debugging-with-xcode",children:"XCode for debugging"})," if you prefer a graphical interface."]}),"\n",(0,r.jsx)(n.h2,{id:"requirements",children:"Requirements"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"A testing build of Electron"}),": The easiest way is usually to build it from source,\nwhich you can do by following the instructions in the ",(0,r.jsx)(n.a,{href:"/docs/latest/development/build-instructions-macos",children:"build instructions"}),". While you can attach to and debug Electron as you can download it directly, you will\nfind that it is heavily optimized, making debugging substantially more difficult.\nIn this case the debugger will not be able to show you the content of all\nvariables and the execution path can seem strange because of inlining,\ntail calls, and other compiler optimizations."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Xcode"}),": In addition to Xcode, you should also install the Xcode command line tools.\nThey include ",(0,r.jsx)(n.a,{href:"https://lldb.llvm.org/",children:"LLDB"}),", the default debugger in Xcode on macOS. It supports\ndebugging C, Ob
1jective-C and C++ on the desktop and iOS devices and simulator."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:".lldbinit"}),": Create or edit ",(0,r.jsx)(n.code,{children:"~/.lldbinit"})," to allow Chromium code to be properly source-mapped."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-text",children:"# e.g: ['~/electron/src/tools/lldb']\nscript sys.path[:0] = ['<...path/to/electron/src/tools/lldb>']\nscript import lldbinit\n"})}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"attaching-to-and-debugging-electron",children:"Attaching to and Debugging Electron"}),"\n",(0,r.jsxs)(n.p,{children:["To start a debugging session, open up Terminal and start ",(0,r.jsx)(n.code,{children:"lldb"}),", passing a non-release\nbuild of Electron as a parameter."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"$ lldb ./out/Testing/Electron.app\n(lldb) target create \"./out/Testing/Electron.app\"\nCurrent executable set to './out/Testing/Electron.app' (x86_64).\n"})}),"\n",(0,r.jsx)(n.h3,{id:"setting-breakpoints",children:"Setting Breakpoints"}),"\n",(0,r.jsx)(n.p,{children:"LLDB is a powerful tool and supports multiple strategies for code inspection. For\nthis basic introduction, let's assume that you're calling a command from JavaScript\nthat isn't behaving correctly - so you'd like to break on that command's C++\ncounterpart inside the Electron source."}),"\n",(0,r.jsxs)(n.p,{children:["Relevant code files can be found in ",(0,r.jsx)(n.code,{children:"./shell/"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["Let's assume that you want to debug ",(0,r.jsx)(n.code,{children:"app.setName()"}),", which is defined in ",(0,r.jsx)(n.code,{children:"browser.cc"}),"\nas ",(0,r.jsx)(n.code,{children:"Browser::SetName()"}),". Set the breakpoint using the ",(0,r.jsx)(n.code,{children:"breakpoint"})," command, specifying\nfile and line to break on:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"(lldb) breakpoint set --file browser.cc --line 117\nBreakpoint 1: where = Electron Framework`atom::Browser::SetName(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) + 20 at browser.cc:118, address = 0x000000000015fdb4\n"})}),"\n",(0,r.jsx)(n.p,{children:"Then, start Electron:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"(lldb) run\n"})}),"\n",(0,r.jsx)(n.p,{children:"The app will immediately be paused, since Electron sets the app's name on launch:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"(lldb) run\nProcess 25244 launched: '/Users/fr/Code/electron/out/Testing/Electron.app/Contents/MacOS/Electron' (x86_64)\nProcess 25244 stopped\n* thread #1: tid = 0x839a4c, 0x0000000100162db4 Electron Framework`atom::Browser::SetName(this=0x0000000108b14f20, name=\"Electron\") + 20 at browser.cc:118, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1\n    frame #0: 0x0000000100162db4 Electron Framework`atom::Browser::SetName(this=0x0000000108b14f20, name=\"Electron\") + 20 at browser.cc:118\n   115 	}\n   116\n   117 	void Browser::SetName(const std::string& name) {\n-> 118 	  name_override_ = name;\n   119 	}\n   120\n   121 	int Browser::GetBadgeCount() {\n(lldb)\n"})}),"\n",(0,r.jsxs)(n.p,{children:["To show the arguments and local variables for the current frame, run ",(0,r.jsx)(n.code,{children:"frame variable"})," (or ",(0,r.jsx)(n.code,{children:"fr v"}),'),\nwhich will show you that the app is currently setting the name to "Electron".']}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:'(lldb) frame variable\n(atom::Browser *) this = 0x0000000108b14f20\n(const string &) name = "Electron": {\n    [...]\n}\n'})}),"\n",(0,r.jsxs)(n.p,{children:["To do a source level single step in the currently selected thread, execute ",(0,r.jsx)(n.code,{children:"step"})," (or ",(0,r.jsx)(n.code,{children:"s"}),").\nThis would take you into ",(0,r.jsx)(n.code,{children:"name_override_.empty()"}),". To proceed and do a step over,\nrun ",(0,r.jsx)(n.code,{children:"next"})," (or ",(0,r.jsx)(n.code,{children:"n"}),")."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:'(lldb) step\nProcess 25244 stopped\n* thread #1: tid = 0x839a4c, 0x0000000100162dcc Electron Framework`atom::Browser::SetName(this=0x0000000108b14f20, name="Electron") + 44 at browser.cc:119, queue = \'com.apple.main-thread\', stop reason = step in\n    frame #0: 0x0000000100162dcc Electron Framework`atom::Browser::SetName(this=0x0000000108b14f20, name="Electron") + 44 at browser.cc:119\n   116\n   117 	void Browser::SetName(const std::string& name) {\n   118 	  name_override_ = name;\n-> 119 	}\n   120\n   121 	int Browser::GetBadgeCount() {\n   122 	  return badge_count_;\n'})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"NOTE:"})," If you don't see source code when you think you should, you may 
1not have added the ",(0,r.jsx)(n.code,{children:"~/.lldbinit"})," file above."]}),"\n",(0,r.jsxs)(n.p,{children:["To finish debugging at this point, run ",(0,r.jsx)(n.code,{children:"process continue"}),". You can also continue until a certain\nline is hit in this thread (",(0,r.jsx)(n.code,{children:"thread until 100"}),"). This command will run the thread in the current\nframe till it reaches line 100 in this frame or stops if it leaves the current frame."]}),"\n",(0,r.jsxs)(n.p,{children:["Now, if you open up Electron's developer tools and call ",(0,r.jsx)(n.code,{children:"setName"}),", you will once again hit the\nbreakpoint."]}),"\n",(0,r.jsx)(n.h3,{id:"further-reading",children:"Further Reading"}),"\n",(0,r.jsxs)(n.p,{children:["LLDB is a powerful tool with a great documentation. To learn more about it, consider\nApple's debugging documentation, for instance the ",(0,r.jsx)(n.a,{href:"https://developer.apple.com/library/mac/documentation/IDEs/Conceptual/gdb_to_lldb_transition_guide/document/lldb-basics.html#//apple_ref/doc/uid/TP40012917-CH2-SW2",children:"LLDB Command Structure Reference"}),"\nor the introduction to ",(0,r.jsx)(n.a,{href:"https://developer.apple.com/library/mac/documentation/IDEs/Conceptual/gdb_to_lldb_transition_guide/document/lldb-terminal-workflow-tutorial.html",children:"Using LLDB as a Standalone Debugger"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["You can also check out LLDB's fantastic ",(0,r.jsx)(n.a,{href:"https://lldb.llvm.org/tutorial.html",children:"manual and tutorial"}),", which\nwill explain more complex debugging scenarios."]})]})}function u(e={}){let{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453(e,n,t){t.d(n,{R:()=>s,x:()=>a});var o=t(96540);let r={},i=o.createContext(r);function s(e){let n=o.useContext(i);return o.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),o.createElement(i.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.