它们通信的目的在于:
b2g要发消息给nuwa,让它fork出web app进程。它们发生在nuwa进程已经完全启动,并准备好fork 其他app子进程。猜想,用的是socket pair 建立关系,ipdl(最终用的是共享内存读写)进行线程级别的信息交互。socket pair只是用于建立通道???
nuwa的操作,从b2g开始fork出两个进程之后,兵分两路,nuwa进程完成自己的所有初始化(包括哪些?)且一直在等待b2g的加载新进程的消息。b2g也一路走下去,完成初始化等,并在appstartup 请求nuwa加载新进程。
具体通信:
/**
* How does B2G Loader Work?
*
* <<parent process>> <<child process>>
* ProcLoaderParent -----> ProcLoaderChild
* ^ |
* | load() | content_process_main()
* | V
* ProcLoaderClient Nuwa/plugin-container
* ^
* | ProcLoaderLoad()
* ...
* ContentParent
*
*
* B2G loader includes an IPC protocol PProcLoader for communication
* between client (parent) and server (child). The b2g process is the
* client. It requests the server to load/start the Nuwa process with
* the given arguments, env variables, and file descriptors.
*
* ProcLoaderClientInit() is called by B2G loader to initialize the
* client side, the b2g process. Then the b2g_main() is called to
* start b2g process.
*
* ProcLoaderClientGeckoInit() is called by XRE_main() to create the
* parent actor, |ProcLoaderParent|, of PProcLoader for servicing the
* request to run Nuwa process later once Gecko has been initialized.
*创建parent actor 用于请求nuwa加载进程
* ProcLoaderServiceRun() is called by the server process. It starts
* an IOThread and event loop to serve the |ProcLoaderChild|
* implmentation of PProcLoader protocol as the child actor. Once it
* recieves a load() request, it stops the IOThread and event loop,
* then starts running the main function of the content process with
* the given arguments.
*
* NOTE: The server process serves at most one load() request.
*/
/**
* How does B2G Loader Work?
*
* <<parent process>> <<child process>>
* ProcLoaderParent -----> ProcLoaderChild
* ^ |
* | load() | content_process_main()
* | V
* ProcLoaderClient Nuwa/plugin-container
* ^
* | ProcLoaderLoad()
* ...
* ContentParent
*
*
* B2G loader includes an IPC protocol PProcLoader for communication
* between client (parent) and server (child). The b2g process is the
* client. It requests the server to load/start the Nuwa process with
* the given arguments, env variables, and file descriptors.
*
* ProcLoaderClientInit() is called by B2G loader to initialize the
* client side, the b2g process. Then the b2g_main() is called to
* start b2g process.
*
* ProcLoaderClientGeckoInit() is called by XRE_main() to create the
* parent actor, |ProcLoaderParent|, of PProcLoader for servicing the
* request to run Nuwa process later once Gecko has been initialized.
*创建parent actor 用于请求nuwa加载进程
* ProcLoaderServiceRun() is called by the server process. It starts
* an IOThread and event loop to serve the |ProcLoaderChild|
* implmentation of PProcLoader protocol as the child actor. Once it
* recieves a load() request, it stops the IOThread and event loop,
* then starts running the main function of the content process with
* the given arguments.
*
* NOTE: The server process serves at most one load() request.
*/ |
#include "mozilla/ipc/PProcLoaderParent.h"
#include "mozilla/ipc/PProcLoaderChild.h"
gecko/ipc/glue/ProcessUtils_linux.cpp
前b2g:
main->LoadStaticData ->LoadLibxul-> XPCOMGlueEnablePreload--->//设置值为true ,使得可preload,预加载
main->LoadStaticData ->LoadLibxul -> XPCOMGlueStartup--->XPCOMGlueLoad --->ReadDependentCB//获取5个.so库
main->LoadStaticData ->LoadLibxul -> XPCOMGlueLoadXULFunctions--->//加载出GlueLoadXUL函数,并保存其地址,两次加载的函数不一样
main->LoadStaticData ->XRE_ProcLoaderPreload --->//开始preload,进程预加载
.cpp:945, Fuc:XRE_ProcLoaderPreload >>>>>>>>>>>>>>>>>>>>>>>>>>>st.func
.cpp:950, Fuc:XRE_ProcLoaderPreload call NS_NewNativeLocalFile-->//新的本地文件
.cpp:951, Fuc:XRE_ProcLoaderPreload aProgramDir:/system/b2g/,omnijarFile//程序目录
.cpp:957, Fuc:XRE_ProcLoaderPreload call Omnijar->AppendNative--->//添加进omnijar中
.cpp:970, Fuc:XRE_ProcLoaderPreload <<<<<<<<<<<<<<<<<<<<<<<<<<<ed.func
|
以上数据函数库等完全准备好了。
完毕之后就开始:
main --> return RunProcesses(argc, argv, reservedFds)
开始fork后分出两个进程进行工作。
main() (b2g/app/B2GLoader.cpp)
|
|-ReserveFileDescriptors
|
|-LoadStaticData
|
|-RunProcesses
|
|-fork
|
|-XRE_ProcLoaderServiceRun (child(nuwa) process)
|
|-b2g_main (parent(b2g) process) (b2g/app/nsBrowserApp.cpp)
|
|-android::ProcessState::self()->startThreadPool();
|
|-(void)setsid();
|
|-do_main
|
|-mozilla::StartBootAnimation();
|
|-XRE_main
|
|-XREMain::XRE_main
|
nuwa process:
main ->RunProcesses->XRE_ProcLoaderServiceRun -> mozilla::ipc::ProcLoaderServiceRun(aPeerPid:180, aFd:14,aArgc:1, aArgv[...0]:/system/b2g/b2g,aReservedFds[...0]:3)
RunProcesses->XRE_ProcLoaderServiceRun->ProcLoaderServiceRun->
(1XRE_InitCommandLine->XRE_GetBinaryPath(aArgv:/system/b2g/b2g)
(2process= new ContentProcess(aPeerPid:179)--->
ChildThread *iothread = process->child_thread();
(3new ProcLoaderChild(aPeerPid:179)->iothread->message_loop()
ProcLoaderChild *loaderChild = new ProcLoaderChild(aPeerPid)
loaderChild->Open(transport, aPeerPid, iothread->message_loop())
ProcessChild::ProcessChild(ProcessId aParentPid)
: ChildProcess(new IOThreadChild())
, mUILoop(MessageLoop::current())
, mParentPid(aParentPid)
{ ... }
(4BackgroundHangMonitor::Prohibit()
(5loop.Run();
(6 BackgroundHangMonitor::Allow();
(7 XRE_DeinitCommandLine();
(8 int ret = task->DoWork()->int ret = content_process_main(argc, argv)
RunProcesses开始,
nuwa 进程被fork 出来,去执行XRE_ProcLoaderServiceRun->ProcLoaderServiceRun call XRE_InitCommandLine--->
Fuc:RunProcesses ### pid >0 is parentSock(Pid of childSock), or 0 is return by childSock:0
Fuc:RunProcesses ### pid=0,|pid='0',it is childprocess|, isChildProcess=1
Fuc:RunProcesses close parentSock,in nuwa(child) process
Fuc:RunProcesses call XRE_ProcLoaderServiceRun--->
Fuc:RunProcesses XRE_ProcLoaderServiceRun(getppid():181, childSock:14, argc:1, argv:/system/b2g/b2g,aReservedFds[...0]:3)
ipc/glue/ProcessUtils_linux.cpp:672, Fuc:XRE_ProcLoaderServiceRun ----------------------------------
ipc/glue/ProcessUtils_linux.cpp:673, Fuc:XRE_ProcLoaderServiceRun .==nuwa process==. XRE_ProcLoaderServiceRun call mozilla::ipc::ProcLoaderServiceRun(aPeerPid:181, aFd:14,aArgc:1, aArgv[...0]:/system/b2g/b2g,aReservedFds[...0]:3)
ipc/glue/ProcessUtils_linux.cpp:577, Fuc:ProcLoaderServiceRun ----------------------------------
ipc/glue/ProcessUtils_linux.cpp:588, Fuc:ProcLoaderServiceRun aArgv[i]:/system/b2g/b2g
ipc/glue/ProcessUtils_linux.cpp:597, Fuc:ProcLoaderServiceRun call XRE_InitCommandLine--->b2g ,nuwa都要来执行这个模块,为了getbinarypath 二进制可执行文件的地址?
cpp:4583, Fuc:XRE_InitCommandLine ----------------------------------
nuwa 进程被fork 出来,去执行XRE_ProcLoaderServiceRun->ProcLoaderServiceRun ->XRE_InitCommandLine--->
XRE_ProcLoaderServiceRun传入b2g的pid,child的sock 号,就直接去初始化XRE_InitCommandLine,
Fuc:XRE_InitCommandLine XRE_GetBinaryPath(aArgv:/system/b2g/b2g)--->//一样,获取地址
rocessUtils_linux.cpp:610, Fuc:ProcLoaderServiceRun new ContentProcess(aPeerPid:181)--->
rocessChild.cpp:46, Fuc:ProcessChild >>>>>>>>>>>>>>>>>>>>>>>>>>>st.func
rocessUtils_linux.cpp:615, Fuc:ProcLoaderServiceRun new ProcLoaderChild(aPeerPid:181)--->//传入b2g的进程pid,是直接复制b2g一模一样的资源吗?
rocessUtils_linux.cpp:619, Fuc:ProcLoaderServiceRun loaderChild->Open(transport, aPeerPid, iothread->message_loop())//加载子进程并打开,io线程执行message_loop,并与b2g进程进行传输消息?
rocessUtils_linux.cpp:621, Fuc:ProcLoaderServiceRun call BackgroundHangMonitor::Prohibit()--->//禁止后台挂起监控
rocessUtils_linux.cpp:625, Fuc:ProcLoaderServiceRun call loop.Run--->//循环运行
/**
* Run service of ProcLoader.//开启进程加载器的服务端,一直在那里运行,传入参数就是b2g进程的pid,以及socket的文件描述符(父进程的?不对是childSock:14,)
*
* \param aPeerPid is the pid of the parent.
* \param aFd is the file descriptor of the socket for IPC.
*
* See the comment near the head of this file.
*/
static int
ProcLoaderServiceRun(pid_t aPeerPid, int aFd,
int aArgc, const char *aArgv[],
FdArray& aReservedFds)
{
...
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
b2g process:
1.
1.1main ->RunProcesses->XRE_ProcLoaderClientInit->ProcLoaderClientInit //初始化client 端,各数据供后与nuwa通信用
XRE_ProcLoaderClientInit call mozilla::ipc::ProcLoaderClientInit(aPeerPid:556, aChannelFd:13)
ProcLoaderClientInit sProcLoaderPid:556,sProcLoaderChannelFd:13,sProcLoaderClientInitialized:true
初始化这些数据,供后面nuwa 与b2g 通信时建立连接等。
1.2main ->RunProcesses->b2g_main -> startThreadPool--->//共享线程池
1.3main ->RunProcesses->b2g_main ->XPCOMGlueLoadXULFunctions //再次加载GlueLoadXUL函数
抓重点!!!别看些细枝末节的东西。
1.4b2g_main->do_main -> StartBootAnimation--->//开机动画
1.5main ->RunProcesses->b2g_main -> do_main--->XRE_main
b2g_main->do_main -> XRE_main--->XRE_main::XRE_main()->:
b2g_main->do_main-> XRE_main--->XRE_main::XRE_main() -> XRE_mainInit--->mDirProvider.Initialize-->//初始化目录服务
XRE_mainInit -> XRE_InitCommandLine()-->//xre 主初始化命令行,
XRE_main::XRE_main() -> XRE_mainStartup--->//主启动,版本创建
ScopedXPCOMStartup::Initialize()
XRE_main::XRE_main() ->rv = mScopedXPCOM->Initialize()--->NS_InitXPCOM2-->//初始化并启动xpcom等
fork分开之初:
Fuc:RunProcesses aReservedFds:0,argv[]:PATH=/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin
Fuc:RunProcesses aReservedFds:0,argv[]:LOOP_MOUNTPOINT=/mnt/obb
Fuc:RunProcesses aReservedFds:-1229987536,argv[]:ANDROID_DATA=/data
Fuc:RunProcesses aReservedFds:1,argv[]:ANDROID_ROOT=/system
Fuc:RunProcesses aReservedFds:0,argv[]:EMULATED_STORAGE_TARGET=/storage/emulated
Fuc:RunProcesses virtual fd from socketpair,ipcSockets[0]:13,ipcSockets[1]:14
Fuc:RunProcesses parentSock:13,childSock:14
Fuc:RunProcesses before fork,childSock:14,parentSock:13
Fuc:RunProcesses ### pid >0 is parentSock(Pid of childSock), or 0 is return by childSock:530
Fuc:RunProcesses ### pid=530,|pid='0',it is childprocess|, isChildProcess=0
Fuc:RunProcesses close childSock,in b2g(parent) process
Fuc:RunProcesses call XRE_ProcLoaderClientInit---> Fuc:RunProcesses XRE_ProcLoaderClientInit(childPid:530, parentSock:13, aReservedFds[...03)]:
ipc/glue/ProcessUtils_linux.cpp:658, Fuc:XRE_ProcLoaderClientInit ----------------------------------
ipc/glue/ProcessUtils_linux.cpp:661, Fuc:XRE_ProcLoaderClientInit call mozilla::ipc::CloseFileDescriptors(aReservedFds)
ipc/glue/ProcessUtils_linux.cpp:663, Fuc:XRE_ProcLoaderClientInit .==b2g process==. XRE_ProcLoaderClientInit call mozilla::ipc::ProcLoaderClientInit(aPeerPid:530, aChannelFd:13)
ipc/glue/ProcessUtils_linux.cpp:216, Fuc:ProcLoaderClientInit ----------------------------------
ipc/glue/ProcessUtils_linux.cpp:222,Fuc:ProcLoaderClientInit sProcLoaderPid:530,sProcLoaderChannelFd:13,sProcLoaderClientInitialized:true Fuc:RunProcesses call return b2g_main(argc:1,argv:/system/b2g/b2g)--->
g_main >>>>>>>>>>>>>>>>>>>>>>>>>>>st.func
p:330, Fuc:RunProcesses call return b2g_main(argc:1,argv:/system/b2g/b2g)--->
Fuc:b2g_main >>>>>>>>>>>>>>>>>>>>>>>>>>>st.func
Fuc:b2g_main call startThreadPool--->
Fuc:b2g_main call XPCOMGlueLoadXULFunctions 2cond --->
COMGlue.cpp:446, Fuc:XPCOMGlueLoadXULFunctions ----------------------------------
COMGlue.cpp:451, Fuc:XPCOMGlueLoadXULFunctions sTop->libHandle:libxul.so
|
main() ->RunProcesses fork 出2进程后:
main() ->RunProcesses->b2g_main -> XPCOMGlueLoadXULFunctions 不厌其烦地废话!!!
XPCOMGlueLoadXULFunctions 就加载些函数,并不是重点,过。
call XPCOMGlueLoadXULFunctions 2cond --->//第一次是在LoadStaticdata
, Fuc:XPCOMGlueLoadXULFunctions ----------------------------------
, Fuc:XPCOMGlueLoadXULFunctions sTop->libHandle:libxul.so
, Fuc:XPCOMGlueLoadXULFunctions aSymbols->functionName:XRE_GetFileFromPath
, Fuc:XPCOMGlueLoadXULFunctions buffer:XRE_GetFileFromPath
, Fuc:XPCOMGlueLoadXULFunctions call GetSymbol(sTop->libHandle, buffer)--->
, Fuc:GetSymbol dlsym: XRE_GetFileFromPath
, Fuc:XPCOMGlueLoadXULFunctions result of GetSymbol: aSymbols->function:b4ef5bed
, Fuc:XPCOMGlueLoadXULFunctions ++aSymbols:b6fe7da0
, Fuc:XPCOMGlueLoadXULFunctions aSymbols->functionName:XRE_CreateAppData
, Fuc:XPCOMGlueLoadXULFunctions buffer:XRE_CreateAppData
, Fuc:XPCOMGlueLoadXULFunctions call GetSymbol(sTop->libHandle, buffer)--->
, Fuc:GetSymbol dlsym: XRE_CreateAppData
, Fuc:XPCOMGlueLoadXULFunctions result of GetSymbol: aSymbols->function:b4efec61
, Fuc:XPCOMGlueLoadXULFunctions ++aSymbols:b6fe7da8
, Fuc:XPCOMGlueLoadXULFunctions aSymbols->functionName:XRE_FreeAppData
, Fuc:XPCOMGlueLoadXULFunctions buffer:XRE_FreeAppData
, Fuc:XPCOMGlueLoadXULFunctions call GetSymbol(sTop->libHandle, buffer)--->
, Fuc:GetSymbol dlsym: XRE_FreeAppData
, Fuc:XPCOMGlueLoadXULFunctions result of GetSymbol: aSymbols->function:b4efce11
, Fuc:XPCOMGlueLoadXULFunctions ++aSymbols:b6fe7db0
, Fuc:XPCOMGlueLoadXULFunctions aSymbols->functionName:XRE_TelemetryAccumulate
, Fuc:XPCOMGlueLoadXULFunctions buffer:XRE_TelemetryAccumulate
, Fuc:XPCOMGlueLoadXULFunctions call GetSymbol(sTop->libHandle, buffer)--->
, Fuc:GetSymbol dlsym: XRE_TelemetryAccumulate
, Fuc:XPCOMGlueLoadXULFunctions result of GetSymbol: aSymbols->function:b4ee0089
, Fuc:XPCOMGlueLoadXULFunctions ++aSymbols:b6fe7db8
, Fuc:XPCOMGlueLoadXULFunctions aSymbols->functionName:XRE_main
, Fuc:XPCOMGlueLoadXULFunctions buffer:XRE_main
, Fuc:XPCOMGlueLoadXULFunctions call GetSymbol(sTop->libHandle, buffer)--->
, Fuc:GetSymbol dlsym: XRE_main
, Fuc:XPCOMGlueLoadXULFunctions result of GetSymbol: aSymbols->function:b4efbfed
, Fuc:XPCOMGlueLoadXULFunctions ++aSymbols:b6fe7dc0
gotCounters:1
rocesses ### pid >0 is parentSock(Pid of childSock), or 0 is return by childSock:0
|
中间分析:b2g -> nuwa 猜想假设等
RunProcesses XRE_ProcLoaderClientInit(childPid:530, parentSock:13, aReservedFds[...0]:3)
ProcLoaderClientGeckoInit sProcLoaderParent = new ProcLoaderParent()
RunProcesses XRE_ProcLoaderServiceRun(getppid():181, childSock:14, argc:1, argv:/system/b2g/b2g,aReservedFds[...0]:3)
ProcLoaderServiceRun new ContentProcess(aPeerPid:181)--->,
new ProcLoaderChild(aPeerPid:181)
在b2g 和nuwa之间,起触发因素的似乎是appstartup,猜想,是appstartup 提交了启动应用的请求,b2g发消息给nuwa,nuwa结束目前循环,加载出来一个进程(对应一个上层应用),然后把它丢到后台,继续回来接活,直到又有新应用向b2g发请求,说”给我拉起一个进程,让这家伙跑“,nuwa接到活后快乐的去把它拉起来,丢到后台,然后继续出来接活,反反复复。
nuwa其实就是一个进程生产器,生产出来就丢出去,至于它们跟b2g的通信,或者进程和进程之间的通信,应该是它们自己解决,如何呢?ipdl如何运作?以及猜想是否正确,待验证。
b2g总模块:
从main->RunProcesses -> return b2g_main()进来开始,
b2g_main call startThreadPool--->//启动线程池子
b2g_main call XPCOMGlueLoadXULFunctions 2cond --->//加载公用函数,保存其地址
b2g_main call do_main--->
do_main call StartBootAnimation--->//调用开机动画模块,
do_main call return XRE_main--->
|
main() (b2g/app/B2GLoader.cpp)
|
|-ReserveFileDescriptors
|
|-LoadStaticData
|
|-RunProcesses
|
|-fork
|
|-XRE_ProcLoaderServiceRun (child(nuwa) process)
|
|-b2g_main (parent(b2g) process) (b2g/app/nsBrowserApp.cpp)
|
|-android::ProcessState::self()->startThreadPool();
|
|-(void)setsid();
|
|-do_main
|
|-mozilla::StartBootAnimation();
|
|-XRE_main
|
|-XREMain::XRE_main
|
gecko/toolkit/xre/nsAppRunner.cpp:4569, Fuc:XRE_main >>>>>>>>>>>>>>>>>>>>>>>>>>>st.func
|-XREMain::XRE_main
|
|-new ScopedAppData(aAppData);
|
|-XREMain::XRE_mainInit
|
|-XREMain::XRE_mainStartup
|
|-mScopedXPCOM = MakeUnique<ScopedXPCOMStartup>();
|
|-mScopedXPCOM->Initialize(); (toolkit/xre/nsAppRunner.cpp)
| |
| |-NS_InitXPCOM2 (xpcom/build/XPCOMInit.cpp)
| |
| |-sMessageLoop = new MessageLoopForUI(MessageLoop::TYPE_MOZILLA_UI);
| |
| |-ioThread = MakeUnique<BrowserProcessSubThread>(BrowserProcessSubThread::IO);
| |-ioThread->StartWithOptions
| |
| |-nsThreadManager::get()->Init();
| |
| |-nsTimerImpl::Startup();
| |
| |-nsComponentManagerImpl::gComponentManager = new nsComponentManagerImpl();
| |
| |-nsCycleCollector_init
| |
| |-nsCycleCollector_startup
| |
| |-JS_Init
| |
| |-nsComponentManagerImpl::gComponentManager->Init();(xpcom/components/nsComponentManager.cpp)
| | |
| | |-nsComponentManagerImpl::InitializeStaticModules()
| | |
| | |-RegisterModule(...)
| | |
| | |-greOmnijar =mozilla::Omnijar::GetReader(mozilla::Omnijar::GRE);
| | |
| | |-cl->location.Init(greOmnijar, "chrome.manifest");
| | |
| | |-nsComponentManagerImpl::RereadChromeManifests
| | |
| | |-nsComponentManagerImpl::RegisterManifest
| | |
| | |-DoRegisterManifest
| | |
| | |-ParseManifest
| | |
| | |-...
| | |
| | |-nsComponentManagerImpl::ManifestContract
| |
| |-XPTInterfaceInfoManager::GetSingleton();
| |
| |-nsDirectoryService::gService->RegisterCategoryProviders();
| |
| |-SharedThreadPool::InitStatics();
| |
| |-AbstractThread::InitStatics();
| |
| |-mozilla::scache::StartupCache::GetSingleton();
| |
| |-mozilla::AvailableMemoryTracker::Activate();
| |
| |-NS_CreateServicesFromCategory(...)
| |
| |-mozilla::HangMonitor::Startup();
| |
| |-mozilla::BackgroundHangMonitor::Startup();
| |
| |-sMainHangMonitor = new mozilla::BackgroundHangMonitor
|
|-XREMain::XRE_mainRun()
|
|-mozilla::ipc::ProcLoaderClientGeckoInit();
|
|-mScopedXPCOM->SetWindowCreator(mNativeApp);
|
|-startupNotifier->Observe(nullptr, APPSTARTUP_TOPIC, nullptr);
|
|-mDirProvider.DoStartup();
|
|-cmdLine->Init(...)
|
|-obsService->NotifyObservers(cmdLine, "command-line-startup", nullptr);
|
|-appStartup->CreateHiddenWindow();
|
|-obsService->NotifyObservers(nullptr, "final-ui-startup", nullptr);
|
|-cmdLine->Run(); (toolkit/components/commandlines/nsCommandLine.cpp)
| |
| |- nsCommandLine::EnumerateValidators
| |
| |-nsCommandLine::EnumerateHandlers
| |
| |-EnumRun
| |
| |-nsICommandLineHandler->Handle (first page will be loaded in here)
|
|-mNativeApp->Enable();
|
|-appStartup->Run(); (toolkit/components/startup/nsAppStartup.cpp)
|
|-mAppShell->Run(); (widget/gonk/nsAppShell.cpp->widget/nsBaseAppShell.cpp)
|
|-MessageLoop::current()->Run(); // run forever~~~~~
|
重点分析XRE_main:
结构:
|-new ScopedAppData(aAppData);
|
|-XREMain::XRE_mainInit//简言之,开启路径获取模块,获取路径
|
|-XREMain::XRE_mainStartup//设置关闭检查,创建版本
|
|-mScopedXPCOM = MakeUnique<ScopedXPCOMStartup>();
|
|-mScopedXPCOM->Initialize(); (toolkit/xre/nsAppRunner.cpp)
|-XREMain::XRE_mainRun()
|
前3个稍微了解即可,初始化启动些必要的东西。简言之,准备数据,数据丢进运行功能模块运行。
do_main call return XRE_main--->//进入xre_main
:do_main <<<<<<<<<<<<<<<<<<<<<<<<<<<ed.func
er.cpp:4569, Fuc:XRE_main >>>>>>>>>>>>>>>>>>>>>>>>>>>st.func
er.cpp:4571, Fuc:XRE_main call XRE_CreateStatsObject--->//创建对象?不重要
er.cpp:4573, Fuc:XRE_main call main.XRE_main()--->
er.cpp:4403, Fuc:XRE_main ----------------------------------
er.cpp:4408, Fuc:XRE_main call profilerGuard--->//保护设置
er.cpp:4418, Fuc:XRE_main gArgc:1,gArgv:/system/b2g/b2g
er.cpp:4440, Fuc:XRE_main call XRE_mainInit--->
er.cpp:3140, Fuc:XRE_mainInit ----------------------------------
er.cpp:3218, Fuc:XRE_mainInit chek for application.ini override//检查覆盖
er.cpp:3254, Fuc:XRE_mainInit XRE_GetBinaryPath-->//获取二进制文件路径
er.cpp:3301, Fuc:XRE_mainInit mDirProvider.Initialize-->//初始化目录提供服务模块
er.cpp:3310, Fuc:XRE_mainInit MOZ_CRASHREPORTER
er.cpp:3504, Fuc:XRE_mainInit call XRE_InitCommandLine()-->//b2g ,nuwa都要来执行这个模块,为了getbinarypath 二进制可执行文件的地址?
er.cpp:4583, Fuc:XRE_InitCommandLine ----------------------------------
er.cpp:4595, Fuc:XRE_InitCommandLine XRE_GetBinaryPath(aArgv:/system/b2g/b2g)--->//获取二进制文件路径,不重要
er.cpp:3527, Fuc:XRE_mainInit <<<<<<<<<<<<<<<<<<<<<<<<<<<ed.func//mainInit主要的初始化结束,
er.cpp:4446, Fuc:XRE_main XRE_mainStartup--->
er.cpp:3658, Fuc:XRE_mainStartup ----------------------------------
er.cpp:3664, Fuc:XRE_mainStartup call SetShutdownChecks()-->//设置关闭/机检查
er.cpp:3964, Fuc:XRE_mainStartup call BuildVersion-->//创建版本?不重要
er.cpp:4050, Fuc:XRE_mainStartup <<<<<<<<<<<<<<<<<<<<<<<<<<<ed.func
er.cpp:4454, Fuc:XRE_main call MakeUnique--->
er.cpp:4459, Fuc:XRE_main ----------------------------------
er.cpp:4460, Fuc:XRE_main ScopedXPCOMStartup::Initialize()
er.cpp:4461, Fuc:XRE_main rv = mScopedXPCOM->Initialize()--->
er.cpp:1571, Fuc:Initialize ----------------------------------
er.cpp:1575, Fuc:Initialize ---here ,startup xpcom---
er.cpp:1576, Fuc:Initialize ScopedXPCOMStartup::Initialize,call NS_InitXPCOM2-->
xpcom/build/XPCOMInit.cpp:512, Fuc:NS_InitXPCOM2 ----------------------------------
|
NS_InitXPCOM2重点分析:b2g process
|
|-NS_InitXPCOM2 (xpcom/build/XPCOMInit.cpp)
|
|-sMessageLoop = new MessageLoopForUI(MessageLoop::TYPE_MOZILLA_UI);//创建UI的messageloop,与界面请求相关,点击等
|
|-ioThread = MakeUnique<BrowserProcessSubThread>(BrowserProcessSubThread::IO);
|-ioThread->StartWithOptions
|
|-nsThreadManager::get()->Init();
|
|-nsTimerImpl::Startup();
|
|-nsComponentManagerImpl::gComponentManager = new nsComponentManagerImpl();
|
|-nsCycleCollector_init
|
|-nsCycleCollector_startup
|
|-JS_Init
|
|-nsComponentManagerImpl::gComponentManager->Init();(xpcom/components/nsComponentManager.cpp)
| |
| |-nsComponentManagerImpl::InitializeStaticModules()
| |
| |-RegisterModule(...)
| |
| |-greOmnijar =mozilla::Omnijar::GetReader(mozilla::Omnijar::GRE);
| |
| |-cl->location.Init(greOmnijar, "chrome.manifest");
| |
| |-nsComponentManagerImpl::RereadChromeManifests
| |
| |-nsComponentManagerImpl::RegisterManifest
| |
| |-DoRegisterManifest
| |
| |-ParseManifest
| |
| |-...
| |
| |-nsComponentManagerImpl::ManifestContract
|
|-XPTInterfaceInfoManager::GetSingleton();
|
|-nsDirectoryService::gService->RegisterCategoryProviders();
|
|-SharedThreadPool::InitStatics();
|
|-AbstractThread::InitStatics();
|
|-mozilla::scache::StartupCache::GetSingleton();
|
|-mozilla::AvailableMemoryTracker::Activate();
|
|-NS_CreateServicesFromCategory(...)
|
|-mozilla::HangMonitor::Startup();
|
|-mozilla::BackgroundHangMonitor::Startup();
|
|-sMainHangMonitor = new mozilla::BackgroundHangMonitor
|
b2g process NS_InitXPCOM2部分Log分析:
Fuc:XRE_main rv = mScopedXPCOM->Initialize()--->//开始进入初始化xpcom的入口
Fuc:Initialize ----------------------------------
Fuc:Initialize ---here ,startup xpcom---
Fuc:Initialize ScopedXPCOMStartup::Initialize,call NS_InitXPCOM2-->//调NS_InitXPCOM2
c:NS_InitXPCOM2 ----------------------------------//进NS_InitXPCOM2
c:NS_InitXPCOM2 the whole process: main()->RunProcesses()->b2g_main()->do_main()->XRE_main->ScopedXPCOMStartup::Initialize()->NS_InitXPCOM2()
Fuc:NS_InitXPCOM2 call -- mozilla::AvailableMemoryTracker::Init(); --->
Fuc:NS_InitXPCOM2 return value of MessageLoop::current = false//测试messageloop::current 是否已存在,作为判断是否是第一次开启的开关
Fuc:NS_InitXPCOM2 call -- sMessageLoop = new MessageLoopForUI(MessageLoop::TYPE_MOZILLA_UI); --->//创建UI的messageloop,与界面请求相关,点击等
Fuc:NS_InitXPCOM2 call -- sMessageLoop->set_thread_name('Gecko'); --->
Fuc:NS_InitXPCOM2 call -- sMessageLoop->set_hang_timeouts(128, 8192); --->//设置挂起时间
Fuc:NS_InitXPCOM2 if (XRE_IsParentProcess() && !BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)) = ?? //是父进程(仅b2g或者包括其他父进程?)且BrowserProcessSubThread::GetMessageLoop(nuwa那边)为false,即没有messageloop?简言之,保证是初次启动xpcom,且没有messageloop
Fuc:NS_InitXPCOM2 if (XRE_IsParentProcess() && !BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)) = true //进来了,满足两个条件,
Fuc:NS_InitXPCOM2 call -- UniquePtr<BrowserProcessSubThread> ioThread = MakeUnique<BrowserProcessSubThread>(BrowserProcessSubThread::IO); --->//new(创建) 了一个BrowserProcessSubThread::IO线程
Fuc:NS_InitXPCOM2 call -- options.message_loop_type = MessageLoop::TYPE_IO; --->//设置线程类型,
Fuc:NS_InitXPCOM2 call -- sIOThread = ioThread.release(); --->//释放线程???阻塞模式,直到所有工作完成才会释放 shutdown?
Fuc:NS_InitXPCOM2 Establish the main thread here.//创建主线程,
Fuc:NS_InitXPCOM2 call -- rv = nsThreadManager::get()->Init(); --->//创建主线程,初始化
Fuc:NS_InitXPCOM2 call -- // Set up the timer globals/timer thread --->
Fuc:NS_InitXPCOM2 call -- rv = nsTimerImpl::Startup(); --->//启动timer线程,用于???
Fuc:NS_InitXPCOM2 call -- NS_StartupLocalFile(); --->//启动localfile服务
Fuc:NS_InitXPCOM2 call -- if (aBinDirectory) { --->//获取二进制文件目录?
Fuc:NS_InitXPCOM2 call -- nsDirectoryService::gService->Set(NS_XPCOM_INIT_CURRENT_PROCESS_DIR, --->//设置当前进程目录
Fuc:NS_InitXPCOM2 aAppFileLocationProvider = true,call RegisterProvider()-->//获取app文件成功后,调用注册服务,注册组件?
Fuc:NS_InitXPCOM2 call -- nsDirectoryService::gService->Get(NS_GRE_BIN_DIR, --->//获取二进制文件目录
Fuc:NS_InitXPCOM2 call -- xpcomLib->AppendNative(nsDependentCString(XPCOM_DLL)); --->
Fuc:NS_InitXPCOM2 call -- nsDirectoryService::gService->Set(NS_XPCOM_LIBRARY_FILE, xpcomLib); --->//设置库文件路径 Fuc:NS_InitXPCOM2 call -- if (!mozilla::Omnijar::IsInitialized()) { --->//omnijar 未初始化则进行初始化,
Fuc:NS_InitXPCOM2 call -- if (!mozilla::Omnijar::IsInitialized()) { --->
Fuc:NS_InitXPCOM2 call -- mozilla::Omnijar::Init(); --->//按照所提供的NSfile 去调取相应的app???组件?
Fuc:NS_InitXPCOM2 Create the Component/Service Manage----
Fuc:NS_InitXPCOM2 call -- nsComponentManagerImpl::gComponentManager = new nsComponentManagerImpl(); --->//创建组件服务和管理
Fuc:NS_InitXPCOM2 call -- // Global cycle collector initialization. --->//全局循环收集器初始化
Fuc:NS_InitXPCOM2 call -- if (!nsCycleCollector_init()) { --->//若未初始化则初始化
Fuc:NS_InitXPCOM2 call -- nsCycleCollector_startup(); --->//并启动循环收集器
Fuc:NS_InitXPCOM2 call -- mozilla::SetICUMemoryFunctions(); --->
Fuc:NS_InitXPCOM2 ----- Initialize the JS engine -----//初始化js 引擎
Fuc:NS_InitXPCOM2 if (!JS_Init()),call JS_Init()--->
Fuc:NS_InitXPCOM2 call -- rv = nsComponentManagerImpl::gComponentManager->Init(); --->//初始化组件管理器,,,
MessageLoop最早出现在这里,可能是某个地方初始化时就启动了,未查明,不管了,不重要,估计单开了某个线程专门用于此 MessageLoop ----------------------------------
MessageLoop return BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)
MessageLoop ----------------------------------
MessageLoop return BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)
Fuc:NS_InitXPCOM2 NS_ADDREF(*aResult = nsComponentManagerImpl::gComponentManager)
Fuc:NS_InitXPCOM2 The iimanager constructor searches and registers XPT files.---
Fuc:NS_InitXPCOM2 call -- (void)XPTInterfaceInfoManager::GetSingleton(); --->//单例模式自动注册xpt,在这些组件均未实例化之前
Fuc:NS_InitXPCOM2 call -- // After autoreg, but before we actually instantiate any components, // add any services listed in the 'xpcom-directory-providers' category // to the directory service. --->
Fuc:NS_InitXPCOM2 nsDirectoryService::gService->RegisterCategoryProviders()-->//自动注册组件,多个个???
Fuc:NS_InitXPCOM2 call -- // Init SharedThreadPool (which needs the service manager). --->
Fuc:NS_InitXPCOM2 call -- SharedThreadPool::InitStatics(); --->//共享线程初始化
Fuc:NS_InitXPCOM2 call -- AbstractThread::InitStatics(); --->//抽象?线程初始化
Fuc:NS_InitXPCOM2 do_GetService of jsloader----
Fuc:NS_InitXPCOM2 componentLoader = do_GetService('@mozilla.org/moz/jsloader;1')--->//实例化jsloader服务
Fuc:NS_InitXPCOM2 // Notify observers of xpcom autoregistration star//
Fuc:NS_InitXPCOM2 NS_CreateServicesFromCategory(NS_XPCOM_STARTUP_CATEGORY,nullptr,NS_XPCOM_STARTUP_OBSERVER_ID) --->//创建监听服务,xpcom启动后的监听观察者
Fuc:NS_InitXPCOM2 XRE_IsParentProcess =true,call mozilla::SystemMemoryReporter::Init()--->//是父进程则
Fuc:NS_InitXPCOM2 call -- // The memory reporter manager is up and running -- register our reporters. --->
Fuc:NS_InitXPCOM2 call -- RegisterStrongMemoryReporter(new ICUReporter()); --->//注册内存报告服务
Fuc:NS_InitXPCOM2 call -- mozilla::Telemetry::Init(); --->//远程测试?初始化
Fuc:NS_InitXPCOM2 call -- mozilla::HangMonitor::Startup(); --->//启动挂起监控
Fuc:NS_InitXPCOM2 call -- mozilla::BackgroundHangMonitor::Startup(); --->//启动后台挂起监控
Fuc:NS_InitXPCOM2 call -- const MessageLoop* const loop = MessageLoop::current(); --->//调用消息队列循环,它之前为何出现messageloop 的信息
Fuc:NS_InitXPCOM2 call -- sMainHangMonitor = new mozilla::BackgroundHangMonitor( loop->thread_name().c_str(), loop->transient_hang_timeout(), loop->permanent_hang_timeout()); --->")//新建一个后台挂起监控,监听(线程名,短暂挂起,永久挂起)情况
--->startup xpcom seccessed?? call do_QueryInterface(mServiceManager)-->
Fuc:XRE_main call XRE_mainRun--->
XRE_mainRun ----------------------------------
call mozilla::ipc::ProcLoaderClientGeckoInit()--->
|
启动app(nuwa)进程 部分:
|-XREMain::XRE_mainRun()
|
|-mozilla::ipc::ProcLoaderClientGeckoInit();//调用ProcLoaderClientGeckoInit与service端建立连接?
|
|-mScopedXPCOM->SetWindowCreator(mNativeApp);
|
|-startupNotifier->Observe(nullptr, APPSTARTUP_TOPIC, nullptr);//开启APP启动监听者进行监听,
|
|-mDirProvider.DoStartup();
|
|-cmdLine->Init(...)//初始化命令行
|
|-obsService->NotifyObservers(cmdLine, "command-line-startup", nullptr);//通知器通知命令行启动
|
|-appStartup->CreateHiddenWindow();//创建隐藏窗口
|
|-obsService->NotifyObservers(nullptr, "final-ui-startup", nullptr);//通知器通知启动最终ui(窗口)
|
|-cmdLine->Run(); (toolkit/components/commandlines/nsCommandLine.cpp)//加载进第一个页面iframe进去???
| |
| |- nsCommandLine::EnumerateValidators
| |
| |-nsCommandLine::EnumerateHandlers
| |
| |-EnumRun
| |
| |-nsICommandLineHandler->Handle (first page will be loaded in here) //启动第一个页面/窗口(window)
|
|-mNativeApp->Enable();
|
|-appStartup->Run(); (toolkit/components/startup/nsAppStartup.cpp)//启动各种app,先systme app,homescreen 等?
|
|-mAppShell->Run(); (widget/gonk/nsAppShell.cpp->widget/nsBaseAppShell.cpp)
|
|-MessageLoop::current()->Run(); // run forever~~~~~
|
较完整版XRE_mainRun
/XPCOMInit.cpp:858, Fuc:NS_InitXPCOM2 call -- sMainHangMonitor = new mozilla::BackgroundHangMonitor( loop->thread_name().c_str(), loop->transient_hang_timeout(), loop->permanent_hang_timeout()); --->
, Fuc:Initialize startup xpcom seccessed?? call do_QueryInterface(mServiceManager)-->
完成了xpcom等的启动:
Fuc:XRE_main call XRE_mainRun--->//XRE_mainRun入口
Fuc:XRE_mainRun ----------------------------------
Fuc:XRE_mainRun call mozilla::ipc::ProcLoaderClientGeckoInit()--->//调ProcLoaderClientGeckoInit,作用是,new ProcLoaderParent端
rocessUtils_linux.cpp:231, Fuc:ProcLoaderClientGeckoInit ----------------------------------//创建parent actor, |ProcLoaderParent
rocessUtils_linux.cpp:251, Fuc:ProcLoaderClientGeckoInit sProcLoaderParent = new ProcLoaderParent()
rocessUtils_linux.cpp:251, Fuc:ProcLoaderClientGeckoInit sProcLoaderParent->Open(transport,sProcLoaderPid,XRE_GetIOMessageLoop(),ParentSide)//打开传输,并开始调XRE_GetIOMessageLoop循环,获取io的消息循环 73, Fuc:XRE_GetIOMessageLoop ----------------------------------
75, Fuc:XRE_GetIOMessageLoop return BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)
rocessUtils_linux.cpp:258, Fuc:ProcLoaderClientGeckoInit call sProcLoaderLoop = MessageLoop::current()--->//两个循环不一样???// Returns the MessageLoop object for the current thread, or null if none.返回当前线程的消息
Fuc:XRE_mainRun call SetWindowCreator--->//调用窗口创建器
mponents/startup/nsAppStartup.cpp:172, Fuc:nsAppStartup ----------------------------------//进入app启动器
mponents/startup/nsAppStartup.cpp:179, Fuc:Init ----------------------------------//初始化APP启动器,创建io观察监听器等
mponents/startup/nsAppStartup.cpp:185, Fuc:Init nsCOMPtr<nsIObserverService> os = mozilla::services::GetObse
mponents/startup/nsAppStartup.cpp:190, Fuc:Init os->AddObserver(this, 'quit-application.........', true)//添加监听器
Fuc:XRE_mainRun nsCOMPtr<nsIPrefService> prefs = do_GetService('@mozilla.org/preferences-service;1', &rv)//获取preferences 服务,偏好或优先权配置
Fuc:XRE_mainRun set of CrashReporter after xpcom Initialization,here? again?
打了太多垃圾log!!!!
Fuc:XRE_mainRun startupNotifier ,do_CreateInstance --//启动通知器
上段一样的,合并保留,懒得整理一起了
, Fuc:XRE_main call XRE_mainRun--->
, Fuc:XRE_mainRun ----------------------------------
, Fuc:XRE_mainRun call mozilla::ipc::ProcLoaderClientGeckoInit()---> ProcLoaderClientGeckoInit目的在于最后与nuwa 建立连接?
/ProcessUtils_linux.cpp:231, Fuc:ProcLoaderClientGeckoInit ----------------------------------
/ProcessUtils_linux.cpp:250, Fuc:ProcLoaderClientGeckoInit call -- Transport *transport = OpenDescriptor(fd, Transport::MODE_CLIENT); --->//open the fd of nuwa(child process)?设置打开nuwa的fd方式?
/ProcessUtils_linux.cpp:252, Fuc:ProcLoaderClientGeckoInit sProcLoaderParent = new ProcLoaderParent()
/ProcessUtils_linux.cpp:254, Fuc:ProcLoaderClientGeckoInit sProcLoaderParent->Open(transport,sProcLoaderPid,XRE_GetIOMessageLoop(),ParentSide) //打开建立连接,并启XRE_GetIOMessageLoop :673, Fuc:XRE_GetIOMessageLoop ----------------------------------
:675, Fuc:XRE_GetIOMessageLoop return BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)
/ProcessUtils_linux.cpp:259, Fuc:ProcLoaderClientGeckoInit call sProcLoaderLoop = MessageLoop::current()---> 创建当前的消息循环
, Fuc:XRE_mainRun call -- rv = mScopedXPCOM->SetWindowCreator(mNativeApp); --->//给app设置窗口,
components/startup/nsAppStartup.cpp:172, Fuc:nsAppStartup ---------------------------------- 开始启动APP
components/startup/nsAppStartup.cpp:179, Fuc:Init ----------------------------------//初始化等,如获取监听服务,添加服务等
components/startup/nsAppStartup.cpp:185, Fuc:Init nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService()
components/startup/nsAppStartup.cpp:190, Fuc:Init os->AddObserver(this, 'quit-application.........', true)
, Fuc:XRE_mainRun nsCOMPtr<nsIPrefService> prefs = do_GetService('@mozilla.org/preferences-service;1', &rv) 获取偏好设置服务
, Fuc:XRE_mainRun set of CrashReporter after xpcom Initialization,here? again?
, Fuc:XRE_mainRun call -- if (mStartOffline) { --->
, Fuc:XRE_mainRun call -- nsCOMPtr<nsIObserver> startupNotifier (do_CreateInstance(NS_APPSTARTUPNOTIFIER_CONTRACTID, &rv)); ---> 启动通知器
, Fuc:XRE_mainRun call -- startupNotifier->Observe(nullptr, APPSTARTUP_TOPIC, nullptr); --->使通知器启动一个对应用启动的监听 :673, Fuc:XRE_GetIOMessageLoop ----------------------------------
:675, Fuc:XRE_GetIOMessageLoop return BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)
, Fuc:XRE_mainRun call -- nsCOMPtr<nsIAppStartup> appStartup (do_GetService(NS_APPSTARTUP_CONTRACTID)); ---> 获取app启动服务,,重要
, Fuc:XRE_mainRun call -- mDirProvider.DoStartup(); ---> 启动路径提供器
谁调了它,,,
/XPCOMInit.cpp:272, Fuc:nsThreadManagerGetSingleton call -- return nsThreadManager::get()->QueryInterface(aIID, aInstancePtr); ---> 通过线程管理器获取单列模式的app线程?
:673, Fuc:XRE_GetIOMessageLoop ----------------------------------
:675, Fuc:XRE_GetIOMessageLoop return BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)
:673, Fuc:XRE_GetIOMessageLoop ----------------------------------
:675, Fuc:XRE_GetIOMessageLoop return BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)
:673, Fuc:XRE_GetIOMessageLoop ----------------------------------
:675, Fuc:XRE_GetIOMessageLoop return BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)
:673, Fuc:XRE_GetIOMessageLoop ----------------------------------
:675, Fuc:XRE_GetIOMessageLoop return BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)
:673, Fuc:XRE_GetIOMessageLoop ----------------------------------
:675, Fuc:XRE_GetIOMessageLoop return BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)
:673, Fuc:XRE_GetIOMessageLoop ----------------------------------
:675, Fuc:XRE_GetIOMessageLoop return BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)
, Fuc:XRE_mainRun call -- appStartup->GetShuttingDown(&mShuttingDown); ---> app诡异的关闭?关闭什么?
components/startup/nsAppStartup.cpp:574, Fuc:GetShuttingDown ----------------------------------
, Fuc:XRE_mainRun call -- if (!mShuttingDown) { --->关闭之后
, Fuc:XRE_mainRun call -- cmdLine = do_CreateInstance('@mozilla.org/toolkit/command-line;1'); ---> 调用命令行,并初始化命令行
, Fuc:XRE_mainRun call -- rv = cmdLine->Init(gArgc, gArgv, workingDir, nsICommandLine::STATE_INITIAL_LAUNCH); --->调用 初始化启动APP的各参数
ines/nsCommandLine.cpp:451, Fuc:Init ----------------------------------
, Fuc:XRE_mainRun call -- nsCOMPtr<nsIObserverService> obsService = mozilla::services::GetObserverService(); ---> 再此获取监听服务
, Fuc:XRE_mainRun call -- obsService->NotifyObservers(cmdLine, 'command-line-startup', nullptr); ---> 通知服务通知观察者启动命令行
, Fuc:XRE_mainRun SaveStateForAppInitiatedRestart()---> 保存APP的状态,用于重启
, Fuc:XRE_mainRun call -- // clear out any environment variables which may have been set // during the relaunch process now that we know we won't be relaunching. --->清除各种环境变量
, Fuc:XRE_mainRun call -- if (!mShuttingDown) { --->
, Fuc:XRE_mainRun call -- rv = appStartup->CreateHiddenWindow(); ---> 创建APP的隐藏窗口
components/startup/nsAppStartup.cpp:264, Fuc:CreateHiddenWindow ----------------------------------
, Fuc:XRE_mainRun call -- nsCOMPtr<nsIObserverService> obsService = mozilla::services::GetObserverService(); --->获取监听观察服务
, Fuc:XRE_mainRun call -- if (obsService) obsService->NotifyObservers(nullptr, 'final-ui-startup', nullptr); --->观察者通知监听器启动最终的ui
, Fuc:XRE_mainRun appStartup->DoneStartingUp()--> 完成APP的启动
components/startup/nsAppStartup.cpp:590, Fuc:DoneStartingUp ----------------------------------
, Fuc:XRE_mainRun call appStartup->GetShuttingDown(&mShuttingDown) 又关闭APP
components/startup/nsAppStartup.cpp:574, Fuc:GetShuttingDown ----------------------------------
, Fuc:XRE_mainRun call -- if (!mShuttingDown) { --->
, Fuc:XRE_mainRun mShuttingDown = false, rv = cmdLine->Run() 调用命令行运行
ines/nsCommandLine.cpp:641, Fuc:Run ----------------------------------
ines/nsCommandLine.cpp:643, Fuc:Run rv = EnumerateValidators(EnumValidate, nullptr)-->列举可以的APP???
ines/nsCommandLine.cpp:582, Fuc:EnumerateValidators ----------------------------------
ines/nsCommandLine.cpp:647, Fuc:Run rv = EnumerateHandlers(EnumRun, nullptr)-->
ines/nsCommandLine.cpp:530, Fuc:EnumerateHandlers ----------------------------------
ines/nsCommandLine.cpp:533, Fuc:EnumerateHandlers call -- nsCOMPtr<nsICategoryManager> catman (do_GetService(NS_CATEGORYMANAGER_CONTRACTID)); --->
ines/nsCommandLine.cpp:539, Fuc:EnumerateHandlers call -- rv = catman->EnumerateCategory('command-line-handler', getter_AddRefs(entenum)); ---> 处理命令行获取的APP???
ines/nsCommandLine.cpp:549, Fuc:EnumerateHandlers call -- while (NS_SUCCEEDED(strenum->HasMore(&hasMore)) && hasMore) { --->如果成功,则一直去处理更多的APP的运行???
循环多次??为什么?启动了几个APP???不可能,
ines/nsCommandLine.cpp:554, Fuc:EnumerateHandlers call -- rv = catman->GetCategoryEntry('command-line-handler', entry.get(), getter_Copies(contractID)); --->
ines/nsCommandLine.cpp:561, Fuc:EnumerateHandlers call -- nsCOMPtr<nsICommandLineHandler> clh(do_GetService(contractID.get())); --->
ines/nsCommandLine.cpp:633, Fuc:EnumRun ----------------------------------
ines/nsCommandLine.cpp:634, Fuc:EnumRun call -- return aHandler->Handle(aThis); --->
ines/nsCommandLine.cpp:554, Fuc:EnumerateHandlers call -- rv = catman->GetCategoryEntry('command-line-handler', entry.get(), getter_Copies(contractID)); --->
ines/nsCommandLine.cpp:561, Fuc:EnumerateHandlers call -- nsCOMPtr<nsICommandLineHandler> clh(do_GetService(contractID.get())); --->
ines/nsCommandLine.cpp:633, Fuc:EnumRun ----------------------------------
ines/nsCommandLine.cpp:634, Fuc:EnumRun call -- return aHandler->Handle(aThis); --->
ines/nsCommandLine.cpp:554, Fuc:EnumerateHandlers call -- rv = catman->GetCategoryEntry('command-line-handler', entry.get(), getter_Copies(contractID)); --->
ines/nsCommandLine.cpp:561, Fuc:EnumerateHandlers call -- nsCOMPtr<nsICommandLineHandler> clh(do_GetService(contractID.get())); --->
ines/nsCommandLine.cpp:633, Fuc:EnumRun ----------------------------------
ines/nsCommandLine.cpp:634, Fuc:EnumRun call -- return aHandler->Handle(aThis); --->
ines/nsCommandLine.cpp:554, Fuc:EnumerateHandlers call -- rv = catman->GetCategoryEntry('command-line-handler', entry.get(), getter_Copies(contractID)); --->
ines/nsCommandLine.cpp:561, Fuc:EnumerateHandlers call -- nsCOMPtr<nsICommandLineHandler> clh(do_GetService(contractID.get())); --->
ines/nsCommandLine.cpp:633, Fuc:EnumRun ----------------------------------
ines/nsCommandLine.cpp:634, Fuc:EnumRun call -- return aHandler->Handle(aThis); --->
循环四次以后,又开始关闭应用???疯了吗?
components/startup/nsAppStartup.cpp:727, Fuc:Observe ----------------------------------
, Fuc:XRE_mainRun call -- appStartup->GetShuttingDown(&mShuttingDown); --->
components/startup/nsAppStartup.cpp:574, Fuc:GetShuttingDown ----------------------------------
为了等待下面这个条件满足?
, Fuc:XRE_mainRun call -- if (PR_GetEnv('MOZ_INSTRUMENT_EVENT_LOOP')) { --->
, Fuc:XRE_mainRun call -- rv = appStartup->Run(); --->
components/startup/nsAppStartup.cpp:295, Fuc:Run ----------------------------------
components/startup/nsAppStartup.cpp:309, Fuc:Run call nsresult rv = mAppShell->Run()--->APP开始运行?之后去哪了?
cessHost.cpp:448, Fuc:LaunchAndWaitForProcessHandle call -- PrepareLaunch(); --->准备启动nuwa
cessHost.cpp:451, Fuc:LaunchAndWaitForProcessHandle call -- MessageLoop* ioLoop = XRE_GetIOMessageLoop(); --->调用messageloop信息队列循环, :673, Fuc:XRE_GetIOMessageLoop ----------------------------------
:675, Fuc:XRE_GetIOMessageLoop return BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)
cessHost.cpp:470, Fuc:InitializeChannel call -- CreateChannel(); ---> 创建通道连接service端
/ProcessUtils_linux.cpp:322, Fuc:ProcLoaderLoad ----------------------------------调ProcLoaderLoad开始加载nuwa进程???
/ProcessUtils_linux.cpp:323, Fuc:ProcLoaderLoad call -- * Request the loader service, the server, to load Nuwa. --->
/ProcessUtils_linux.cpp:352, Fuc:ProcLoaderLoad sProcLoaderLoop->PostTask(FROM_HERE, NewRunnableFunction(AsyncSendLoad, load))--> 将任务post到messageloop里,之后service 端开始接收到加载的请求, :673, Fuc:XRE_GetIOMessageLoop ----------------------------------
:675, Fuc:XRE_GetIOMessageLoop return BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)
下面是nuwa进程紧接着打印的Log,将要开始load nuwa
开始load nuwa:
/ProcessUtils_linux.cpp:521, Fuc:RecvLoad ----------------------------------
/ProcessUtils_linux.cpp:529, Fuc:RecvLoad call -- sProcLoaderDispatchedTask = new ProcLoaderLoadRunner(aArgv, aEnv, aFdsRemap, privs); --->
/ProcessUtils_linux.cpp:532, Fuc:RecvLoad call -- SendLoadComplete(mPeerPid, aCookie); --->
/ProcessUtils_linux.cpp:535, Fuc:RecvLoad call -- MessageLoop::current()->PostTask(FROM_HERE, NewRunnableFunction(_ProcLoaderChildDestroy, this)); --->
/ProcessUtils_linux.cpp:639, Fuc:ProcLoaderServiceRun call BackgroundHangMonitor::Allow()--->
/ProcessUtils_linux.cpp:641, Fuc:ProcLoaderServiceRun call XRE_DeinitCommandLine--->
/ProcessUtils_linux.cpp:648, Fuc:ProcLoaderServiceRun call task->DoWork()--->
/ProcessUtils_linux.cpp:451, Fuc:DoWork ----------------------------------
/ProcessUtils_linux.cpp:467, Fuc:DoWork call SetCurrentProcessPrivileges(mPrivs)--->
/ProcessUtils_linux.cpp:471, Fuc:DoWork Start Nuwa (main function),call int ret = content_process_main(argc, argv)--->
|
nuwa部分分析:
完整的nuwa process 端Log分析:
fork后b2g部分
Fuc:RunProcesses ### pid >0 is parentSock(Pid of childSock), or 0 is return by childSock:464
Fuc:RunProcesses ### pid=464,|pid='0',it is childprocess|, isChildProcess=0
Fuc:RunProcesses XRE_ProcLoaderClientInit(childPid:464, parentSock:13, aReservedFds[...0]:3)
/ipc/glue/ProcessUtils_linux.cpp:674, Fuc:XRE_ProcLoaderClientInit .==b2g process==. XRE_ProcLoaderClientInit call mozilla::ipc::ProcLoaderClientInit(aPeerPid:464, aChannelFd:13)
/ipc/glue/ProcessUtils_linux.cpp:222, Fuc:ProcLoaderClientInit sProcLoaderPid:464,sProcLoaderChannelFd:13,sProcLoaderClientInitialized:true
fork 后nuwa部分 nuwa 进程开始运行:
Fuc:RunProcesses ### pid >0 is parentSock(Pid of childSock), or 0 is return by childSock:0
Fuc:RunProcesses ### pid=0,|pid='0',it is childprocess|, isChildProcess=1
Fuc:RunProcesses close parentSock,in nuwa(child) process
Fuc:RunProcesses call XRE_ProcLoaderServiceRun--->
Fuc:RunProcesses XRE_ProcLoaderServiceRun(getppid():180, childSock:14, argc:1, argv:/system/b2g/b2g,aReservedFds[...0]:3)
/ipc/glue/ProcessUtils_linux.cpp:683, Fuc:XRE_ProcLoaderServiceRun ----------------------------------
/ipc/glue/ProcessUtils_linux.cpp:684, Fuc:XRE_ProcLoaderServiceRun .==nuwa process==. XRE_ProcLoaderServiceRun call mozilla::ipc::ProcLoaderServiceRun(aPeerPid:180, aFd:14,aArgc:1, aArgv[...0]:/system/b2g/b2g,aReservedFds[...0]:3)//nuwa调ProcLoaderServiceRun
/ipc/glue/ProcessUtils_linux.cpp:584, Fuc:ProcLoaderServiceRun ----------------------------------
/ipc/glue/ProcessUtils_linux.cpp:595, Fuc:ProcLoaderServiceRun aArgv[i]:/system/b2g/b2g
/ipc/glue/ProcessUtils_linux.cpp:604, Fuc:ProcLoaderServiceRun call XRE_InitCommandLine--->
.cpp:4583, Fuc:XRE_InitCommandLine ----------------------------------
.cpp:4595, Fuc:XRE_InitCommandLine XRE_GetBinaryPath(aArgv:/system/b2g/b2g)--->
/ipc/glue/ProcessUtils_linux.cpp:617, Fuc:ProcLoaderServiceRun new ContentProcess(aPeerPid:180)--->传入b2g进程的pid?为什么
/ipc/glue/ProcessUtils_linux.cpp:618, Fuc:ProcLoaderServiceRun call -- process = new ContentProcess(aPeerPid); --->
/ipc/glue/ProcessChild.cpp:46, Fuc:ProcessChild >>>>>>>>>>>>>>>>>>>>>>>>>>>st.func//进入ProcessChild
。。。与b2g process 创建连接
/ipc/glue/ProcessChild.cpp:47, Fuc:ProcessChild init with-- ProcessChild::ProcessChild(ProcessId aParentPid) : ChildProcess(new IOThreadChild()) , mUILoop(MessageLoop::current()) , mParentPid(aParentPid) --- 为子进程创建io子线程,创建uiloop消息循环线程?
/ipc/glue/ProcessUtils_linux.cpp:620, Fuc:ProcLoaderServiceRun call -- ChildThread *iothread = process->child_thread(); --->//调用子线程?
/ipc/glue/ProcessUtils_linux.cpp:623, Fuc:ProcLoaderServiceRun call -- Transport *transport = OpenDescriptor(fd, Transport::MODE_CLIENT); --->//打开文件描述符(与b2g打开的相同,实现传输?),MODE_CLIENT方式???传输部分?进程间??
/ipc/glue/ProcessUtils_linux.cpp:625, Fuc:ProcLoaderServiceRun new ProcLoaderChild(aPeerPid:180)--->
/ipc/glue/ProcessUtils_linux.cpp:626, Fuc:ProcLoaderServiceRun call -- ProcLoaderChild *loaderChild = new ProcLoaderChild(aPeerPid); --->//创建loaderChild, Pass a message loop to initialize (connect) the channel // (connection). 下面的open发一个messageloop去建立连接通道,因为上面已经指定了进程号和文件描述符,使建立连接通道,接着nuwa这侧就在等load信号了
/ipc/glue/ProcessUtils_linux.cpp:630, Fuc:ProcLoaderServiceRun loaderChild->Open(transport, aPeerPid, iothread->message_loop())//进行传输,与b2g进程,并启动它的其中一个子线程用于messageloop,消息队列循环,ipdl的open,线程间相互传消息
/ipc/glue/ProcessUtils_linux.cpp:632, Fuc:ProcLoaderServiceRun call BackgroundHangMonitor::Prohibit()--->//禁止后台挂起
/ipc/glue/ProcessUtils_linux.cpp:636, Fuc:ProcLoaderServiceRun call loop.Run--->//loop 循环,等待b2g的load 请求
//不知为何就开始recvload了,获得了,b2g 端以及发请求,详见交互部分log:
等待。等待。等待。
673, Fuc:XRE_GetIOMessageLoop ----------------------------------//b2g 那边的循环突然来了,那边已经appStartup->Run了 此为b2g的log
ProcessUtils_linux.cpp:521, Fuc:RecvLoad ----------------------------------//谁调了它,接收到调用请求
ProcessUtils_linux.cpp:522, Fuc:RecvLoad ############this func RecvLoad(),called by objdir-gecko/ipc/ipdl/PProcLoaderChild.cpp ################
ProcessUtils_linux.cpp:523, Fuc:RecvLoad call -- if ((!(RecvLoad(mozilla::Move(argv), mozilla::Move(env), mozilla::Move(fdsRemap), mozilla::Move(privs), mozilla::Move(cookie))))) { --->
ProcessUtils_linux.cpp:529, Fuc:RecvLoad call -- sProcLoaderDispatchedTask = new ProcLoaderLoadRunner(aArgv, aEnv, aFdsRemap, privs); ---> 创建进程加载调度任务,ProcLoaderLoadRunner
ProcessUtils_linux.cpp:532, Fuc:RecvLoad call -- SendLoadComplete(mPeerPid:181, aCookie); --->发送完整的加载指令,发给b2g???
ProcessUtils_linux.cpp:535, Fuc:RecvLoad call -- MessageLoop::current()->PostTask(FROM_HERE, NewRunnableFunction(_ProcLoaderChildDestroy, this)); --->消息队列MessageLoop::current添加任务
ProcessUtils_linux.cpp:639, Fuc:ProcLoaderServiceRun call BackgroundHangMonitor::Allow()--->允许线程挂起,后台线程监控允许
ProcessUtils_linux.cpp:641, Fuc:ProcLoaderServiceRun call XRE_DeinitCommandLine--->反初始化CommandLine释放相关资源
ProcessUtils_linux.cpp:648, Fuc:ProcLoaderServiceRun call task->DoWork()--->任务开始工作
ProcessUtils_linux.cpp:451, Fuc:DoWork ----------------------------------
ProcessUtils_linux.cpp:467, Fuc:DoWork call SetCurrentProcessPrivileges(mPrivs)---> 设置进程特性
ProcessUtils_linux.cpp:471, Fuc:DoWork Start Nuwa (main function),call int ret = content_process_main(argc, argv)--->调content_process_main真正创建出一个进程
pp:182, Fuc:content_process_main ----------------------------------
pp:214, Fuc:content_process_main XRE_SetProcessType(argv[--argc])--> 设置进程类型
pp:219, Fuc:content_process_main isNuwa=true, PrepareNuwaProcess()-->是Nuwa进程,则准备启动nuwa进程
pp:245, Fuc:content_process_main isNuwa=true, NuwaAddFinalConstructor(&InitializeBinder, nullptr)添加nuwa的最后构造者,初始化binder等
pp:274, Fuc:content_process_main *** nsresult rv = XRE_InitChildProcess(argc, argv, loader)--> 初始化子进程(此时是否已经出来新进程了)需要看到新的进程号
329, Fuc:XRE_InitChildProcess ---------------------------------- 467, Fuc:XRE_InitChildProcess defined MOZ_CRASHREPORTER
开始重复b2g里的那套
nuwa是b2g的复制???
556, Fuc:XRE_InitChildProcess nsresult rv = XRE_InitCommandLine(aArgc, aArgv)-->又重复,初始化命令行
Fuc:XRE_InitCommandLine ----------------------------------
Fuc:XRE_InitCommandLine XRE_GetBinaryPath(aArgv:/system/b2g/plugin-container)--->获取二进制文件地址
Fuc:XRE_InitCommandLine mozilla::Omnijar::Init(greOmni, appOmni)-->将omni文件传入,Omnijar::Init初始化
565, Fuc:XRE_InitChildProcess switch (XRE_GetProcessType())--> 获取进程类型
ProcessChild.cpp:46, Fuc:ProcessChild >>>>>>>>>>>>>>>>>>>>>>>>>>>st.func ProcessChild.cpp:47, Fuc:ProcessChild init with-- ProcessChild::ProcessChild(ProcessId aParentPid) : ChildProcess(new IOThreadChild()) , mUILoop(MessageLoop::current()) , mParentPid(aParentPid) --- 初始化子进程启动子进程的io子线程,uiloop等,只有nuwa进程需要吗???
ScopedXREEmbed.cpp:59, Fuc:SetAppDir ----------------------------------
.cpp:108, Fuc:Init ----------------------------------初始化
.cpp:109, Fuc:Init call -- mContent.Init(IOThreadChild::message_loop(), ParentPid(), IOThreadChild::channel()); --->对content进行初始化,传入io子线程的消息队列循环,父进程PID,io线程的通道对content进程进行初始化
.cpp:113, Fuc:Init call -- mXREEmbed.Start(); --->开始嵌入?
ScopedXREEmbed.cpp:73, Fuc:Start ----------------------------------
ScopedXREEmbed.cpp:89, Fuc:Start rv = localFile->GetParent(getter_AddRefs(parent)-->获取父类的什么?
ScopedXREEmbed.cpp:93, Fuc:Start localFile = do_QueryInterface(parent)-->本地文件??
ScopedXREEmbed.cpp:130, Fuc:Start mAppDir = true,call rv = XRE_InitEmbedding2(localFile, mAppDir, nullptr)-->传入本地文件以及APP目录开始着床进程???
172, Fuc:XRE_InitEmbedding2 ----------------------------------
nuwa这一线下来是完成对自己的初始化和各功能块拉起?
192, Fuc:XRE_InitEmbedding2 call -- rv = gDirServiceProvider->Initialize(aAppDirectory, aLibXULDirectory, --->目录服务初始化
197, Fuc:XRE_InitEmbedding2 rv = NS_InitXPCOM2(nullptr, aAppDirectory, gDirServiceProvider)-->又开始初始化xpcom???
XPCOMInit.cpp:513, Fuc:NS_InitXPCOM2 ----------------------------------
XPCOMInit.cpp:514, Fuc:NS_InitXPCOM2 ###################basic part of nuwa and b2g proc start ######################
XPCOMInit.cpp:517, Fuc:NS_InitXPCOM2 call -- if (sInitialized) { --->
XPCOMInit.cpp:525, Fuc:NS_InitXPCOM2 call -- mozPoisonValueInit(); --->
XPCOMInit.cpp:563, Fuc:NS_InitXPCOM2 ###################basic part of nuwa and b2g proc end ######################
XPCOMInit.cpp:565, Fuc:NS_InitXPCOM2 call -- if (!MessageLoop::current()) {//when nuwa then will not come in for loop = true --->专门给b2g的
XPCOMInit.cpp:577, Fuc:NS_InitXPCOM2 if (XRE_IsParentProcess() && !BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)) = ?? 也不是nuwa 的菜
XPCOMInit.cpp:597, Fuc:NS_InitXPCOM2 ##############nuwa jump here directly from basic for b2g and nuwa part #######################
XPCOMInit.cpp:599, Fuc:NS_InitXPCOM2 Establish the main thread here. 创建主线程(每个进程自己的主线程?)
XPCOMInit.cpp:600, Fuc:NS_InitXPCOM2 call -- rv = nsThreadManager::get()->Init(); --->线程管理器获取并初始化线程
XPCOMInit.cpp:606, Fuc:NS_InitXPCOM2 call -- // Set up the timer globals/timer thread --->设置timer 全局线程
XPCOMInit.cpp:608, Fuc:NS_InitXPCOM2 call -- rv = nsTimerImpl::Startup(); --->
XPCOMInit.cpp:625, Fuc:NS_InitXPCOM2 call -- NS_StartupLocalFile(); --->
XPCOMInit.cpp:628, Fuc:NS_InitXPCOM2 call -- StartupSpecialSystemDirectory(); --->
XPCOMInit.cpp:631, Fuc:NS_InitXPCOM2 call -- nsDirectoryService::RealInit(); --->目录服务真正启动?
XPCOMInit.cpp:637, Fuc:NS_InitXPCOM2 call -- if (aBinDirectory) { --->
XPCOMInit.cpp:640, Fuc:NS_InitXPCOM2 call -- nsDirectoryService::gService->Set(NS_XPCOM_INIT_CURRENT_PROCESS_DIR, --->初始化当前进程的目录(proc目录下的那些??)
XPCOMInit.cpp:647, Fuc:NS_InitXPCOM2 aAppFileLocationProvider = true,call RegisterProvider()-->调用注册
XPCOMInit.cpp:655, Fuc:NS_InitXPCOM2 call -- nsDirectoryService::gService->Get(NS_GRE_BIN_DIR, --->
XPCOMInit.cpp:663, Fuc:NS_InitXPCOM2 call -- xpcomLib->GetPath(path); --->xpcomLib获取路径
XPCOMInit.cpp:667, Fuc:NS_InitXPCOM2 call -- xpcomLib->AppendNative(nsDependentCString(XPCOM_DLL)); --->
XPCOMInit.cpp:669, Fuc:NS_InitXPCOM2 call -- nsDirectoryService::gService->Set(NS_XPCOM_LIBRARY_FILE, xpcomLib); --->
XPCOMInit.cpp:672, Fuc:NS_InitXPCOM2 call -- if (!mozilla::Omnijar::IsInitialized()) { --->看omnijar有没有初始化,没有初始化则会中断?
XPCOMInit.cpp:714, Fuc:NS_InitXPCOM2 Create the Component/Service Manage----创建组件服务管理器
XPCOMInit.cpp:715, Fuc:NS_InitXPCOM2 call -- nsComponentManagerImpl::gComponentManager = new nsComponentManagerImpl(); --->
XPCOMInit.cpp:720, Fuc:NS_InitXPCOM2 call -- // Global cycle collector initialization. --->全局循环收集器初始化,负责它自己的线程?
XPCOMInit.cpp:721, Fuc:NS_InitXPCOM2 call -- if (!nsCycleCollector_init()) { --->
XPCOMInit.cpp:726, Fuc:NS_InitXPCOM2 call -- // And start it up for this thread too. --->
XPCOMInit.cpp:728, Fuc:NS_InitXPCOM2 call -- nsCycleCollector_startup(); --->全局循环收集器启动,为此线程
XPCOMInit.cpp:737, Fuc:NS_InitXPCOM2 call -- mozilla::SetICUMemoryFunctions(); --->
XPCOMInit.cpp:766, Fuc:NS_InitXPCOM2 ----- Initialize the JS engine -----初始化js引擎,应该不做了,在b2g里已经搞定?
XPCOMInit.cpp:767, Fuc:NS_InitXPCOM2 if (!JS_Init()),call JS_Init()--->继续log看
XPCOMInit.cpp:772, Fuc:NS_InitXPCOM2 call -- rv = nsComponentManagerImpl::gComponentManager->Init(); --->组件管理器初始化并启动
ntManager.cpp:400, Fuc:Init ----------------------------------
ntManager.cpp:444, Fuc:Init call -- InitializeModuleLocations(); --->组件管理器加载相关app??
ntManager.cpp:452, Fuc:Init call -- RefPtr<nsZipArchive> greOmnijar = mozilla::Omnijar::GetReader(mozilla::Omnijar::GRE); --->
ntManager.cpp:458, Fuc:Init call -- cl->location.Init(greOmnijar, 'chrome.manifest'); --->
ntManager.cpp:471, Fuc:Init call -- RefPtr<nsZipArchive> appOmnijar = mozilla::Omnijar::GetReader(mozilla::Omnijar::APP); --->
ntManager.cpp:481, Fuc:Init call -- RereadChromeManifests(false); --->读取清单文件??不读?
ntManager.cpp:878, Fuc:RereadChromeManifests ----------------------------------
ntManager.cpp:484, Fuc:Init call -- nsCategoryManager::GetSingleton()->SuppressNotifications(false); ---> 673, Fuc:XRE_GetIOMessageLoop ----------------------------------
678, Fuc:XRE_GetIOMessageLoop call -- return IOThreadChild::message_loop(); --->
XPCOMInit.cpp:789, Fuc:NS_InitXPCOM2 The iimanager constructor searches and registers XPT files.---
XPCOMInit.cpp:790, Fuc:NS_InitXPCOM2 call -- (void)XPTInterfaceInfoManager::GetSingleton(); --->
XPCOMInit.cpp:793, Fuc:NS_InitXPCOM2 call -- // After autoreg, but before we actually instantiate any components, // add any services listed in the 'xpcom-directory-providers' category // to the directory service. --->自动注册组件??
XPCOMInit.cpp:797, Fuc:NS_InitXPCOM2 nsDirectoryService::gService->RegisterCategoryProviders()-->
ntManager.cpp:173, Fuc:operator() ----------------------------------
XPCOMInit.cpp:800, Fuc:NS_InitXPCOM2 call -- // Init SharedThreadPool (which needs the service manager). --->
XPCOMInit.cpp:802, Fuc:NS_InitXPCOM2 call -- SharedThreadPool::InitStatics(); --->共享线程
XPCOMInit.cpp:806, Fuc:NS_InitXPCOM2 call -- AbstractThread::InitStatics(); --->抽象线程
XPCOMInit.cpp:811, Fuc:NS_InitXPCOM2 do_GetService of jsloader----获取jsloader加载器
XPCOMInit.cpp:812, Fuc:NS_InitXPCOM2 componentLoader = do_GetService('@mozilla.org/moz/jsloader;1')--->
XPCOMInit.cpp:820, Fuc:NS_InitXPCOM2 // Notify observers of xpcom autoregistration star//
XPCOMInit.cpp:821, Fuc:NS_InitXPCOM2 NS_CreateServicesFromCategory(NS_XPCOM_STARTUP_CATEGORY,nullptr,NS_XPCOM_STARTUP_OBSERVER_ID) --->通知自动注册,为什么多次注册,继续Log
XPCOMInit.cpp:832, Fuc:NS_InitXPCOM2 call -- if (XRE_IsParentProcess()) { --->,true will enter
XPCOMInit.cpp:838, Fuc:NS_InitXPCOM2 call -- // The memory reporter manager is up and running -- register our reporters. --->
XPCOMInit.cpp:840, Fuc:NS_InitXPCOM2 call -- RegisterStrongMemoryReporter(new ICUReporter()); --->
XPCOMInit.cpp:850, Fuc:NS_InitXPCOM2 call -- mozilla::Telemetry::Init(); --->
XPCOMInit.cpp:852, Fuc:NS_InitXPCOM2 call -- mozilla::HangMonitor::Startup(); --->后台线程管理相关
XPCOMInit.cpp:854, Fuc:NS_InitXPCOM2 call -- mozilla::BackgroundHangMonitor::Startup(); --->
XPCOMInit.cpp:856, Fuc:NS_InitXPCOM2 call -- const MessageLoop* const loop = MessageLoop::current(); --->
XPCOMInit.cpp:858, Fuc:NS_InitXPCOM2 call -- sMainHangMonitor = new mozilla::BackgroundHangMonitor( loop->thread_name().c_str(), loop->transient_hang_timeout(), loop->permanent_hang_timeout()); --->
213, Fuc:XRE_InitEmbedding2 call -- startupNotifier->Observe(nullptr, APPSTARTUP_TOPIC, nullptr); --->启动通知器
.cpp:115, Fuc:Init call -- mContent.InitXPCOM(); --->又来了,怎么回事?不一样吧
.cpp:117, Fuc:Init call -- mContent.InitGraphicsDeviceData(); --->mcontent初始化xpcom和图像设备数据????
653, Fuc:XRE_InitChildProcess uiMessageLoop.MessageLoop::Run()-->启动界面消息队列循环,开始有真正界面了是吗??? 673, Fuc:XRE_GetIOMessageLoop ----------------------------------
678, Fuc:XRE_GetIOMessageLoop call -- return IOThreadChild::message_loop(); --->
673, Fuc:XRE_GetIOMessageLoop ----------------------------------
678, Fuc:XRE_GetIOMessageLoop call -- return IOThreadChild::message_loop(); --->
673, Fuc:XRE_GetIOMessageLoop ----------------------------------
678, Fuc:XRE_GetIOMessageLoop call -- return IOThreadChild::message_loop(); --->
XPCOMInit.cpp:272, Fuc:nsThreadManagerGetSingleton call -- return nsThreadManager::get()->QueryInterface(aIID, aInstancePtr); --->猜想:nuwa进程获取界面调用消息?返回
omponents/startup/nsAppStartup.cpp:172, Fuc:nsAppStartup ----------------------------------谁调了它
omponents/startup/nsAppStartup.cpp:179, Fuc:Init ----------------------------------
omponents/startup/nsAppStartup.cpp:185, Fuc:Init nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService() 获取监听服务
omponents/startup/nsAppStartup.cpp:190, Fuc:Init os->AddObserver(this, 'quit-application.........', true)获取到退出应用的消息 673, Fuc:XRE_GetIOMessageLoop ----------------------------------
678, Fuc:XRE_GetIOMessageLoop call -- return IOThreadChild::message_loop(); --->
673, Fuc:XRE_GetIOMessageLoop ----------------------------------
678, Fuc:XRE_GetIOMessageLoop call -- return IOThreadChild::message_loop(); --->
:673, Fuc:XRE_GetIOMessageLoop ----------------------------------
:678, Fuc:XRE_GetIOMessageLoop call -- return IOThreadChild::message_loop(); --->
|
b2g 叫相关模块Load nuwa 以及之后,混杂b2g 和nuwa 进程
。。。
Fuc:XRE_mainRun call -- appStartup->GetShuttingDown(&mShuttingDown); --->
omponents/startup/nsAppStartup.cpp:574, Fuc:GetShuttingDown ----------------------------------
Fuc:XRE_mainRun call -- if (PR_GetEnv('MOZ_INSTRUMENT_EVENT_LOOP')) { --->
Fuc:XRE_mainRun call -- rv = appStartup->Run(); --->
omponents/startup/nsAppStartup.cpp:295, Fuc:Run ----------------------------------
omponents/startup/nsAppStartup.cpp:309, Fuc:Run call nsresult rv = mAppShell->Run()--->
essHost.cpp:448, Fuc:LaunchAndWaitForProcessHandle call -- PrepareLaunch(); --->
essHost.cpp:451, Fuc:LaunchAndWaitForProcessHandle call -- MessageLoop* ioLoop = XRE_GetIOMessageLoop(); --->不是后台的那个loop,是这里往io里写东西,然后nuwa的ioloop 接收到?XRE_GetIOMessageLoop都在b2g进程中,APP也会发吗?谁激发b2g,启动的load信号
673, Fuc:XRE_GetIOMessageLoop ----------------------------------
Fuc:XRE_GetIOMessageLoop return BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)
ost.cpp:470, Fuc:InitializeChannel call -- CreateChannel(); --->
essUtils_linux.cpp:322, Fuc:ProcLoaderLoad ----------------------------------//一直循环,等待postTask任务
essUtils_linux.cpp:323, Fuc:ProcLoaderLoad call -- * Request the loader service, the server, to load Nuwa. ---> essUtils_linux.cpp:352, Fuc:ProcLoaderLoad sProcLoaderLoop->PostTask(FROM_HERE, NewRunnableFunction(AsyncSendLoad, load))-->
Fuc:XRE_GetIOMessageLoop ----------------------------------
Fuc:XRE_GetIOMessageLoop return BrowserProcessSubThread::GetMessageLoop(BrowserProcessSubThread::IO)
以上为b2g 部分,此时才开始叫相关模块拉起nuwa来,此时b2g实际已经完成了哪些工作呢?
已经完成xpcom的启动,开始调用XRE_mainRun(),并已经到appStartup->Run部分,要真正启动"app"了,nuwa就是第一个应用??然后用它孵化出其他app(具体的)???
在appStartup->Run部分load nuwa
以下是nuwa部分log
接收到加载的信号,,开始进行相关加载任务:
essUtils_linux.cpp:521, Fuc:RecvLoad ----------------------------------
essUtils_linux.cpp:529, Fuc:RecvLoad call -- sProcLoaderDispatchedTask = new ProcLoaderLoadRunner(aArgv, aEnv, aFdsRemap, privs); --->
essUtils_linux.cpp:532, Fuc:RecvLoad call -- SendLoadComplete(mPeerPid, aCookie); --->
essUtils_linux.cpp:535, Fuc:RecvLoad call -- MessageLoop::current()->PostTask(FROM_HERE, NewRunnableFunction(_ProcLoaderChildDestroy, this)); --->
essUtils_linux.cpp:639, Fuc:ProcLoaderServiceRun call BackgroundHangMonitor::Allow()--->
essUtils_linux.cpp:641, Fuc:ProcLoaderServiceRun call XRE_DeinitCommandLine--->
essUtils_linux.cpp:648, Fuc:ProcLoaderServiceRun call task->DoWork()--->
essUtils_linux.cpp:451, Fuc:DoWork ----------------------------------
essUtils_linux.cpp:467, Fuc:DoWork call SetCurrentProcessPrivileges(mPrivs)--->
essUtils_linux.cpp:471, Fuc:DoWork Start Nuwa (main function),call int ret = content_process_main(argc, argv)--->
82, Fuc:content_process_main ----------------------------------
14, Fuc:content_process_main XRE_SetProcessType(argv[--argc])-->
19, Fuc:content_process_main isNuwa=true, PrepareNuwaProcess()-->
45, Fuc:content_process_main isNuwa=true, NuwaAddFinalConstructor(&InitializeBinder, nullptr)
74, Fuc:content_process_main *** nsresult rv = XRE_InitChildProcess(argc, argv, loader)-->
Fuc:XRE_InitChildProcess ----------------------------------
Fuc:XRE_InitChildProcess defined MOZ_CRASHREPORTER
Fuc:XRE_InitChildProcess nsresult rv = XRE_InitCommandLine(aArgc, aArgv)-->
:XRE_InitCommandLine ----------------------------------
...
|
两进程交互部分:
RunProcesses -> XRE_ProcLoaderClientInit--->//初始化client端,传入nuwa进程的pid,fd,parent sock等
在前面初始化client的时候,ProcLoaderClientInit sProcLoaderPid:530,sProcLoaderChannelFd:13,sProcLoaderClientInitialized:true
这里搞定之后就开始进入b2g_main了,
与上层应用联系的地方?gecko/widget/gonk/nsAppShell.cpp
进程间:
#include "mozilla/ipc/PProcLoaderParent.h"
#include "mozilla/ipc/PProcLoaderChild.h"
gecko/ipc/glue/ProcessUtils_linux.cpp
/**
* Initialize the client of B2G loader for loader itself.
*
* The initialization of B2G loader are divided into two stages. First
* stage is to collect child info passed from the main program of the
* loader. Second stage is to initialize Gecko according to info from the
* first stage and make the client of loader service ready.
*
* \param aPeerPid is the pid of the child.
* \param aChannelFd is the file descriptor of the socket used for IPC.
*/
static void
ProcLoaderClientInit(pid_t aPeerPid, int aChannelFd)
{
P_LOGI(SEPARATOR_LINE );
MOZ_ASSERT(!sProcLoaderClientInitialized, "call ProcLoaderClientInit() more than once");
MOZ_ASSERT(aPeerPid != 0 && aChannelFd != -1, "invalid argument");
sProcLoaderPid = aPeerPid;
sProcLoaderChannelFd = aChannelFd;
sProcLoaderClientInitialized = true;
P_LOGI("sProcLoaderPid:%d,sProcLoaderChannelFd:%d,sProcLoaderClientInitialized:true",sProcLoaderPid,sProcLoaderChannelFd);
}
/**
* Initialize the client of B2G loader for Gecko.
*/
void
ProcLoaderClientGeckoInit()
{
P_LOGI(SEPARATOR_LINE );
MOZ_ASSERT(sProcLoaderClientInitialized, "call ProcLoaderClientInit() at first");
MOZ_ASSERT(!sProcLoaderClientGeckoInitialized,
"call ProcLoaderClientGeckoInit() more than once");
if (!Preferences::GetBool("dom.ipc.processPrelaunch.enabled", false)) {
P_LOGI(" call kill(sProcLoaderPid, SIGKILL)");
kill(sProcLoaderPid, SIGKILL);
sProcLoaderPid = 0;
close(sProcLoaderChannelFd);
sProcLoaderChannelFd = -1;
return;
}
sProcLoaderClientGeckoInitialized = true;
TransportDescriptor fd;
fd.mFd = base::FileDescriptor(sProcLoaderChannelFd, /*auto_close=*/ false);
sProcLoaderChannelFd = -1;
Transport *transport = OpenDescriptor(fd, Transport::MODE_CLIENT);
P_LOGI(" sProcLoaderParent = new ProcLoaderParent()");
sProcLoaderParent = new ProcLoaderParent();
P_LOGI("sProcLoaderParent->Open(transport,sProcLoaderPid,XRE_GetIOMessageLoop(),ParentSide) ");
sProcLoaderParent->Open(transport,
sProcLoaderPid,
XRE_GetIOMessageLoop(),
ParentSide);
P_LOGI("call sProcLoaderLoop = MessageLoop::current()--->");
sProcLoaderLoop = MessageLoop::current();
}
/**
* Request the loader service, the server, to load Nuwa.
*/
bool
ProcLoaderLoad(const char *aArgv[],
const char *aEnvp[],
const file_handle_mapping_vector &aFdsRemap,
const ChildPrivileges aPrivs,
ProcessHandle *aProcessHandle)
{
P_LOGI(SEPARATOR_LINE );
static int cookie=0;
int i;
if (sProcLoaderParent == nullptr || sProcLoaderPid == 0) {
return false;
}
AsyncSendLoadData *load = new AsyncSendLoadData();
nsTArray<nsCString> &argv = load->mArgv;
for (i = 0; aArgv[i] != nullptr; i++) {
argv.AppendElement(nsCString(aArgv[i]));
}
nsTArray<nsCString> &env = load->mEnv;
for (i = 0; aEnvp[i] != nullptr; i++) {
env.AppendElement(nsCString(aEnvp[i]));
}
nsTArray<FDRemap> &fdsremap = load->mFdsremap;
for (file_handle_mapping_vector::const_iterator fdmap =
aFdsRemap.begin();
fdmap != aFdsRemap.end();
fdmap++) {
fdsremap.AppendElement(FDRemap(FileDescriptor(fdmap->first), fdmap->second));
}
load->mPrivs = aPrivs;
load->mCookie = cookie++;
*aProcessHandle = sProcLoaderPid;
sProcLoaderPid = 0;
sProcLoaderLoop->PostTask(FROM_HERE,
NewRunnableFunction(AsyncSendLoad, load));
return true;
}
/**
* Run service of ProcLoader.
*
* \param aPeerPid is the pid of the parent.
* \param aFd is the file descriptor of the socket for IPC.
*
* See the comment near the head of this file.
*/
static int
ProcLoaderServiceRun(pid_t aPeerPid, int aFd,
int aArgc, const char *aArgv[],
FdArray& aReservedFds)
{
P_LOGI(SEPARATOR_LINE );
// Make a copy of aReservedFds. It will be used when we dup() the magic file
// descriptors when ProcLoaderChild::RecvLoad() runs.
sReservedFds = MakeUnique<FdArray>(mozilla::Move(aReservedFds));
ScopedLogging logging;
char **_argv;
_argv = new char *[aArgc + 1];
for (int i = 0; i < aArgc; i++) {
_argv[i] = ::strdup(aArgv[i]);
P_LOGI("aArgv[i]:%s",_argv[i]);
MOZ_ASSERT(_argv[i] != nullptr);
}
_argv[aArgc] = nullptr;
gArgv = _argv;
gArgc = aArgc;
{
P_LOGI("call XRE_InitCommandLine--->");
nsresult rv = XRE_InitCommandLine(aArgc, _argv);
if (NS_FAILED(rv)) {
MOZ_CRASH();
}
TransportDescriptor fd;
fd.mFd = base::FileDescriptor(aFd, /*auto_close =*/false);
MOZ_ASSERT(!sProcLoaderServing);
MessageLoop loop;
nsAutoPtr<ContentProcess> process;
P_LOGI("new ContentProcess(aPeerPid:%d)--->",aPeerPid);
process = new ContentProcess(aPeerPid);
ChildThread *iothread = process->child_thread();
Transport *transport = OpenDescriptor(fd, Transport::MODE_CLIENT);
P_LOGI("new ProcLoaderChild(aPeerPid:%d)--->",aPeerPid);
ProcLoaderChild *loaderChild = new ProcLoaderChild(aPeerPid);
// Pass a message loop to initialize (connect) the channel
// (connection).
P_LOGI(" loaderChild->Open(transport, aPeerPid, iothread->message_loop())");
loaderChild->Open(transport, aPeerPid, iothread->message_loop());
P_LOGI("call BackgroundHangMonitor::Prohibit()--->");
BackgroundHangMonitor::Prohibit();
sProcLoaderServing = true;
P_LOGI("call loop.Run--->");
loop.Run();
P_LOGI("call BackgroundHangMonitor::Allow()--->");
BackgroundHangMonitor::Allow();
P_LOGI("call XRE_DeinitCommandLine--->");
XRE_DeinitCommandLine();
}
MOZ_ASSERT(sProcLoaderDispatchedTask != nullptr);
ProcLoaderRunnerBase *task = sProcLoaderDispatchedTask;
sProcLoaderDispatchedTask = nullptr;
P_LOGI("call task->DoWork()--->");
int ret = task->DoWork();
delete task;
for (int i = 0; i < aArgc; i++) {
free(_argv[i]);
}
delete[] _argv;
return ret;
}
#ifdef MOZ_B2G_LOADER
void
XRE_ProcLoaderClientInit(pid_t aPeerPid, int aChannelFd, FdArray& aReservedFds)
{
P_LOGI(SEPARATOR_LINE );
// We already performed fork(). It's safe to free the "danger zone" of file
// descriptors .
mozilla::ipc::CloseFileDescriptors(aReservedFds);
P_LOGI(".==b2g process==. XRE_ProcLoaderClientInit call mozilla::ipc::ProcLoaderClientInit(aPeerPid:%d, aChannelFd:%d)",aPeerPid, aChannelFd);
mozilla::ipc::ProcLoaderClientInit(aPeerPid, aChannelFd);
}
int
XRE_ProcLoaderServiceRun(pid_t aPeerPid, int aFd,
int aArgc, const char *aArgv[],
FdArray& aReservedFds)
{
P_LOGI(SEPARATOR_LINE );
P_LOGI(".==nuwa process==. XRE_ProcLoaderServiceRun call mozilla::ipc::ProcLoaderServiceRun(aPeerPid:%d, aFd:%d,aArgc:%d, aArgv[...0]:%s,aReservedFds[...0]:%d)",aPeerPid, aFd,aArgc, aArgv[0],aReservedFds[0]);
return mozilla::ipc::ProcLoaderServiceRun(aPeerPid, aFd,
aArgc, aArgv,
aReservedFds);
}
#endif /* MOZ_B2G_LOADER */
/**
* Run service of ProcLoader.
*
* \param aPeerPid is the pid of the parent.
* \param aFd is the file descriptor of the socket for IPC.
*
* See the comment near the head of this file.
*/
static int
ProcLoaderServiceRun(pid_t aPeerPid, int aFd,
int aArgc, const char *aArgv[],
FdArray& aReservedFds)
{
P_LOGI(SEPARATOR_LINE );
// Make a copy of aReservedFds. It will be used when we dup() the magic file
// descriptors when ProcLoaderChild::RecvLoad() runs.
sReservedFds = MakeUnique<FdArray>(mozilla::Move(aReservedFds));
ScopedLogging logging;
char **_argv;
_argv = new char *[aArgc + 1];
for (int i = 0; i < aArgc; i++) {
_argv[i] = ::strdup(aArgv[i]);
P_LOGI("aArgv[i]:%s",_argv[i]);
MOZ_ASSERT(_argv[i] != nullptr);
}
_argv[aArgc] = nullptr;
gArgv = _argv;
gArgc = aArgc;
{
P_LOGI("call XRE_InitCommandLine--->");
nsresult rv = XRE_InitCommandLine(aArgc, _argv);
if (NS_FAILED(rv)) {
MOZ_CRASH();
}
TransportDescriptor fd;
fd.mFd = base::FileDescriptor(aFd, /*auto_close =*/false);
MOZ_ASSERT(!sProcLoaderServing);
MessageLoop loop;
nsAutoPtr<ContentProcess> process;
P_LOGI("new ContentProcess(aPeerPid:%d)--->",aPeerPid);
process = new ContentProcess(aPeerPid);
ChildThread *iothread = process->child_thread();
Transport *transport = OpenDescriptor(fd, Transport::MODE_CLIENT);
P_LOGI("new ProcLoaderChild(aPeerPid:%d)--->",aPeerPid);
ProcLoaderChild *loaderChild = new ProcLoaderChild(aPeerPid);
// Pass a message loop to initialize (connect) the channel
// (connection).
P_LOGI(" loaderChild->Open(transport, aPeerPid, iothread->message_loop())");
loaderChild->Open(transport, aPeerPid, iothread->message_loop());
P_LOGI("call BackgroundHangMonitor::Prohibit()--->");
BackgroundHangMonitor::Prohibit();
sProcLoaderServing = true;
P_LOGI("call loop.Run--->");
loop.Run();
P_LOGI("call BackgroundHangMonitor::Allow()--->");
BackgroundHangMonitor::Allow();
P_LOGI("call XRE_DeinitCommandLine--->");
XRE_DeinitCommandLine();
}
MOZ_ASSERT(sProcLoaderDispatchedTask != nullptr);
ProcLoaderRunnerBase *task = sProcLoaderDispatchedTask;
sProcLoaderDispatchedTask = nullptr;
P_LOGI("call task->DoWork()--->");
int ret = task->DoWork();
delete task;
for (int i = 0; i < aArgc; i++) {
free(_argv[i]);
}
delete[] _argv;
return ret;
}
processchild:
gecko/ipc/glue/ProcessChild.cpp
ProcessChild::ProcessChild(ProcessId aParentPid)
: ChildProcess(new IOThreadChild())
, mUILoop(MessageLoop::current())
, mParentPid(aParentPid)
{
P_LOGI(STA_LINE);
//P_LOGI("ProcessId:%d aParentPid:%d",ProcessId, aParentPid);
MOZ_ASSERT(mUILoop, "UILoop should be created by now");
MOZ_ASSERT(!gProcessChild, "should only be one ProcessChild");
gProcessChild = this;
}