Better fatal error reporting, broadcast discovery fix crash

This commit is contained in:
Gioacchino Mazzurco 2022-11-06 12:48:57 -03:00
parent 95f8001baa
commit 4a83174093
No known key found for this signature in database
GPG Key ID: A1FBCA3872E87051
6 changed files with 95 additions and 69 deletions

View File

@ -650,6 +650,7 @@ list(
util/rsjson.h
util/rskbdinput.cc
util/rskbdinput.h
util/rsmacrosugar.hpp
util/rsmemcache.h
util/rsmemory.h
util/rsnet.h

View File

@ -513,7 +513,8 @@ HEADERS += util/folderiterator.h \
util/cxx14retrocompat.h \
util/cxx17retrocompat.h \
util/cxx23retrocompat.h \
util/rsurl.h
util/rsurl.h \
util/rsmacrosugar.hpp
SOURCES += ft/ftchunkmap.cc \
ft/ftcontroller.cc \

View File

@ -37,7 +37,6 @@
# include "rs_android/retroshareserviceandroid.hpp"
#endif // def __ANDROID__
/*extern*/ RsBroadcastDiscovery* rsBroadcastDiscovery = nullptr;
struct BroadcastDiscoveryPack : RsSerializable
@ -75,18 +74,11 @@ struct BroadcastDiscoveryPack : RsSerializable
*/
static std::unique_ptr<BroadcastDiscoveryPack> fromSerializedString(
const std::string& st,
rs_view_ptr<std::error_condition> ec )
rs_view_ptr<std::error_condition> ec = nullptr)
{
if(st.empty())
{
if(!ec)
{
RS_FATAL("Attempteted from empty string ", std::errc::no_message);
print_stacktrace();
exit(static_cast<int>(std::errc::no_message));
}
*ec = std::errc::no_message;
rs_error_bubble_or_exit(std::errc::no_message_available, ec);
return nullptr;
}
@ -98,15 +90,7 @@ struct BroadcastDiscoveryPack : RsSerializable
bdp->serial_process(RsGenericSerializer::DESERIALIZE, ctx);
if(ctx.mOk) return bdp;
if(!ec)
{
RS_FATAL( "Attempteted from invalid string ",
std::errc::invalid_argument );
print_stacktrace();
exit(static_cast<int>(std::errc::invalid_argument));
}
*ec = std::errc::invalid_argument;
rs_error_bubble_or_exit(std::errc::invalid_argument, ec);
return nullptr;
}
@ -125,7 +109,6 @@ struct BroadcastDiscoveryPack : RsSerializable
~BroadcastDiscoveryPack() override;
};
BroadcastDiscoveryService::BroadcastDiscoveryService(
RsPeers& pRsPeers ) :
mDiscoveredDataMutex("BroadcastDiscoveryService discovered data mutex"),
@ -203,9 +186,8 @@ void BroadcastDiscoveryService::threadTick()
currentMap[dEndpoint.ip_port()] = dEndpoint.user_data();
auto findIt = mDiscoveredData.find(dEndpoint.ip_port());
if( !dEndpoint.user_data().empty() && (
findIt == mDiscoveredData.end() ||
findIt->second != dEndpoint.user_data() ) )
if( findIt == mDiscoveredData.end() ||
findIt->second != dEndpoint.user_data() )
updateMap[dEndpoint.ip_port()] = dEndpoint.user_data();
}
mDiscoveredData = currentMap;
@ -258,9 +240,11 @@ BroadcastDiscoveryService::createResult(
const UDC::IpPort& ipp, const std::string& uData,
rs_view_ptr<std::error_condition> ec )
{
/* if ec is nullptr the error is treathed downstream otherwise upstream in
* any case should not be treated here */
/* On error we just return nullptr without handling it here because, it will
* either bubble up via ec or handled downstream if ec is nullptr.
* In any case it should not be treated here. */
auto bdp = BroadcastDiscoveryPack::fromSerializedString(uData, ec);
if(!bdp) return nullptr;
auto rbdr = std::make_unique<RsBroadcastDiscoveryResult>();
rbdr->mPgpFingerprint = bdp->mPgpFingerprint;

View File

@ -2,8 +2,8 @@
* RetroShare debugging utilities *
* *
* Copyright (C) 2004-2008 Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2019-2021 Gioacchino Mazzurco <gio@eigenlab.org> *
* Copyright (C) 2020-2021 Asociación Civil Altermundi <info@altermundi.net> *
* Copyright (C) 2019-2022 Gioacchino Mazzurco <gio@eigenlab.org> *
* Copyright (C) 2020-2022 Asociación Civil Altermundi <info@altermundi.net> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -35,6 +35,7 @@
#include "util/rsjson.h"
#include "util/rsmacrosugar.hpp"
#ifdef __ANDROID__
@ -71,7 +72,6 @@ std::string rsErrorNotInCategory(int errNum, const std::string& categoryName);
*/
std::error_condition rs_errno_to_condition(int errno_code);
template <RsLoggerCategories CATEGORY>
struct t_RsLogger : std::ostringstream
{
@ -254,9 +254,31 @@ struct hexDump {
}
};
/**
* @def rs_error_bubble_or_exit
* Bubbling up an error condition to be handled upstream if possible or dealing
* it fatally here, is a very common pattern, @see rs_malloc as an example, so
* instead of rewriting the same snippet over and over, increasing the
* possibility of introducing bugs, use this macro to properly deal with that
* situation.
* @param p_error_condition expect something convertible to an
* std::error_condition to be dealt with
* @param p_bubble_storage pointer to a location to store the
* std::error_condition to be bubbled up upstream, if it is nullptr the error
* will be handled with a fatal report end then exiting here
* @param ... optional additional information you want to be printed toghether
* with the error report when is fatal (aka not bubbled up) */
#define rs_error_bubble_or_exit(p_error_condition, p_bubble_storage, ... ) \
if(p_bubble_storage) \
{ \
*p_bubble_storage = p_error_condition; \
} \
else \
{ \
RS_FATAL(p_error_condition, " " RS_OPT_VA_ARGS(__VA_ARGS__)); \
print_stacktrace(); \
exit(std::error_condition(p_error_condition).value()); \
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
@ -266,15 +288,6 @@ struct hexDump {
#include "util/rsdeprecate.h"
/**
* Concatenate preprocessor tokens A and B without expanding macro definitions
* (however, if invoked from a macro, macro arguments are expanded).
*/
#define RS_CONCAT_MACRO_NX(A, B) A ## B
/// Concatenate preprocessor tokens A and B after macro-expanding them.
#define RS_CONCAT_MACRO(A, B) RS_CONCAT_MACRO_NX(A, B)
/**
* Set local context debug level.
* Avoid copy pasting boilerplate code around @see RsDbg for usage details

43
src/util/rsmacrosugar.hpp Normal file
View File

@ -0,0 +1,43 @@
/*******************************************************************************
* *
* libretroshare: retroshare core library *
* *
* Copyright (C) 2022 Gioacchino Mazzurco <gio@altermundi.net> *
* Copyright (C) 2022 Asociación Civil Altermundi <info@altermundi.net> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#pragma once
/** Comfortable optional variadic macro arguments
* @see https://www.appsloveworld.com/cplus/100/16/variadic-macros-with-zero-arguments
* C/C++ variadic macros gives error on expansion if no argument is passed, the
* result is that at least one argument must be passed or compilation fails.
* Wrapping __VA_ARGS__ in RS_OPT_VA_ARGS at expansion place omitting the comma
* before solves this issue rendering the variadic arguments effectively
* optionals.
*/
#define RS_OPT_VA_ARGS(...) , ##__VA_ARGS__
/**
* Concatenate preprocessor tokens A and B without expanding macro definitions
* (however, if invoked from a macro, macro arguments are expanded).
*/
#define RS_CONCAT_MACRO_NX(A, B) A ## B
/// Concatenate preprocessor tokens A and B after macro-expanding them.
#define RS_CONCAT_MACRO(A, B) RS_CONCAT_MACRO_NX(A, B)

View File

@ -4,8 +4,8 @@
* libretroshare: retroshare core library *
* *
* Copyright (C) 2012 Cyril Soler <csoler@users.sourceforge.net> *
* Copyright (C) 2019-2021 Gioacchino Mazzurco <gio@altermundi.net> *
* Copyright (C) 2021 Asociación Civil Altermundi <info@altermundi.net> *
* Copyright (C) 2019-2022 Gioacchino Mazzurco <gio@altermundi.net> *
* Copyright (C) 2021-2022 Asociación Civil Altermundi <info@altermundi.net> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -131,43 +131,27 @@ template<typename T = void> rs_owner_ptr<T> rs_malloc(
{
if(size == 0)
{
if(!ec)
{
RS_ERR("A chunk of size 0 was requested");
print_stacktrace();
exit(static_cast<int>(std::errc::invalid_argument));
}
*ec = std::errc::invalid_argument;
rs_error_bubble_or_exit(
std::errc::invalid_argument, ec,
"A chunk of size 0 was requested" );
return nullptr;
}
if(size > SAFE_MEMALLOC_THRESHOLD)
{
if(!ec)
{
RS_ERR( "A chunk of size larger than ", SAFE_MEMALLOC_THRESHOLD,
" was requested" );
print_stacktrace();
exit(static_cast<int>(std::errc::argument_out_of_domain));
}
*ec = std::errc::argument_out_of_domain;
rs_error_bubble_or_exit(
std::errc::argument_out_of_domain, ec,
"A chunk of size larger than ", SAFE_MEMALLOC_THRESHOLD,
" was requested" );
return nullptr;
}
void* mem = malloc(size);
if(!mem)
{
if(!ec)
{
RS_ERR( "Allocation failed for a chunk of ", size,
" bytes with: ", errno);
print_stacktrace();
exit(errno);
}
*ec = rs_errno_to_condition(errno);
rs_error_bubble_or_exit(
rs_errno_to_condition(errno), ec,
"malloc failed for a chunk of ", size, " bytes" );
return nullptr;
}