Skip to content

Commit

Permalink
Fix SIOF (Static initializer order Fiasco) with lazy initialization o…
Browse files Browse the repository at this point in the history
…f loggers:

`clStandardPaths::Get().GetUserDataDir()` (called from Logger constructor) requires that Application is set.
  • Loading branch information
Jarod42 committed Apr 9, 2024
1 parent c96ed55 commit bb270f5
Show file tree
Hide file tree
Showing 12 changed files with 109 additions and 107 deletions.
5 changes: 4 additions & 1 deletion CodeLite/LSP/basic_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ INITIALISE_MODULE_LOG(LSP_LOG_HANDLER, "LSP", "lsp.log");
namespace LSP
{

clModuleLogger& GetLogHandle() { return LSP_LOG_HANDLER; }
clModuleLogger& GetLogHandle()
{
return LSP_LOG_HANDLER();
}

wxString FileNameToURI(const wxString& filename)
{
Expand Down
24 changes: 13 additions & 11 deletions CodeLite/clModuleLogger.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ class WXDLLIMPEXP_CL clModuleLogger
clModuleLogger();
~clModuleLogger();

clModuleLogger(clModuleLogger&&) = default;
clModuleLogger& operator=(clModuleLogger&&) = default;

/// Set the module name
void SetModule(const wxString& name) { m_module = name; }

Expand Down Expand Up @@ -249,20 +252,19 @@ template <typename T> clModuleLogger& operator<<(clModuleLogger& logger, const T
#define INITIALISE_MODULE_LOG(LOG, MODULE_NAME, FILE_NAME) \
namespace \
{ \
thread_local clModuleLogger LOG; \
struct Init { \
Init() \
{ \
clModuleLogger& LOG() \
{ \
thread_local static clModuleLogger instance = []() { \
wxFileName logfile{ clStandardPaths::Get().GetUserDataDir(), FILE_NAME }; \
logfile.AppendDir("logs"); \
logfile.Mkdir(wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL); \
LOG.SetModule(MODULE_NAME); \
LOG.Open(logfile.GetFullPath()); \
} \
}; \
\
/*Initialise our logger (once per thread)*/ \
thread_local Init init; \
clModuleLogger logger; \
logger.SetModule(MODULE_NAME); \
logger.Open(logfile.GetFullPath()); \
return logger; \
}(); \
return instance; \
} \
}

#endif // CLMODULELOGGER_HPP
6 changes: 3 additions & 3 deletions CodeLite/ssh/clSSHChannel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ void clSSHChannel::Close()

if(m_hadErrors) {
// log this
LOG_DEBUG(LOG) << "ssh session had errors. discarding it" << endl;
LOG_DEBUG(LOG()) << "ssh session had errors. discarding it" << endl;

} else {
// put back the ssh session
Expand All @@ -140,7 +140,7 @@ IProcess::Ptr_t clSSHChannel::CreateAndExecuteScript(clSSH::Ptr_t ssh, clSSHDele
bool wantStderr)
{
if(!ssh::write_remote_file_content(ssh, script_path, content)) {
LOG_ERROR(LOG) << "failed to write remote file:" << script_path << endl;
LOG_ERROR(LOG()) << "failed to write remote file:" << script_path << endl;
return nullptr;
}
return Execute(ssh, std::move(deleter_cb), owner, script_path, wantStderr);
Expand All @@ -154,7 +154,7 @@ IProcess::Ptr_t clSSHChannel::Execute(clSSH::Ptr_t ssh, clSSHDeleterFunc deleter
channel = new clSSHChannel(ssh, std::move(deleter_cb), owner, wantStderr);
channel->Open();
} catch(clException& e) {
LOG_ERROR(LOG) << "failed to open channel." << e.What() << endl;
LOG_ERROR(LOG()) << "failed to open channel." << e.What() << endl;
wxDELETE(channel);
return nullptr;
}
Expand Down
8 changes: 4 additions & 4 deletions CodeLite/ssh/clSSHChannelCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,22 @@ void channel_read_internal(SSHChannel_t channel, ReadResult* result, bool isStde
int bytes = ssh_channel_read_timeout(channel, buffer, sizeof(buffer) - 1, isStderr ? 1 : 0, 1);
if(bytes == SSH_ERROR) {
// an error
LOG_DEBUG(LOG) << "channel read error" << endl;
LOG_DEBUG(LOG()) << "channel read error" << endl;
int exit_code = ssh_channel_get_exit_status(channel);
result->exit_code = exit_code;
result->rc = ssh::read_result::SSH_IO_ERROR;

} else if(bytes == SSH_EOF) {
// channel closed
LOG_DEBUG(LOG) << "channel read eof" << endl;
LOG_DEBUG(LOG()) << "channel read eof" << endl;
int exit_code = ssh_channel_get_exit_status(channel);
result->exit_code = exit_code;
result->rc = ssh::read_result::SSH_CONN_CLOSED;

} else if(bytes == 0) {
// timeout
if(ssh_channel_is_eof(channel)) {
LOG_DEBUG(LOG) << "channel eof detected" << endl;
LOG_DEBUG(LOG()) << "channel eof detected" << endl;
int exit_code = ssh_channel_get_exit_status(channel);
result->exit_code = exit_code;
result->rc = ssh::read_result::SSH_CONN_CLOSED;
Expand All @@ -63,7 +63,7 @@ void channel_read_internal(SSHChannel_t channel, ReadResult* result, bool isStde
result->rc = ssh::read_result::SSH_TIMEOUT;
}
} else {
LOG_DEBUG(LOG) << "read" << bytes << "bytes" << endl;
LOG_DEBUG(LOG()) << "read" << bytes << "bytes" << endl;
buffer[bytes] = 0;
result->exit_code = 0;
result->rc = ssh::read_result::SSH_SUCCESS;
Expand Down
78 changes: 39 additions & 39 deletions CodeLite/ssh/clSSHInteractiveChannel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,16 @@

INITIALISE_SSH_LOG(LOG, "Interactive-Channel");

#define CHECK_ARG(arg, msg) \
if(!(arg)) { \
LOG_WARNING(LOG) << msg << endl; \
return nullptr; \
#define CHECK_ARG(arg, msg) \
if(!(arg)) { \
LOG_WARNING(LOG()) << msg << endl; \
return nullptr; \
}

#define CHECK_ARG_VOID(arg, msg) \
if(!(arg)) { \
LOG_WARNING(LOG) << msg << endl; \
return; \
#define CHECK_ARG_VOID(arg, msg) \
if(!(arg)) { \
LOG_WARNING(LOG()) << msg << endl; \
return; \
}

namespace
Expand All @@ -46,12 +46,12 @@ struct CmdSignal {

std::thread* start_helper_thread(SSHChannel_t channel, wxEvtHandler* handler, wxMessageQueue<wxAny>& Q)
{
LOG_DEBUG(LOG) << "start_helper_thread is called" << endl;
LOG_DEBUG(LOG()) << "start_helper_thread is called" << endl;
// our helper thread
// 1) poll the channel for incoming data
// 2) poll the `Q` for data to write to the remote process
std::thread* thr = new std::thread([channel, &Q, handler]() mutable {
LOG_DEBUG(LOG) << "helper thread started" << endl;
LOG_DEBUG(LOG()) << "helper thread started" << endl;
while(true) {
// Poll the channel for output
auto stdout_res = ssh::channel_read(channel, handler, false, true);
Expand Down Expand Up @@ -79,11 +79,11 @@ std::thread* start_helper_thread(SSHChannel_t channel, wxEvtHandler* handler, wx
// fall: timeout
wxAny msg;
if(Q.ReceiveTimeout(1, msg) == wxMSGQUEUE_NO_ERROR) {
LOG_DEBUG(LOG) << "got request from the queue" << endl;
LOG_DEBUG(LOG()) << "got request from the queue" << endl;
// got a message
if(msg.CheckType<CmdShutdown>()) {
// shutdown, terminate the channel
LOG_DEBUG(LOG) << "shutting down" << endl;
LOG_DEBUG(LOG()) << "shutting down" << endl;
break;

} else if(msg.CheckType<CmdWrite>()) {
Expand All @@ -92,15 +92,15 @@ std::thread* start_helper_thread(SSHChannel_t channel, wxEvtHandler* handler, wx
CmdWrite write_command;
msg.GetAs(&write_command);

LOG_DEBUG(LOG) << "writing:" << write_command.content << endl;
LOG_DEBUG(LOG()) << "writing:" << write_command.content << endl;
int rc = ssh_channel_write(channel, write_command.content.c_str(), write_command.content.size());
if(rc != write_command.content.size()) {
LOG_WARNING(LOG) << "failed to write:" << write_command.content << "to ssh channel" << endl;
LOG_WARNING(LOG()) << "failed to write:" << write_command.content << "to ssh channel" << endl;
clCommandEvent event(wxEVT_SSH_CHANNEL_WRITE_ERROR);
handler->QueueEvent(event.Clone());
break;
} else {
LOG_DEBUG(LOG) << "successfully written:" << write_command.content << "to ssh channel" << endl;
LOG_DEBUG(LOG()) << "successfully written:" << write_command.content << "to ssh channel" << endl;
}

} else if(msg.CheckType<CmdSignal>()) {
Expand All @@ -109,23 +109,23 @@ std::thread* start_helper_thread(SSHChannel_t channel, wxEvtHandler* handler, wx
CmdSignal cmd;
msg.GetAs(&cmd);

LOG_DEBUG(LOG) << "sending signal:" << cmd.signal_prefix << endl;
LOG_DEBUG(LOG()) << "sending signal:" << cmd.signal_prefix << endl;
int rc = ssh_channel_request_send_signal(channel, cmd.signal_prefix.c_str());
if(rc != SSH_OK) {
LOG_WARNING(LOG) << "failed to send signal:" << cmd.signal_prefix << "to ssh channel" << endl;
LOG_WARNING(LOG()) << "failed to send signal:" << cmd.signal_prefix << "to ssh channel" << endl;
clCommandEvent event(wxEVT_SSH_CHANNEL_WRITE_ERROR);
handler->QueueEvent(event.Clone());
break;
} else {
LOG_DEBUG(LOG) << "successfully sent signal:" << cmd.signal_prefix << "to ssh channel" << endl;
LOG_DEBUG(LOG()) << "successfully sent signal:" << cmd.signal_prefix << "to ssh channel" << endl;
}

} else {
LOG_WARNING(LOG) << "received unknown command." << endl;
LOG_WARNING(LOG()) << "received unknown command." << endl;
}
}
}
LOG_DEBUG(LOG) << "helper thread is going down" << endl;
LOG_DEBUG(LOG()) << "helper thread is going down" << endl;
});
return thr;
}
Expand All @@ -150,32 +150,32 @@ clSSHInteractiveChannel::Ptr_t clSSHInteractiveChannel::Create(wxEvtHandler* par

wxString content = ssh::build_script_content(args, workingDir, envlist);
wxString remote_script = "/tmp/clssh_" + FileUtils::NormaliseFilename(args[0]);
LOG_DEBUG(LOG) << "executing remote script:" << remote_script << endl;
LOG_DEBUG(LOG()) << "executing remote script:" << remote_script << endl;
auto res = ssh::write_remote_file_content(ssh, remote_script, content);
if(!res) {
LOG_WARNING(LOG) << "SSH failed to write remote file." << res.error_message() << endl;
LOG_WARNING(LOG()) << "SSH failed to write remote file." << res.error_message() << endl;
return nullptr;
}

auto channel = ssh_channel_new(session);
if(!channel) {
LOG_WARNING(LOG) << "Failed to allocate new ssh channel." << ssh_get_error(session) << endl;
LOG_WARNING(LOG()) << "Failed to allocate new ssh channel." << ssh_get_error(session) << endl;
return nullptr;
}

// open the session
int rc = SSH_OK;
rc = ssh_channel_open_session(channel);
if(rc != SSH_OK) {
LOG_WARNING(LOG) << "Failed to open the session." << ssh_get_error(session) << endl;
LOG_WARNING(LOG()) << "Failed to open the session." << ssh_get_error(session) << endl;
ssh_channel_free(channel);
return nullptr;
}

// request a shell
rc = ssh_channel_request_shell(channel);
if(rc != SSH_OK) {
LOG_WARNING(LOG) << "SSH request shell error." << ssh_get_error(session) << endl;
LOG_WARNING(LOG()) << "SSH request shell error." << ssh_get_error(session) << endl;
ssh_channel_free(channel);
return nullptr;
}
Expand Down Expand Up @@ -210,7 +210,7 @@ clSSHInteractiveChannel::clSSHInteractiveChannel(wxEvtHandler* parent, clSSH::Pt

clSSHInteractiveChannel::~clSSHInteractiveChannel()
{
LOG_DEBUG(LOG) << "Unbinding events" << endl;
LOG_DEBUG(LOG()) << "Unbinding events" << endl;
Unbind(wxEVT_SSH_CHANNEL_WRITE_ERROR, &clSSHInteractiveChannel::OnChannelError, this);
Unbind(wxEVT_SSH_CHANNEL_READ_ERROR, &clSSHInteractiveChannel::OnChannelError, this);
Unbind(wxEVT_SSH_CHANNEL_READ_OUTPUT, &clSSHInteractiveChannel::OnChannelStdout, this);
Expand Down Expand Up @@ -304,7 +304,7 @@ bool clSSHInteractiveChannel::WriteRaw(const std::string& buff)

void clSSHInteractiveChannel::WaitForTerminate(wxString& output)
{
LOG_ERROR(LOG) << "WaitForTerminate is not supported for interactive shell commands" << endl;
LOG_ERROR(LOG()) << "WaitForTerminate is not supported for interactive shell commands" << endl;
}

bool clSSHInteractiveChannel::WriteToConsole(const wxString& buff) { return Write(buff); }
Expand Down Expand Up @@ -353,7 +353,7 @@ void clSSHInteractiveChannel::Signal(wxSignal sig)
break;
}
if(!prefix) {
LOG_ERROR(LOG) << "unknown signal" << endl;
LOG_ERROR(LOG()) << "unknown signal" << endl;
return;
}

Expand All @@ -363,20 +363,20 @@ void clSSHInteractiveChannel::Signal(wxSignal sig)

void clSSHInteractiveChannel::ResumeAsyncReads()
{
LOG_ERROR(LOG) << "ResumeAsyncReads is not supported for interactive shell commands" << endl;
LOG_ERROR(LOG()) << "ResumeAsyncReads is not supported for interactive shell commands" << endl;
}

void clSSHInteractiveChannel::SuspendAsyncReads()
{
LOG_ERROR(LOG) << "SuspendAsyncReads is not supported for interactive shell commands" << endl;
LOG_ERROR(LOG()) << "SuspendAsyncReads is not supported for interactive shell commands" << endl;
}

void clSSHInteractiveChannel::OnChannelStdout(clCommandEvent& event)
{
LOG_IF_DEBUG { LOG_DEBUG(LOG) << event.GetStringRaw() << endl; }
LOG_IF_DEBUG { LOG_DEBUG(LOG()) << event.GetStringRaw() << endl; }

if(!m_waiting) {
LOG_DEBUG(LOG) << "sending wxEVT_ASYNC_PROCESS_OUTPUT event" << endl;
LOG_DEBUG(LOG()) << "sending wxEVT_ASYNC_PROCESS_OUTPUT event" << endl;
clProcessEvent event_stdout{ wxEVT_ASYNC_PROCESS_OUTPUT };
event_stdout.SetProcess(nullptr);
event_stdout.SetOutputRaw(event.GetStringRaw());
Expand All @@ -392,7 +392,7 @@ void clSSHInteractiveChannel::OnChannelStdout(clCommandEvent& event)
m_waiting = false;

// found the marker
LOG_DEBUG(LOG) << "found the marker" << endl;
LOG_DEBUG(LOG()) << "found the marker" << endl;

// remove the marker from the input string
wxString remainder = m_waitingBuffer.substr(where + marker.length());
Expand All @@ -403,11 +403,11 @@ void clSSHInteractiveChannel::OnChannelStdout(clCommandEvent& event)
event_stdout.SetOutputRaw(StringUtils::ToStdString(remainder));
event_stdout.SetOutput(remainder);
AddPendingEvent(event_stdout);
LOG_DEBUG(LOG) << "stdout (active): `" << remainder << "`" << endl;
LOG_DEBUG(LOG()) << "stdout (active): `" << remainder << "`" << endl;
}
m_waitingBuffer.clear();
} else {
LOG_DEBUG(LOG) << "stdout (waiting): `" << event.GetStringRaw() << "`" << endl;
LOG_DEBUG(LOG()) << "stdout (waiting): `" << event.GetStringRaw() << "`" << endl;
}
}
}
Expand All @@ -421,9 +421,9 @@ void clSSHInteractiveChannel::OnChannelStderr(clCommandEvent& event)
event_stdout.SetOutputRaw(event.GetStringRaw());
event_stdout.SetOutput(event.GetStringRaw());
AddPendingEvent(event_stdout);
LOG_DEBUG(LOG) << "stderr (active): `" << event.GetStringRaw() << "`" << endl;
LOG_DEBUG(LOG()) << "stderr (active): `" << event.GetStringRaw() << "`" << endl;
} else {
LOG_DEBUG(LOG) << "stderr (waiting): `" << event.GetStringRaw() << "`" << endl;
LOG_DEBUG(LOG()) << "stderr (waiting): `" << event.GetStringRaw() << "`" << endl;
}
}

Expand All @@ -433,14 +433,14 @@ void clSSHInteractiveChannel::OnChannelClosed(clCommandEvent& event)
clProcessEvent event_terminated{ wxEVT_ASYNC_PROCESS_TERMINATED };
event_terminated.SetProcess(nullptr);
AddPendingEvent(event_terminated);
LOG_DEBUG(LOG) << "channel closed" << endl;
LOG_DEBUG(LOG()) << "channel closed" << endl;
m_closeEventFired = true;
}
}

void clSSHInteractiveChannel::OnChannelError(clCommandEvent& event)
{
LOG_DEBUG(LOG) << "channel error." << ssh_get_error(m_ssh->GetSession()) << endl;
LOG_DEBUG(LOG()) << "channel error." << ssh_get_error(m_ssh->GetSession()) << endl;
clProcessEvent event_terminated{ wxEVT_ASYNC_PROCESS_TERMINATED };
event_terminated.SetProcess(nullptr);
AddPendingEvent(event_terminated);
Expand Down
14 changes: 7 additions & 7 deletions Plugin/LSP/LSPNetworkRemoteSTDIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ void LSPNetworkRemoteSTDIO::DoClose()

void LSPNetworkRemoteSTDIO::DoStartRemoteProcess()
{
LOG_DEBUG(LOG) << "Starting remote process:" << endl;
LOG_DEBUG(LOG) << m_startupInfo.GetLspServerCommand() << endl;
LOG_DEBUG(LOG) << m_startupInfo.GetWorkingDirectory() << endl;
LOG_DEBUG(LOG()) << "Starting remote process:" << endl;
LOG_DEBUG(LOG()) << m_startupInfo.GetLspServerCommand() << endl;
LOG_DEBUG(LOG()) << m_startupInfo.GetWorkingDirectory() << endl;
for(const auto& p : m_startupInfo.GetEnv()) {
LOG_DEBUG(LOG) << p.first << "=" << p.second << endl;
LOG_DEBUG(LOG()) << p.first << "=" << p.second << endl;
}

m_process = clRemoteHost::Instance()->run_interactive_process(
Expand All @@ -48,9 +48,9 @@ void LSPNetworkRemoteSTDIO::DoStartRemoteProcess()

void LSPNetworkRemoteSTDIO::Send(const std::string& data)
{
LOG_IF_DEBUG { LOG_DEBUG(LOG) << ">" << data << endl; }
LOG_IF_DEBUG { LOG_DEBUG(LOG()) << ">" << data << endl; }
if(!m_process) {
LOG_WARNING(LOG) << "remote server is not running" << endl;
LOG_WARNING(LOG()) << "remote server is not running" << endl;
return;
}
m_process->WriteRaw(data);
Expand Down Expand Up @@ -88,7 +88,7 @@ void LSPNetworkRemoteSTDIO::OnProcessStderr(clProcessEvent& event)
void LSPNetworkRemoteSTDIO::BindEvents()
{
if(!m_process) {
LOG_WARNING(LOG) << "failed to bind events. process is not running" << endl;
LOG_WARNING(LOG()) << "failed to bind events. process is not running" << endl;
return;
}
if(!m_eventsBound) {
Expand Down
Loading

0 comments on commit bb270f5

Please sign in to comment.