Line 1: |
Line 1: |
− | PGL (Program Loader) is a sysmodule designed for encapsulating all program loading logic. | + | PGL (Program Launcher) is a sysmodule designed for encapsulating all program launching / management logic. |
| + | |
| + | The core logic of this sysmodule was previously encapsulated by the ns:dev interface (and the nn.nssrv.ProcessLaunchControlTask thread in particular). |
| | | |
| = pgl = | | = pgl = |
Line 14: |
Line 16: |
| | 4 || [[#GetHostContentMetaInfo]] | | | 4 || [[#GetHostContentMetaInfo]] |
| |- | | |- |
− | | 5 || | + | | 5 || [[#GetApplicationProcessId]] |
| |- | | |- |
− | | 6 || | + | | 6 || [[#BoostSystemMemoryResourceLimit]] |
| |- | | |- |
− | | 7 || | + | | 7 || [[#IsProcessTracked]] |
| |- | | |- |
− | | 8 || | + | | 8 || [[#EnableApplicationCrashReport]] |
| |- | | |- |
− | | 9 || | + | | 9 || [[#IsApplicationCrashReportEnabled]] |
| |- | | |- |
− | | 10 || | + | | 10 || [[#EnableApplicationAllThreadDumpOnCrash]] |
| |- | | |- |
− | | 12 || | + | | 12 || [[#TriggerSnapShotDumper]] |
| |- | | |- |
− | | 20 || [[#GetEventObserver]] | + | | 20 || [[#GetShellEventObserver]] |
| + | |- |
| + | | 21 || [11.0.0-11.0.1] |
| |} | | |} |
| | | |
− | = LaunchFlags = | + | == LaunchProgram == |
| + | Takes a [[NCM_services#ProgramLocation|ProgramLocation]], a u32 [[Process_Manager_services#LaunchFlags]] pm launch_flags, and a u8 [[#LaunchFlags|LaunchFlags]] pgl launch_flags. |
| + | |
| + | This calls pm:shell->LaunchProgram with the program location and the input launch flags. If jit_debug!enable_jit_debug is true, LaunchFlags_SignalOnCrash is ORRd into the flags sent to PM. |
| + | |
| + | This then creates a new process tracking structure for the new process id and with the pgl launch flags. If an empty process struct is not allocated from the 0x20 slab heap, pgl aborts. |
| + | |
| + | If settings::GetDebugModeFlag() returns 1, then LaunchFlags_EnableCrashReportScreenShotForDevelop is used to enable crash report screenshot, otherwise LaunchFlags_EnableCrashReportScreenShotForProduction is used. |
| + | |
| + | It returns a u64 process id. |
| + | |
| + | == TerminateProcess == |
| + | This just calls pm:shell->TerminateProcess with the input process id. |
| + | |
| + | == GetShellEventObserver == |
| + | No input. Returns an [[#IEventObserver]]. |
| + | |
| + | == LaunchProgramFromHost == |
| + | This takes an input u32 [[Process_Manager_services#LaunchFlags]] pm launch_flags and a MapAlias input buffer "content path". |
| + | |
| + | The content path must be to an ".nsp" file or a ".nspd" folder. "*.nspd/program0.ncd/" is also allowed. |
| + | |
| + | This calls fs::MountApplicationPackage on the input content path, and reads content meta from "meta0.ncd" or ".cnmt.nca" extension folder/file depending on whether it is a .nspd or .nsp content path. |
| + | |
| + | A location resolver for the Host storage is opened, and EraseProgramRedirection is called for the parsed program id. |
| + | |
| + | RedierectProgramPath is then called for the program ID to set it to the input content path. |
| + | |
| + | This then calls the implementation function for [[#LaunchProgram]] with the input pm launch flags and pgl launch flags = 0. |
| + | |
| + | == GetHostContentMetaInfo == |
| + | This takes an input MapAlias buffer "content path", and does the same parsing as [[#LaunchProgramFromHost]]. |
| + | |
| + | Instead of launching the program, it instead returns an 0x10 output [[#ContentMetaInfo]] from the parsed info. |
| + | |
| + | == GetApplicationProcessId == |
| + | This calls pm:shell->GetApplicationProcessIdForShell, and returns the output process id. |
| + | |
| + | Error 0x6E4 is returned when there is no application process. |
| + | |
| + | == BoostSystemMemoryResourceLimit == |
| + | This takes in a u64 mem_size, and uses it as input to pm:shell->BoostSystemMemoryResourceLimit |
| + | |
| + | == EnableApplicationCrashReport == |
| + | Takes an input boolean "enable". |
| + | |
| + | This calls pm:shell->GetApplicationProcessId. If the returned process ID is tracked, this sets or clears bit 1 (value 0x2) in the tracked process's flags. |
| + | |
| + | When a process crash event occurs and pgl launches crash report, the second argument is "%d" formatted with the bitwise AND of this bit and bit 0 (value 0x1). |
| + | |
| + | LaunchFlags_EnableDetailedCrashReport causes the process to have both of these flags set, otherwise they are both zero. |
| + | |
| + | Thus this command is only useful for disabling/toggling detailed crash reports for applications launched with LaunchFlags_EnableDetailedCrashReport, as processes without the launch flag will always send "0" for the creport argument. |
| + | |
| + | == IsApplicationCrashReportEnabled == |
| + | This returns the value of the bit set or cleared by [[#EnableApplicationCrashReport]] |
| + | |
| + | == EnableApplicationAllThreadDumpOnCrash == |
| + | Takes an input boolean "enable". |
| + | |
| + | This calls pm:shell->GetApplicationProcessId. If the returned process ID is tracked, this sets or clears bit 3 (value 0x8) in the tracked process's flags. |
| + | |
| + | Using this command unconditionally sets bit 2 (value 0x4) in the tracked process's flags. |
| + | |
| + | When the SnapShotDumper is launched, argument "-log %d" is set to the value of bit 3 if bit 2 is 1. Otherwise, argument "-log %d" is set to the value of the system setting "snap_shot_dump!output_all_log". |
| + | |
| + | Thus, this overrides the log option for the current application process from snap_shot_dump!output_all_log with the input value. |
| + | |
| + | Previously this functionality was controlled by ns:am2->EnableApplicationAllThreadDumpOnCrash, which is now a wrapper for this function. |
| + | |
| + | == TriggerSnapShotDumper == |
| + | This takes an input 32 "SnapShotDumpType" and an input MapAliasBuffer "argument". |
| + | |
| + | This manually invokes the same function to launch the SnapShotDumper program (0100000000002071) as is called automatically when a process crashes and jit_debug!enable_jit_debug is 1. |
| + | |
| + | If the argument is NULL, then the snap shot dumper is launched with argument Format("D %010llu -log %d -dump %d", process_id, log_option, snap_shot_dump_type - 1). |
| + | If the argument is not NULL, the snap shot dumper is launched with argument Format("D %010llu \"%s\" -log %d -dump %d", process_id, argument, log_option, snap_shot_dump_type - 1). |
| + | |
| + | When invoked automatically, the SnapShotDumpType is SnapShotDumpType_Full if both "snap_shot_dump!full_dump" and "snap_shot_dump!auto_dump" are true, SnapShotDumpType_Auto if only "snap_shot_dump!auto_dump" is 1, and SnapShotDumpType_None otherwise. |
| + | |
| + | == IEventObserver == |
| + | {| class="wikitable" border="1" |
| + | |- |
| + | ! Cmd || Name |
| + | |- |
| + | | 0 || [[#GetProcessEventHandle]] |
| + | |- |
| + | | 1 || [[#GetProcessEventInfo]] |
| + | |} |
| + | |
| + | == GetProcessEventHandle == |
| + | This takes no input and returns an output copy event handle. |
| + | |
| + | == GetProcessEventInfo == |
| + | This takes no input and attempts to receive a [[Process_Manager_services#ProcessEventInfo]] from the observer's message queue. |
| + | |
| + | Every time a process event occurs, pgl receives the event from PM (it does pm:shell->GetProcessEventHandle() during startup and has a thread looping pm:shell->GetProcessEventInfo() to track process events. |
| | | |
− | The LaunchFlags enum looks like this:
| + | PGL sends to all observers' message queues a [[Process_Manager_services#ProcessEventInfo]] for each event it receives, thus allowing for multiple subscribers to process events. |
| | | |
| + | = LaunchFlags = |
| {| class=wikitable | | {| class=wikitable |
| ! Bit || Mask || Name | | ! Bit || Mask || Name |
| |- | | |- |
− | | 0 || 1 || LaunchFlags_EnableDetailedCrashReport | + | | 0 || 1 || EnableDetailedCrashReport |
| + | |- |
| + | | 1 || 2 || EnableCrashReportScreenShotForProduction |
| + | |- |
| + | | 2 || 4 || EnableCrashReportScreenShotForDevelop |
| + | |- |
| + | |} |
| + | |
| + | = SnapShotDumpType = |
| + | {| class=wikitable |
| + | ! Value || Name |
| |- | | |- |
− | | 1 || 2 || LaunchFlags_EnableCrashReportScreenShotForProduction | + | | 0 || None |
| |- | | |- |
− | | 2 || 4 || LaunchFlags_EnableCrashReportScreenShotForDevelop | + | | 1 || Auto |
| + | |- |
| + | | 2 || Full |
| |- | | |- |
| |} | | |} |
| | | |
− | == ContentMetaInfo ==
| + | = ContentMetaInfo = |
| {| class="wikitable" border="1" | | {| class="wikitable" border="1" |
| |- | | |- |
Line 72: |
Line 185: |
| | 0x2 | | | 0x2 |
| | Padding | | | Padding |
− | |}
| |
− |
| |
− |
| |
− | == LaunchProgram ==
| |
− | Takes a [[NCM_services#ProgramLocation|ProgramLocation]], a u32 [[Process_Manager_services#LaunchFlags]] pm launch_flags, and a u8 [[#LaunchFlags|LaunchFlags]] pgl launch_flags.
| |
− |
| |
− | This calls pm:shell->LaunchProgram with the program location and the input launch flags. If jit_debug!enable_jit_debug is true, LaunchFlags_SignalOnCrash is ORRd into the flags sent to PM.
| |
− |
| |
− | This then creates a new process tracking structure for the new process id and with the pgl launch flags. If an empty process struct is not allocated from the 0x20 slab heap, pgl aborts.
| |
− |
| |
− | == TerminateProcess ==
| |
− | This just calls pm:shell->TerminateProcess with the input process id.
| |
− |
| |
− | == GetEventObserver ==
| |
− | No input. Returns an [[#IEventObserver]].
| |
− |
| |
− | == IEventObserver ==
| |
− | {| class="wikitable" border="1"
| |
− | |-
| |
− | ! Cmd || Name
| |
− | |-
| |
− | | 0 ||
| |
− | |-
| |
− | | 1 ||
| |
| |} | | |} |