mirror of https://github.com/AxioDL/metaforce.git
Add proper file-based error reporting
This commit is contained in:
parent
e17d5c0b83
commit
577af720d3
|
@ -3,9 +3,12 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <signal.h>
|
||||||
#include <system_error>
|
#include <system_error>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <chrono>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
#include <hecl/hecl.hpp>
|
#include <hecl/hecl.hpp>
|
||||||
#include <hecl/Database.hpp>
|
#include <hecl/Database.hpp>
|
||||||
|
@ -103,7 +106,7 @@ size_t BlenderConnection::_readLine(char* buf, size_t bufSz)
|
||||||
*buf = '\0';
|
*buf = '\0';
|
||||||
if (readBytes >= 4)
|
if (readBytes >= 4)
|
||||||
if (!memcmp(buf, "EXCEPTION", std::min(readBytes, size_t(9))))
|
if (!memcmp(buf, "EXCEPTION", std::min(readBytes, size_t(9))))
|
||||||
BlenderLog.report(logvisor::Fatal, "Blender exception");
|
_blenderDied();
|
||||||
return readBytes;
|
return readBytes;
|
||||||
}
|
}
|
||||||
++readBytes;
|
++readBytes;
|
||||||
|
@ -114,7 +117,7 @@ size_t BlenderConnection::_readLine(char* buf, size_t bufSz)
|
||||||
*buf = '\0';
|
*buf = '\0';
|
||||||
if (readBytes >= 4)
|
if (readBytes >= 4)
|
||||||
if (!memcmp(buf, "EXCEPTION", std::min(readBytes, size_t(9))))
|
if (!memcmp(buf, "EXCEPTION", std::min(readBytes, size_t(9))))
|
||||||
BlenderLog.report(logvisor::Fatal, "Blender exception");
|
_blenderDied();
|
||||||
return readBytes;
|
return readBytes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,7 +134,7 @@ size_t BlenderConnection::_writeLine(const char* buf)
|
||||||
goto err;
|
goto err;
|
||||||
return (size_t)ret;
|
return (size_t)ret;
|
||||||
err:
|
err:
|
||||||
BlenderLog.report(logvisor::Fatal, strerror(errno));
|
_blenderDied();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,10 +145,10 @@ size_t BlenderConnection::_readBuf(void* buf, size_t len)
|
||||||
goto err;
|
goto err;
|
||||||
if (len >= 4)
|
if (len >= 4)
|
||||||
if (!memcmp((char*)buf, "EXCEPTION", std::min(len, size_t(9))))
|
if (!memcmp((char*)buf, "EXCEPTION", std::min(len, size_t(9))))
|
||||||
BlenderLog.report(logvisor::Fatal, "Blender exception");
|
_blenderDied();
|
||||||
return ret;
|
return ret;
|
||||||
err:
|
err:
|
||||||
BlenderLog.report(logvisor::Fatal, strerror(errno));
|
_blenderDied();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +159,7 @@ size_t BlenderConnection::_writeBuf(const void* buf, size_t len)
|
||||||
goto err;
|
goto err;
|
||||||
return ret;
|
return ret;
|
||||||
err:
|
err:
|
||||||
BlenderLog.report(logvisor::Fatal, strerror(errno));
|
_blenderDied();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,9 +169,30 @@ void BlenderConnection::_closePipe()
|
||||||
close(m_writepipe[1]);
|
close(m_writepipe[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BlenderConnection::_blenderDied()
|
||||||
|
{
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
|
FILE* errFp = hecl::Fopen(m_errPath.c_str(), _S("r"));
|
||||||
|
if (errFp)
|
||||||
|
{
|
||||||
|
fseek(errFp, 0, SEEK_END);
|
||||||
|
int64_t len = hecl::FTell(errFp);
|
||||||
|
if (len)
|
||||||
|
{
|
||||||
|
fseek(errFp, 0, SEEK_SET);
|
||||||
|
std::unique_ptr<char[]> buf(new char[len+1]);
|
||||||
|
memset(buf.get(), 0, len+1);
|
||||||
|
fread(buf.get(), 1, len, errFp);
|
||||||
|
BlenderLog.report(logvisor::Fatal, "\n%s", buf.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BlenderLog.report(logvisor::Fatal, "Blender Exception");
|
||||||
|
}
|
||||||
|
|
||||||
BlenderConnection::BlenderConnection(int verbosityLevel)
|
BlenderConnection::BlenderConnection(int verbosityLevel)
|
||||||
{
|
{
|
||||||
BlenderLog.report(logvisor::Info, "Establishing BlenderConnection...");
|
BlenderLog.report(logvisor::Info, "Establishing BlenderConnection...");
|
||||||
|
signal(SIGPIPE, SIG_IGN);
|
||||||
|
|
||||||
/* Put hecl_blendershell.py in temp dir */
|
/* Put hecl_blendershell.py in temp dir */
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -320,6 +344,10 @@ BlenderConnection::BlenderConnection(int verbosityLevel)
|
||||||
m_blenderProc = pid;
|
m_blenderProc = pid;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Stash error path an unlink existing file */
|
||||||
|
m_errPath = hecl::SystemString(TMPDIR) + hecl::Format(_S("/hecl_%016llX.derp"), (unsigned long long)m_blenderProc);
|
||||||
|
hecl::Unlink(m_errPath.c_str());
|
||||||
|
|
||||||
/* Handle first response */
|
/* Handle first response */
|
||||||
char lineBuf[256];
|
char lineBuf[256];
|
||||||
_readLine(lineBuf, sizeof(lineBuf));
|
_readLine(lineBuf, sizeof(lineBuf));
|
||||||
|
@ -398,7 +426,7 @@ BlenderConnection::PyOutStream::StreamBuf::overflow(int_type ch)
|
||||||
{
|
{
|
||||||
if (m_deleteOnError)
|
if (m_deleteOnError)
|
||||||
m_parent.m_parent->deleteBlend();
|
m_parent.m_parent->deleteBlend();
|
||||||
BlenderLog.report(logvisor::Fatal, "error sending '%s' to blender", m_lineBuf.c_str());
|
m_parent.m_parent->_blenderDied();
|
||||||
}
|
}
|
||||||
m_lineBuf.clear();
|
m_lineBuf.clear();
|
||||||
return ch;
|
return ch;
|
||||||
|
|
|
@ -61,11 +61,13 @@ private:
|
||||||
bool m_loadedRigged = false;
|
bool m_loadedRigged = false;
|
||||||
ProjectPath m_loadedBlend;
|
ProjectPath m_loadedBlend;
|
||||||
std::string m_startupBlend;
|
std::string m_startupBlend;
|
||||||
|
hecl::SystemString m_errPath;
|
||||||
size_t _readLine(char* buf, size_t bufSz);
|
size_t _readLine(char* buf, size_t bufSz);
|
||||||
size_t _writeLine(const char* buf);
|
size_t _writeLine(const char* buf);
|
||||||
size_t _readBuf(void* buf, size_t len);
|
size_t _readBuf(void* buf, size_t len);
|
||||||
size_t _writeBuf(const void* buf, size_t len);
|
size_t _writeBuf(const void* buf, size_t len);
|
||||||
void _closePipe();
|
void _closePipe();
|
||||||
|
void _blenderDied();
|
||||||
public:
|
public:
|
||||||
BlenderConnection(int verbosityLevel=1);
|
BlenderConnection(int verbosityLevel=1);
|
||||||
~BlenderConnection();
|
~BlenderConnection();
|
||||||
|
|
|
@ -10,10 +10,19 @@ args = sys.argv[sys.argv.index('--')+1:]
|
||||||
readfd = int(args[0])
|
readfd = int(args[0])
|
||||||
writefd = int(args[1])
|
writefd = int(args[1])
|
||||||
verbosity_level = int(args[2])
|
verbosity_level = int(args[2])
|
||||||
|
err_path = ""
|
||||||
if sys.platform == "win32":
|
if sys.platform == "win32":
|
||||||
import msvcrt
|
import msvcrt
|
||||||
readfd = msvcrt.open_osfhandle(readfd, os.O_RDONLY | os.O_BINARY)
|
readfd = msvcrt.open_osfhandle(readfd, os.O_RDONLY | os.O_BINARY)
|
||||||
writefd = msvcrt.open_osfhandle(writefd, os.O_WRONLY | os.O_BINARY)
|
writefd = msvcrt.open_osfhandle(writefd, os.O_WRONLY | os.O_BINARY)
|
||||||
|
err_path = "/Temp"
|
||||||
|
else:
|
||||||
|
err_path = "/tmp"
|
||||||
|
|
||||||
|
if 'TMPDIR' in os.environ:
|
||||||
|
err_path = os.environ['TMPDIR']
|
||||||
|
|
||||||
|
err_path += "/hecl_%016X.derp" % os.getpid()
|
||||||
|
|
||||||
def readpipeline():
|
def readpipeline():
|
||||||
retval = bytearray()
|
retval = bytearray()
|
||||||
|
@ -230,6 +239,8 @@ def dataout_loop():
|
||||||
writepipebuf(struct.pack('f', c))
|
writepipebuf(struct.pack('f', c))
|
||||||
|
|
||||||
|
|
||||||
|
# Main exception handling
|
||||||
|
try:
|
||||||
# Command loop
|
# Command loop
|
||||||
while True:
|
while True:
|
||||||
cmdargs = read_cmdargs()
|
cmdargs = read_cmdargs()
|
||||||
|
@ -352,3 +363,9 @@ while True:
|
||||||
else:
|
else:
|
||||||
hecl.command(cmdargs, writepipeline, writepipebuf)
|
hecl.command(cmdargs, writepipeline, writepipebuf)
|
||||||
|
|
||||||
|
except Exception:
|
||||||
|
import traceback
|
||||||
|
fout = open(err_path, 'w')
|
||||||
|
traceback.print_exc(file=fout)
|
||||||
|
fout.close()
|
||||||
|
raise
|
||||||
|
|
Loading…
Reference in New Issue