android crashlog implemented gg

This commit is contained in:
altalk23 2023-10-15 17:31:30 +03:00
parent 57a475b3b7
commit 241fed492c
6 changed files with 117 additions and 16 deletions

View file

@ -16,13 +16,13 @@ std::string crashlog::getDateString(bool filesafe) {
return oss.str();
}
static void printGeodeInfo(std::stringstream& stream) {
void crashlog::printGeodeInfo(std::stringstream& stream) {
stream << "Loader Version: " << Loader::get()->getVersion().toString() << "\n"
<< "Installed mods: " << Loader::get()->getAllMods().size() << "\n"
<< "Problems: " << Loader::get()->getProblems().size() << "\n";
}
static void printMods(std::stringstream& stream) {
void crashlog::printMods(std::stringstream& stream) {
auto mods = Loader::get()->getAllMods();
if (mods.empty()) {
stream << "<None>\n";
@ -30,7 +30,7 @@ static void printMods(std::stringstream& stream) {
using namespace std::string_view_literals;
for (auto& mod : mods) {
stream << fmt::format("{} | [{}] {}\n",
mod->isEnabled() ? "x"sv : " "sv,
mod->isEnabled() ? "x"sv : mod->shouldLoad() ? "~"sv : " "sv,
mod->getVersion().toString(), mod->getID()
);
}

View file

@ -13,6 +13,12 @@ namespace crashlog {
* @returns True if the handler was successfully installed, false otherwise
*/
bool GEODE_DLL setupPlatformHandler();
/**
* Setup platform-specific crashlog handler for post-launch
*/
void GEODE_DLL setupPlatformHandlerPost();
/**
* Check if previous launch of GD crashed unexpectedly
* @returns True if the launch crashed, false otherwise or if indeterminate
@ -28,4 +34,9 @@ namespace crashlog {
std::string GEODE_DLL writeCrashlog(geode::Mod* faultyMod, std::string const& info, std::string const& stacktrace, std::string const& registers);
std::string getDateString(bool filesafe);
void printGeodeInfo(std::stringstream& stream);
void printMods(std::stringstream& stream);
}

View file

@ -88,6 +88,8 @@ int geodeEntry(void* platformData) {
return 1;
}
crashlog::setupPlatformHandlerPost();
log::info("Set up loader");
// download and install new loader update in the background

View file

@ -336,7 +336,7 @@ static void handlerThread() {
log::debug("Notified");
}
static bool s_lastLaunchCrashed;
static bool s_lastLaunchCrashed = false;
// bool crashlog::setupPlatformHandler() {
// auto pidFile = crashlog::getCrashLogDirectory() / "last-pid";
@ -413,28 +413,112 @@ static bool s_lastLaunchCrashed;
// }
ghc::filesystem::path crashlog::getCrashLogDirectory() {
return geode::dirs::getSaveDir();
return dirs::getGeodeDir() / "crashlogs";
}
bool crashlog::setupPlatformHandler() {
auto path = crashlog::getCrashLogDirectory() / (getDateString(true) + ".log");
int writeAndGetPid() {
auto pidFile = crashlog::getCrashLogDirectory() / "last-pid";
JniMethodInfo t;
if (JniHelper::getStaticMethodInfo(t, "com/geode/launcher/utils/GeodeUtils", "writeLogcatCrashBuffer", "(Ljava/lang/String;)Z")) {
jstring stringArg1 = t.env->NewStringUTF(path.string().c_str());
int lastPid = 0;
jboolean result = t.env->CallStaticBooleanMethod(t.classID, t.methodID, stringArg1);
if (ghc::filesystem::exists(pidFile)) {
t.env->DeleteLocalRef(stringArg1);
t.env->DeleteLocalRef(t.classID);
return result;
auto res = file::readString(pidFile);
if (!res) {
log::warn("Failed to read last-pid file: {}", res.error());
}
else {
lastPid = std::stoi(res.unwrap());
}
std::error_code ec;
ghc::filesystem::remove(pidFile, ec);
if (ec) {
log::warn("Failed to remove last-pid file: {}", ec.message());
}
}
return false;
auto res = file::writeString(pidFile, std::to_string(getpid()));
if (!res) {
log::warn("Failed to write last-pid file: {}", res.error());
}
return lastPid;
}
void printModsAndroid(std::stringstream& stream) {
auto mods = Loader::get()->getAllMods();
if (mods.empty()) {
stream << "<None>\n";
}
using namespace std::string_view_literals;
for (auto& mod : mods) {
stream << fmt::format("{} | [{}] {}\n",
mod->shouldLoad() ? "x"sv : " "sv,
mod->getVersion().toString(), mod->getID()
);
}
}
static std::string s_result;
bool crashlog::setupPlatformHandler() {
JniMethodInfo t;
if (JniHelper::getStaticMethodInfo(t, "com/geode/launcher/utils/GeodeUtils", "getLogcatCrashBuffer", "()Ljava/lang/String;")) {
jstring stringResult = (jstring)t.env->CallStaticObjectMethod(t.classID, t.methodID);
s_result = JniHelper::jstring2string(stringResult);
t.env->DeleteLocalRef(stringResult);
t.env->DeleteLocalRef(t.classID);
if (s_result.empty()) {
return false;
}
}
else return false;
auto lastPid = writeAndGetPid();
auto index = s_result.rfind(fmt::format("pid {}", lastPid));
if (index != std::string::npos) {
auto begin = s_result.substr(0, index).rfind("F/libc");
if (begin != std::string::npos) {
s_result = s_result.substr(begin);
}
s_lastLaunchCrashed = true;
}
return true;
}
void crashlog::setupPlatformHandlerPost() {
if (s_result.empty()) return;
std::stringstream ss;
ss << "Geode crashed!\n";
ss << "Please submit this crash report to the developer of the mod that caused it.\n";
ss << "\n== Geode Information ==\n";
crashlog::printGeodeInfo(ss);
ss << "\n== Installed Mods ==\n";
printModsAndroid(ss);
ss << "\n== Crash Report (Logcat) ==\n";
ss << s_result;
std::ofstream actualFile;
actualFile.open(
crashlog::getCrashLogDirectory() / (crashlog::getDateString(true) + ".log"), std::ios::app
);
actualFile << ss.rdbuf() << std::flush;
actualFile.close();
}
bool crashlog::didLastLaunchCrash() {
return false;
return s_lastLaunchCrashed;
}
#endif

View file

@ -382,6 +382,8 @@ bool crashlog::setupPlatformHandler() {
return true;
}
void crashlog::setupPlatformHandlerPost() {}
bool crashlog::didLastLaunchCrash() {
return s_lastLaunchCrashed;
}

View file

@ -252,6 +252,8 @@ bool crashlog::didLastLaunchCrash() {
return g_lastLaunchCrashed;
}
void crashlog::setupPlatformHandlerPost() {}
ghc::filesystem::path crashlog::getCrashLogDirectory() {
return dirs::getGeodeDir() / "crashlogs";
}