source-mirror: Handle uncaught exceptions in C callbacks

Fixes various crashes and undefined behavior due to exceptions falling into C code where they now wreak havoc with the current stack.
This commit is contained in:
Michael Fabian 'Xaymar' Dirks 2019-09-04 20:52:37 +02:00
parent f65dfcbbf0
commit 4c44496b87
2 changed files with 71 additions and 48 deletions

View file

@ -106,13 +106,13 @@ source::mirror::mirror_factory::mirror_factory()
source::mirror::mirror_factory::~mirror_factory() {} source::mirror::mirror_factory::~mirror_factory() {}
const char* source::mirror::mirror_factory::get_name(void*) const char* source::mirror::mirror_factory::get_name(void*) noexcept try {
{
return D_TRANSLATE(ST); return D_TRANSLATE(ST);
} catch (...) {
P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
} }
void source::mirror::mirror_factory::get_defaults(obs_data_t* data) void source::mirror::mirror_factory::get_defaults(obs_data_t* data) noexcept try {
{
obs_data_set_default_string(data, ST_SOURCE, ""); obs_data_set_default_string(data, ST_SOURCE, "");
obs_data_set_default_bool(data, ST_AUDIO, false); obs_data_set_default_bool(data, ST_AUDIO, false);
obs_data_set_default_int(data, ST_AUDIO_LAYOUT, static_cast<int64_t>(SPEAKERS_UNKNOWN)); obs_data_set_default_int(data, ST_AUDIO_LAYOUT, static_cast<int64_t>(SPEAKERS_UNKNOWN));
@ -122,10 +122,12 @@ void source::mirror::mirror_factory::get_defaults(obs_data_t* data)
obs_data_set_default_bool(data, ST_SCALING_TRANSFORMKEEPORIGINAL, false); obs_data_set_default_bool(data, ST_SCALING_TRANSFORMKEEPORIGINAL, false);
obs_data_set_default_int(data, ST_SCALING_BOUNDS, (int64_t)obs_bounds_type::OBS_BOUNDS_STRETCH); obs_data_set_default_int(data, ST_SCALING_BOUNDS, (int64_t)obs_bounds_type::OBS_BOUNDS_STRETCH);
obs_data_set_default_int(data, ST_SCALING_ALIGNMENT, OBS_ALIGN_CENTER); obs_data_set_default_int(data, ST_SCALING_ALIGNMENT, OBS_ALIGN_CENTER);
} catch (...) {
P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
} }
bool source::mirror::mirror_factory::modified_properties(obs_properties_t* pr, obs_property_t* p, obs_data_t* data) bool source::mirror::mirror_factory::modified_properties(obs_properties_t* pr, obs_property_t* p,
{ obs_data_t* data) noexcept try {
if (obs_properties_get(pr, ST_SOURCE) == p) { if (obs_properties_get(pr, ST_SOURCE) == p) {
obs_source_t* target = obs_get_source_by_name(obs_data_get_string(data, ST_SOURCE)); obs_source_t* target = obs_get_source_by_name(obs_data_get_string(data, ST_SOURCE));
if (target) { if (target) {
@ -180,11 +182,13 @@ bool source::mirror::mirror_factory::modified_properties(obs_properties_t* pr, o
return true; return true;
} }
return false;
} catch (...) {
P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
return false; return false;
} }
obs_properties_t* source::mirror::mirror_factory::get_properties(void*) obs_properties_t* source::mirror::mirror_factory::get_properties(void*) noexcept try {
{
obs_properties_t* pr = obs_properties_create(); obs_properties_t* pr = obs_properties_create();
obs_property_t* p = nullptr; obs_property_t* p = nullptr;
@ -274,90 +278,109 @@ obs_properties_t* source::mirror::mirror_factory::get_properties(void*)
OBS_ALIGN_RIGHT | OBS_ALIGN_BOTTOM); OBS_ALIGN_RIGHT | OBS_ALIGN_BOTTOM);
return pr; return pr;
} catch (...) {
P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
return nullptr;
} }
void* source::mirror::mirror_factory::create(obs_data_t* data, obs_source_t* source) void* source::mirror::mirror_factory::create(obs_data_t* data, obs_source_t* source) noexcept try {
{
return new source::mirror::mirror_instance(data, source); return new source::mirror::mirror_instance(data, source);
} catch (...) {
P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
return nullptr;
} }
void source::mirror::mirror_factory::destroy(void* p) void source::mirror::mirror_factory::destroy(void* p) noexcept try {
{
if (p) { if (p) {
delete static_cast<source::mirror::mirror_instance*>(p); delete static_cast<source::mirror::mirror_instance*>(p);
} }
} catch (...) {
P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
} }
uint32_t source::mirror::mirror_factory::get_width(void* p) uint32_t source::mirror::mirror_factory::get_width(void* p) noexcept try {
{
if (p) { if (p) {
return static_cast<source::mirror::mirror_instance*>(p)->get_width(); return static_cast<source::mirror::mirror_instance*>(p)->get_width();
} }
return 0; return 0;
} catch (...) {
P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
return 0;
} }
uint32_t source::mirror::mirror_factory::get_height(void* p) uint32_t source::mirror::mirror_factory::get_height(void* p) noexcept try {
{
if (p) { if (p) {
return static_cast<source::mirror::mirror_instance*>(p)->get_height(); return static_cast<source::mirror::mirror_instance*>(p)->get_height();
} }
return 0; return 0;
} catch (...) {
P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
return 0;
} }
void source::mirror::mirror_factory::update(void* p, obs_data_t* data) void source::mirror::mirror_factory::update(void* p, obs_data_t* data) noexcept try {
{
if (p) { if (p) {
static_cast<source::mirror::mirror_instance*>(p)->update(data); static_cast<source::mirror::mirror_instance*>(p)->update(data);
} }
} catch (...) {
P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
} }
void source::mirror::mirror_factory::activate(void* p) void source::mirror::mirror_factory::activate(void* p) noexcept try {
{
if (p) { if (p) {
static_cast<source::mirror::mirror_instance*>(p)->activate(); static_cast<source::mirror::mirror_instance*>(p)->activate();
} }
} catch (...) {
P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
} }
void source::mirror::mirror_factory::deactivate(void* p) void source::mirror::mirror_factory::deactivate(void* p) noexcept try {
{
if (p) { if (p) {
static_cast<source::mirror::mirror_instance*>(p)->deactivate(); static_cast<source::mirror::mirror_instance*>(p)->deactivate();
} }
} catch (...) {
P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
} }
void source::mirror::mirror_factory::video_tick(void* p, float t) void source::mirror::mirror_factory::video_tick(void* p, float t) noexcept try {
{
if (p) { if (p) {
static_cast<source::mirror::mirror_instance*>(p)->video_tick(t); static_cast<source::mirror::mirror_instance*>(p)->video_tick(t);
} }
} catch (...) {
P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
} }
void source::mirror::mirror_factory::video_render(void* p, gs_effect_t* ef) void source::mirror::mirror_factory::video_render(void* p, gs_effect_t* ef) noexcept try {
{
if (p) { if (p) {
static_cast<source::mirror::mirror_instance*>(p)->video_render(ef); static_cast<source::mirror::mirror_instance*>(p)->video_render(ef);
} }
} catch (...) {
P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
} }
void source::mirror::mirror_factory::enum_active_sources(void* p, obs_source_enum_proc_t enum_callback, void* param) void source::mirror::mirror_factory::enum_active_sources(void* p, obs_source_enum_proc_t enum_callback,
{ void* param) noexcept try {
if (p) { if (p) {
static_cast<source::mirror::mirror_instance*>(p)->enum_active_sources(enum_callback, param); static_cast<source::mirror::mirror_instance*>(p)->enum_active_sources(enum_callback, param);
} }
} catch (...) {
P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
} }
void source::mirror::mirror_factory::load(void* p, obs_data_t* d) void source::mirror::mirror_factory::load(void* p, obs_data_t* d) noexcept try {
{
if (p) { if (p) {
static_cast<source::mirror::mirror_instance*>(p)->load(d); static_cast<source::mirror::mirror_instance*>(p)->load(d);
} }
} catch (...) {
P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
} }
void source::mirror::mirror_factory::save(void* p, obs_data_t* d) void source::mirror::mirror_factory::save(void* p, obs_data_t* d) noexcept try {
{
if (p) { if (p) {
static_cast<source::mirror::mirror_instance*>(p)->save(d); static_cast<source::mirror::mirror_instance*>(p)->save(d);
} }
} catch (...) {
P_LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
} }
void source::mirror::mirror_instance::release_input() void source::mirror::mirror_instance::release_input()

View file

@ -54,25 +54,25 @@ namespace source {
mirror_factory(); mirror_factory();
~mirror_factory(); ~mirror_factory();
static const char* get_name(void*); static const char* get_name(void*) noexcept;
static void get_defaults(obs_data_t*); static void get_defaults(obs_data_t*) noexcept;
static bool modified_properties(obs_properties_t*, obs_property_t*, obs_data_t*); static bool modified_properties(obs_properties_t*, obs_property_t*, obs_data_t*) noexcept;
static obs_properties_t* get_properties(void*); static obs_properties_t* get_properties(void*) noexcept;
static void* create(obs_data_t*, obs_source_t*); static void* create(obs_data_t*, obs_source_t*) noexcept;
static void destroy(void*); static void destroy(void*) noexcept;
static uint32_t get_width(void*); static uint32_t get_width(void*) noexcept;
static uint32_t get_height(void*); static uint32_t get_height(void*) noexcept;
static void update(void*, obs_data_t*); static void update(void*, obs_data_t*) noexcept;
static void activate(void*); static void activate(void*) noexcept;
static void deactivate(void*); static void deactivate(void*) noexcept;
static void video_tick(void*, float); static void video_tick(void*, float) noexcept;
static void video_render(void*, gs_effect_t*); static void video_render(void*, gs_effect_t*) noexcept;
static void enum_active_sources(void*, obs_source_enum_proc_t, void*); static void enum_active_sources(void*, obs_source_enum_proc_t, void*) noexcept;
static void load(void*, obs_data_t*); static void load(void*, obs_data_t*) noexcept;
static void save(void*, obs_data_t*); static void save(void*, obs_data_t*) noexcept;
}; };
struct mirror_audio_data { struct mirror_audio_data {