pgl: Implement TriggerApplicationSnapShotDumper

This commit is contained in:
Michael Scire 2020-04-16 03:28:25 -07:00
parent e4653eeaef
commit 48f7697784
5 changed files with 154 additions and 3 deletions

View file

@ -16,5 +16,6 @@
#pragma once
#include "ldr/ldr_types.hpp"
#include "ldr/ldr_pm_api.hpp"
#include <stratosphere/ldr/ldr_types.hpp>
#include <stratosphere/ldr/ldr_shell_api.hpp>
#include <stratosphere/ldr/ldr_pm_api.hpp>

View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vapours.hpp>
#include <stratosphere/ncm/ncm_ids.hpp>
#include <stratosphere/ldr/ldr_types.hpp>
namespace ams::ldr {
/* Shell API. */
Result InitializeForShell();
Result FinalizeForShell();
Result SetProgramArgument(ncm::ProgramId program_id, const void *arg, size_t size);
Result FlushArguments();
}

View file

@ -402,6 +402,34 @@ namespace ams::ncm {
return true;
}
struct SystemDebugAppletId {
u64 value;
constexpr operator ProgramId() const {
return { this->value };
}
static const SystemDebugAppletId Start;
static const SystemDebugAppletId SnapShotDumper;
static const SystemDebugAppletId End;
};
inline constexpr const SystemDebugAppletId SystemDebugAppletId::Start = { 0x0100000000002000ul };
inline constexpr const SystemDebugAppletId SystemDebugAppletId::SnapShotDumper = { 0x0100000000002071ul };
inline constexpr const SystemDebugAppletId SystemDebugAppletId::End = { 0x0100000000002FFFul };
inline constexpr bool IsSystemDebugAppletId(const ProgramId &program_id) {
return SystemDebugAppletId::Start <= program_id && program_id <= SystemDebugAppletId::End;
}
inline constexpr bool IsSystemDebugAppletId(const SystemDebugAppletId &program_id) {
return true;
}
struct LibraryAppletId {
u64 value;

View file

@ -0,0 +1,37 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stratosphere.hpp>
namespace ams::ldr {
Result InitializeForShell() {
return ::ldrShellInitialize();
}
Result FinalizeForShell() {
::ldrShellExit();
return ResultSuccess();
}
Result SetProgramArgument(ncm::ProgramId program_id, const void *arg, size_t size) {
return ::ldrShellSetProgramArguments(static_cast<u64>(program_id), arg, size);
}
Result FlushArguments() {
return ::ldrShellFlushArguments();
}
}

View file

@ -82,6 +82,55 @@ namespace ams::pgl::srv {
}
}
s32 ConvertDumpTypeToArgument(SnapShotDumpType dump_type) {
switch (dump_type) {
case SnapShotDumpType::None: return -1;
case SnapShotDumpType::Auto: return 0;
case SnapShotDumpType::Full: return 1;
AMS_UNREACHABLE_DEFAULT_CASE();
}
}
bool GetSnapShotDumpOutputAllLog(os::ProcessId process_id) {
/* Check if we have an option set for the process. */
{
std::scoped_lock lk(g_process_data_mutex);
if (ProcessData *data = FindProcessData(process_id); data != nullptr) {
if ((data->flags & ProcessDataFlag_HasLogOption) != 0) {
return ((data->flags & ProcessDataFlag_OutputAllLog) != 0);
}
}
}
/* If we don't have an option for the process, fall back to settings. */
u8 log_option;
const size_t option_size = settings::fwdbg::GetSettingsItemValue(std::addressof(log_option), sizeof(log_option), "snap_shot_dump", "output_all_log");
return (option_size == sizeof(log_option) && log_option != 0);
}
size_t CreateSnapShotDumpArguments(char *dst, size_t dst_size, os::ProcessId process_id, SnapShotDumpType dump_type, const char *str_arg) {
const s32 dump_arg = ConvertDumpTypeToArgument(dump_type);
const s32 log_arg = GetSnapShotDumpOutputAllLog(process_id) ? 1 : 0;
if (str_arg != nullptr) {
return std::snprintf(dst, dst_size, "D %010llu \"%s\" -log %d -dump %d", static_cast<unsigned long long>(static_cast<u64>(process_id)), str_arg, log_arg, dump_arg);
} else {
return std::snprintf(dst, dst_size, "D %010llu -log %d -dump %d", static_cast<unsigned long long>(static_cast<u64>(process_id)), log_arg, dump_arg);
}
}
Result TriggerSnapShotDumper(os::ProcessId process_id, SnapShotDumpType dump_type, const char *arg) {
/* Create the arguments. */
char process_arguments[800];
const size_t arg_len = CreateSnapShotDumpArguments(process_arguments, sizeof(process_arguments), process_id, dump_type, arg);
/* Set the arguments. */
R_TRY(ldr::SetProgramArgument(ncm::SystemDebugAppletId::SnapShotDumper, process_arguments, arg_len + 1));
/* Launch the process. */
os::ProcessId dummy_process_id;
return pm::shell::LaunchProgram(std::addressof(dummy_process_id), ncm::ProgramLocation::Make(ncm::SystemDebugAppletId::SnapShotDumper, ncm::StorageId::BuiltInSystem), pm::LaunchFlags_None);
}
}
void InitializeProcessControlTask() {
@ -205,7 +254,12 @@ namespace ams::pgl::srv {
}
Result TriggerApplicationSnapShotDumper(SnapShotDumpType dump_type, const char *arg) {
/* TODO */
/* Try to get the application process id. */
os::ProcessId process_id;
R_TRY(pm::shell::GetApplicationProcessIdForShell(std::addressof(process_id)));
/* Launch the snapshot dumper. */
return TriggerSnapShotDumper(process_id, dump_type, arg);
}
}