openwrt-packages/utils/domoticz/patches/991-linux_crash_when_format...

176 lines
6.4 KiB
Diff

From a9df45497dc79023ed1864dd9b8e435935220171 Mon Sep 17 00:00:00 2001
From: dnpwwo <kendel.boul@gmail.com>
Date: Tue, 1 Mar 2022 13:09:01 +1100
Subject: [PATCH] BugFix: Linux crash when formating Python exceptions Other:
Continue code cleanup
---
hardware/plugins/Plugins.cpp | 45 +++++++++++-------------------------
hardware/plugins/Plugins.h | 3 ++-
main/EventsPythonModule.cpp | 6 ++---
3 files changed, 18 insertions(+), 36 deletions(-)
--- a/hardware/plugins/Plugins.cpp
+++ b/hardware/plugins/Plugins.cpp
@@ -724,13 +724,7 @@ namespace Plugins
}
else
{
- std::string sTypeText("Unknown");
- if (pExcept)
- {
- PyTypeObject* TypeName = (PyTypeObject*)pExcept;
- PyNewRef pName = PyObject_GetAttrString((PyObject*)TypeName, "__name__");
- sTypeText = (std::string)pName;
- }
+ std::string sTypeText("Unknown Error");
/* See if we can get a full traceback */
PyNewRef pModule = PyImport_ImportModule("traceback");
@@ -738,7 +732,7 @@ namespace Plugins
{
PyNewRef pFunc = PyObject_GetAttrString(pModule, "format_exception");
if (pFunc && PyCallable_Check(pFunc)) {
- PyNewRef pList = PyObject_CallFunctionObjArgs(pFunc, pExcept, pValue, pTraceback, NULL);
+ PyNewRef pList = PyObject_CallFunctionObjArgs(pFunc, (PyObject*)pExcept, (PyObject*)pValue, (PyObject*)pTraceback, NULL);
if (pList)
{
for (Py_ssize_t i = 0; i < PyList_Size(pList); i++)
@@ -756,16 +750,19 @@ namespace Plugins
}
else
{
+ if (pExcept) sTypeText = pExcept.Attribute("__name__");
Log(LOG_ERROR, "Exception: '%s'. No traceback available.", sTypeText.c_str());
}
}
else
{
+ if (pExcept) sTypeText = pExcept.Attribute("__name__");
Log(LOG_ERROR, "'format_exception' lookup failed, exception: '%s'. No traceback available.", sTypeText.c_str());
}
}
else
{
+ if (pExcept) sTypeText = pExcept.Attribute("__name__");
Log(LOG_ERROR, "'Traceback' module import failed, exception: '%s'. No traceback available.", sTypeText.c_str());
}
}
@@ -1950,7 +1947,7 @@ namespace Plugins
}
}
- void CPlugin::Callback(PyObject *pTarget, const std::string &sHandler, PyObject *pParams)
+ void CPlugin::Callback(PyBorrowedRef& pTarget, const std::string &sHandler, PyObject *pParams)
{
try
{
@@ -1966,19 +1963,8 @@ namespace Plugins
PyNewRef pFunc = PyObject_GetAttrString(pTarget, sHandler.c_str());
if (pFunc && PyCallable_Check(pFunc))
{
- module_state *pModState = nullptr;
- PyBorrowedRef brModule = PyState_FindModule(&DomoticzModuleDef);
- if (!brModule)
- {
- brModule = PyState_FindModule(&DomoticzExModuleDef);
- }
-
- if (brModule)
- {
- pModState = ((struct module_state *)PyModule_GetState(brModule));
- }
-
// Store the callback object so the Dump function has context if invoked
+ module_state* pModState = FindModule();
if (pModState)
{
pModState->lastCallback = pTarget;
@@ -1986,14 +1972,12 @@ namespace Plugins
if (m_bDebug & PDM_QUEUE)
{
- PyNewRef pName = PyObject_GetAttrString((PyObject*)(pTarget->ob_type), "__name__");
- if (pName)
- Log(LOG_NORM, "Calling message handler '%s' on '%s' type object.", sHandler.c_str(), (std::string(pName).c_str()));
+ Log(LOG_NORM, "Calling message handler '%s' on '%s' type object.", sHandler.c_str(), pTarget.Type().c_str());
}
PyErr_Clear();
- // Invokde the callback function
+ // Invoke the callback function
PyNewRef pReturnValue = PyObject_CallObject(pFunc, pParams);
if (pModState)
@@ -2020,17 +2004,14 @@ namespace Plugins
std::string sAttrName = pItem;
if (sAttrName.substr(0, 2) != "__") // ignore system stuff
{
- if (PyObject_HasAttrString(pTarget, sAttrName.c_str()))
+ std::string strValue = pTarget.Attribute(sAttrName);
+ if (strValue.length())
{
PyNewRef pValue = PyObject_GetAttrString(pTarget, sAttrName.c_str());
if (!PyCallable_Check(pValue)) // Filter out methods
{
- std::string strValue = pValue;
- if (strValue.length())
- {
- std::string sBlank((sAttrName.length() < 20) ? 20 - sAttrName.length() : 0, ' ');
- Log(LOG_NORM, " ----> '%s'%s '%s'", sAttrName.c_str(), sBlank.c_str(), strValue.c_str());
- }
+ std::string sBlank((sAttrName.length() < 20) ? 20 - sAttrName.length() : 0, ' ');
+ Log(LOG_NORM, " ----> '%s'%s '%s'", sAttrName.c_str(), sBlank.c_str(), strValue.c_str());
}
}
}
--- a/hardware/plugins/Plugins.h
+++ b/hardware/plugins/Plugins.h
@@ -92,7 +92,7 @@ namespace Plugins {
void ConnectionWrite(CDirectiveBase *);
void ConnectionDisconnect(CDirectiveBase *);
void DisconnectEvent(CEventBase *);
- void Callback(PyObject* pTarget, const std::string &sHandler, PyObject *pParams);
+ void Callback(PyBorrowedRef& pTarget, const std::string &sHandler, PyObject *pParams);
void RestoreThread();
void ReleaseThread();
void Stop();
@@ -157,6 +157,7 @@ namespace Plugins {
m_pObject = pObject;
};
std::string Attribute(const char* name);
+ std::string Attribute(std::string& name) { return Attribute(name.c_str()); };
std::string Type();
bool IsDict() { return TypeCheck(Py_TPFLAGS_DICT_SUBCLASS); };
bool IsList() { return TypeCheck(Py_TPFLAGS_LIST_SUBCLASS); };
--- a/main/EventsPythonModule.cpp
+++ b/main/EventsPythonModule.cpp
@@ -297,7 +297,7 @@ namespace Plugins
PyBorrowedRef pModule = PythonEventsGetModule();
if (pModule)
{
- PyBorrowedRef pModuleDict = Plugins::PyModule_GetDict(pModule);
+ PyBorrowedRef pModuleDict = PyModule_GetDict(pModule);
if (!pModuleDict)
{
_log.Log(LOG_ERROR, "Python EventSystem: Failed to open module dictionary.");
@@ -312,7 +312,7 @@ namespace Plugins
return;
}
- PyNewRef pDeviceDict = Plugins::PyDict_New();
+ PyNewRef pDeviceDict = PyDict_New();
if (PyDict_SetItemString(pModuleDict, "Devices", pDeviceDict) == -1)
{
_log.Log(LOG_ERROR, "Python EventSystem: Failed to add Device dictionary.");
@@ -320,7 +320,7 @@ namespace Plugins
return;
}
- if (PyType_Ready((PyTypeObject*)Plugins::PDeviceType) < 0)
+ if (PyType_Ready((PyTypeObject*)PDeviceType) < 0)
{
_log.Log(LOG_ERROR, "Python EventSystem: Unable to ready DeviceType Object.");
PyEval_SaveThread();