Skip to content

Commit

Permalink
add android_fdsan_set_error_level() option, Android API 29+ only
Browse files Browse the repository at this point in the history
  • Loading branch information
AGulev committed Oct 8, 2021
1 parent 2896f47 commit ae1e832
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 35 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,17 @@ Native Extension for Defold Game Engine that gives a possibility to use [StrictM

## Installation
Copy-paste `strict_mode` section from extensions [game.project](https://github.com/AGulev/defold-extension-strictmode/blob/3faab456a92d7c861fd4dcfab0712cb63e8a0170/game.project#L17) into your `game.project`

Possible `fdsan_level` values are:
```
0 -- ANDROID_FDSAN_ERROR_LEVEL_DISABLED
1 -- ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE
2 -- ANDROID_FDSAN_ERROR_LEVEL_WARN_ALWAYS
3 -- ANDROID_FDSAN_ERROR_LEVEL_FATAL
```
All the other fields are boolean values and maybe 1 or 0 ON/OFF.

## Issues and suggestions

If you have any issues, questions or suggestions please [create an issue](https://github.com/AGulev/defold-extension-strictmode/issues) or contact me: me@agulev.com
89 changes: 63 additions & 26 deletions extension-strictmode/src/strictmode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,37 @@
#include <dmsdk/sdk.h>
#include "strictmode_jni.h"

#define __EXT_ANDROID_API__ __ANDROID_API__
//redefenition hack to be able to build it
#define __ANDROID_API__ 29
#include <android/fdsan.h>
#define __ANDROID_API__ __EXT_ANDROID_API__
#undef __EXT_ANDROID_API__

dmExtension::Result AppInitializeStrictMode(dmExtension::AppParams* params)
{
dmStrictMode::ThreadAttacher attacher;
JNIEnv *env = attacher.env;
dmStrictMode::ClassLoader class_loader = dmStrictMode::ClassLoader(env);
jclass cls = class_loader.load("com/agulev/strictmode/ApplyStrictMode");

bool policy_active = dmConfigFile::GetInt(params->m_ConfigFile, "strictmode.thread_policy_active", 0) == 1;
if (policy_active) {
bool detect_all = dmConfigFile::GetInt(params->m_ConfigFile, "strictmode.thread_detect_all", 0) == 1;
bool detect_disk_reads = dmConfigFile::GetInt(params->m_ConfigFile, "strictmode.thread_detect_disk_reads", 0) == 1;
bool detect_disk_write = dmConfigFile::GetInt(params->m_ConfigFile, "strictmode.thread_detect_disk_writes", 0) == 1;
bool detect_network = dmConfigFile::GetInt(params->m_ConfigFile, "strictmode.thread_detect_network", 0) == 1;
bool detect_slow_calls = dmConfigFile::GetInt(params->m_ConfigFile, "strictmode.thread_detect_slow_calls", 0) == 1;
bool detect_resource_mismatches = dmConfigFile::GetInt(params->m_ConfigFile, "strictmode.thread_detect_resource_mismatches", 0) == 1;
bool detect_unbuffered_io = dmConfigFile::GetInt(params->m_ConfigFile, "strictmode.thread_detect_unbuffered_io", 0) == 1;
bool policy_active = dmConfigFile::GetInt(params->m_ConfigFile, "strict_mode.thread_policy_active", 0) == 1;
if (policy_active)
{
bool detect_all = dmConfigFile::GetInt(params->m_ConfigFile, "strict_mode.thread_detect_all", 0) == 1;
bool detect_disk_reads = dmConfigFile::GetInt(params->m_ConfigFile, "strict_mode.thread_detect_disk_reads", 0) == 1;
bool detect_disk_write = dmConfigFile::GetInt(params->m_ConfigFile, "strict_mode.thread_detect_disk_writes", 0) == 1;
bool detect_network = dmConfigFile::GetInt(params->m_ConfigFile, "strict_mode.thread_detect_network", 0) == 1;
bool detect_slow_calls = dmConfigFile::GetInt(params->m_ConfigFile, "strict_mode.thread_detect_slow_calls", 0) == 1;
bool detect_resource_mismatches = dmConfigFile::GetInt(params->m_ConfigFile, "strict_mode.thread_detect_resource_mismatches", 0) == 1;
bool detect_unbuffered_io = dmConfigFile::GetInt(params->m_ConfigFile, "strict_mode.thread_detect_unbuffered_io", 0) == 1;

bool penalty_log = dmConfigFile::GetInt(params->m_ConfigFile, "strictmode.thread_penalty_log", 0) == 1;
bool penalty_death = dmConfigFile::GetInt(params->m_ConfigFile, "strictmode.thread_penalty_death", 0) == 1;
bool penalty_dialog = dmConfigFile::GetInt(params->m_ConfigFile, "strictmode.thread_penalty_dialog", 0) == 1;
bool penalty_death_on_network = dmConfigFile::GetInt(params->m_ConfigFile, "strictmode.thread_penalty_death_on_network", 0) == 1;
bool penalty_drop_box = dmConfigFile::GetInt(params->m_ConfigFile, "strictmode.thread_penalty_drop_box", 0) == 1;
bool penalty_flash_screen = dmConfigFile::GetInt(params->m_ConfigFile, "strictmode.thread_penalty_flash_screen", 0) == 1;
bool penalty_log = dmConfigFile::GetInt(params->m_ConfigFile, "strict_mode.thread_penalty_log", 0) == 1;
bool penalty_death = dmConfigFile::GetInt(params->m_ConfigFile, "strict_mode.thread_penalty_death", 0) == 1;
bool penalty_dialog = dmConfigFile::GetInt(params->m_ConfigFile, "strict_mode.thread_penalty_dialog", 0) == 1;
bool penalty_death_on_network = dmConfigFile::GetInt(params->m_ConfigFile, "strict_mode.thread_penalty_death_on_network", 0) == 1;
bool penalty_drop_box = dmConfigFile::GetInt(params->m_ConfigFile, "strict_mode.thread_penalty_drop_box", 0) == 1;
bool penalty_flash_screen = dmConfigFile::GetInt(params->m_ConfigFile, "strict_mode.thread_penalty_flash_screen", 0) == 1;

jmethodID methodThread = env->GetStaticMethodID(cls, "ApplyThreadStrictMode", "(ZZZZZZZZZZZZZ)V");
env->CallStaticVoidMethod(cls, methodThread, detect_all, detect_disk_reads, detect_disk_write, detect_network, detect_slow_calls,
Expand All @@ -37,22 +45,51 @@ dmExtension::Result AppInitializeStrictMode(dmExtension::AppParams* params)
}


bool vm_policy_active = dmConfigFile::GetInt(params->m_ConfigFile, "strictmode.vm_policy_active", 0) == 1;
if (vm_policy_active) {
bool vm_detect_all = dmConfigFile::GetInt(params->m_ConfigFile, "strictmode.vm_detect_all", 0) == 1;
bool vm_detect_sqllite_leaks = dmConfigFile::GetInt(params->m_ConfigFile, "strictmode.vm_detect_sqllite_leaks", 0) == 1;
bool vm_detect_leaked_closable_objects = dmConfigFile::GetInt(params->m_ConfigFile, "strictmode.vm_detect_leaked_closable_objects", 0) == 1;
bool vm_penalty_log = dmConfigFile::GetInt(params->m_ConfigFile, "strictmode.vm_penalty_log", 0) == 1;
bool vm_penalty_death = dmConfigFile::GetInt(params->m_ConfigFile, "strictmode.vm_penalty_death", 0) == 1;
bool vm_penalty_death_on_file_uri_exposure = dmConfigFile::GetInt(params->m_ConfigFile, "strictmode.vm_penalty_death_on_file_uri_exposure", 0) == 1;
bool vm_penalty_death_on_network = dmConfigFile::GetInt(params->m_ConfigFile, "strictmode.vm_penalty_death_on_network", 0) == 1;
bool vm_penalty_drop_box = dmConfigFile::GetInt(params->m_ConfigFile, "strictmode.vm_penalty_drop_box", 0) == 1;
bool vm_policy_active = dmConfigFile::GetInt(params->m_ConfigFile, "strict_mode.vm_policy_active", 0) == 1;
if (vm_policy_active)
{
bool vm_detect_all = dmConfigFile::GetInt(params->m_ConfigFile, "strict_mode.vm_detect_all", 0) == 1;
bool vm_detect_sqllite_leaks = dmConfigFile::GetInt(params->m_ConfigFile, "strict_mode.vm_detect_sqllite_leaks", 0) == 1;
bool vm_detect_leaked_closable_objects = dmConfigFile::GetInt(params->m_ConfigFile, "strict_mode.vm_detect_leaked_closable_objects", 0) == 1;
bool vm_penalty_log = dmConfigFile::GetInt(params->m_ConfigFile, "strict_mode.vm_penalty_log", 0) == 1;
bool vm_penalty_death = dmConfigFile::GetInt(params->m_ConfigFile, "strict_mode.vm_penalty_death", 0) == 1;
bool vm_penalty_death_on_file_uri_exposure = dmConfigFile::GetInt(params->m_ConfigFile, "strict_mode.vm_penalty_death_on_file_uri_exposure", 0) == 1;
bool vm_penalty_death_on_network = dmConfigFile::GetInt(params->m_ConfigFile, "strict_mode.vm_penalty_death_on_network", 0) == 1;
bool vm_penalty_drop_box = dmConfigFile::GetInt(params->m_ConfigFile, "strict_mode.vm_penalty_drop_box", 0) == 1;

jmethodID methodVm = env->GetStaticMethodID(cls, "ApplyVMStrictMode", "(ZZZZZZZZ)V");
env->CallStaticVoidMethod(cls, methodVm, vm_detect_sqllite_leaks, vm_detect_leaked_closable_objects, vm_detect_all, vm_penalty_log,
vm_penalty_death, vm_penalty_death_on_file_uri_exposure, vm_penalty_death_on_network, vm_penalty_drop_box);
}

//// API is avaliable on Android 10.0+ (API 29+)
if (android_get_device_api_level() >= 29)
{
int fdsan_level = dmConfigFile::GetInt(params->m_ConfigFile, "strict_mode.fdsan_level", 0);
switch (fdsan_level)
{
case 0:
dmLogInfo("set_error_level ANDROID_FDSAN_ERROR_LEVEL_DISABLED");
android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_DISABLED);
break;
case 1:
dmLogInfo("set_error_level ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE");
android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE);
break;
case 2:
dmLogInfo("set_error_level ANDROID_FDSAN_ERROR_LEVEL_WARN_ALWAYS");
android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ALWAYS);
break;
case 3:
dmLogInfo("set_error_level ANDROID_FDSAN_ERROR_LEVEL_FATAL");
android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_FATAL);
break;
}

}
else
{
dmLogWarning("`android_fdsan_set_error_level()` is available only on Android API 29 and above");
}
return dmExtension::RESULT_OK;
}

Expand Down
19 changes: 10 additions & 9 deletions game.project
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,30 @@ include_dirs = extension-strictmode

[strict_mode]
thread_detect_all = 1
thread_policy_active = 1
thread_detect_disk_reads = 1
thread_detect_disk_writes = 1
thread_detect_network = 1
thread_detect_slow_calls = 1
thread_detect_resource_mismatches = 1
thread_detect_unbuffered_io = 1
thread_policy_active = 0
thread_detect_disk_reads = 0
thread_detect_disk_writes = 0
thread_detect_network = 0
thread_detect_slow_calls = 0
thread_detect_resource_mismatches = 0
thread_detect_unbuffered_io = 0
thread_penalty_log = 1
thread_penalty_death = 0
thread_penalty_dialog = 0
thread_penalty_death_on_network = 0
thread_penalty_drop_box = 0
thread_penalty_flash_screen = 0
vm_policy_active = 1
vm_detect_sqllite_leaks = 1
vm_detect_leaked_closable_objects = 1
vm_detect_all = 1
vm_detect_sqllite_leaks = 0
vm_detect_leaked_closable_objects = 0
vm_penalty_log = 1
vm_penalty_death = 0
vm_death_on_file_uri_exposure = 0
vm_penalty_death_on_network = 0
vm_penalty_drop_box = 0
vm_penalty_death_on_file_uri_exposure = 0
fdsan_level = 2

[android]
package = com.agulev.strictmode
Expand Down

0 comments on commit ae1e832

Please # to comment.