}
HRESULT ManagedDebugger::SetBreakpoints(
- std::string filename,
+ const std::string& filename,
const std::vector<SourceBreakpoint> &srcBreakpoints,
std::vector<Breakpoint> &breakpoints)
{
return S_OK;
}
-HRESULT CLIProtocol::HandleCommand(std::string command,
+HRESULT CLIProtocol::HandleCommand(const std::string& command,
const std::vector<std::string> &args,
std::string &output)
{
HRESULT doRun(const std::vector<std::string> &args, std::string &output);
HRESULT doStep(const std::vector<std::string> &args, std::string &output);
HRESULT doSetArgs(const std::vector<std::string> &args, std::string &output);
- HRESULT HandleCommand(std::string command,
+ HRESULT HandleCommand(const std::string& command,
const std::vector<std::string> &args,
std::string &output);
virtual HRESULT Continue(ThreadId threadId) = 0;
virtual HRESULT Pause() = 0;
virtual HRESULT GetThreads(std::vector<Thread> &threads) = 0;
- virtual HRESULT SetBreakpoints(std::string filename, const std::vector<SourceBreakpoint> &srcBreakpoints, std::vector<Breakpoint> &breakpoints) = 0;
+ virtual HRESULT SetBreakpoints(const std::string& filename, const std::vector<SourceBreakpoint> &srcBreakpoints, std::vector<Breakpoint> &breakpoints) = 0;
virtual HRESULT SetFunctionBreakpoints(const std::vector<FunctionBreakpoint> &funcBreakpoints, std::vector<Breakpoint> &breakpoints) = 0;
virtual HRESULT GetStackTrace(ThreadId threadId, FrameLevel startFrame, unsigned maxFrames, std::vector<StackFrame> &stackFrames, int &totalFrames) = 0;
virtual HRESULT StepCommand(ThreadId threadId, StepType stepType) = 0;
}
}
-int IProtocol::GetIntArg(const std::vector<std::string> &args, const std::string name, int defaultValue)
+int IProtocol::GetIntArg(const std::vector<std::string> &args, const std::string& name, int defaultValue)
{
auto it = std::find(args.begin(), args.end(), name);
protected:
int ParseInt(const std::string &s, bool &ok);
void StripArgs(std::vector<std::string> &args);
- int GetIntArg(const std::vector<std::string> &args, const std::string name, int defaultValue);
+ int GetIntArg(const std::vector<std::string> &args, const std::string& name, int defaultValue);
bool GetIndices(const std::vector<std::string> &args, int &index1, int &index2);
BreakType GetBreakpointType(const std::vector<std::string> &args);
std::string GetConditionPrepareArgs(std::vector<std::string> &args);
#include <iomanip>
#include <chrono>
#include <stdio.h>
+#include <string.h>
#include "platform.h"
#include "logger.h"
+namespace
+{
+ template <typename Logger>
+ void log_via_va_args(Logger& logger, LogLevel level, const char *msg, ...)
+ {
+ va_list args;
+ va_start(args, msg);
+ logger.vlog(level, "%s", args);
+ va_end(args);
+ }
+}
+
+
#ifdef DEBUGGER_FOR_TIZEN
#include "dlog/dlog.h"
-
class DlogLogger : public LoggerImpl
{
private:
public:
DlogLogger() {}
~DlogLogger() override {}
- void log(LogLevel level, const std::string& msg) override;
- void vlog(LogLevel level, const std::string& fmt, va_list args) override;
+ void log(LogLevel level, const char *msg) override;
+ void vlog(LogLevel level, const char *fmt, va_list args) override;
};
log_priority DlogLogger::MapLogLevel(LogLevel level)
return DLOG_DEBUG;
}
-void DlogLogger::log(LogLevel level, const std::string &msg)
+void DlogLogger::log(LogLevel level, const char *msg)
{
- dlog_print(MapLogLevel(level), "NETCOREDBG", "%s", msg.c_str());
+ log_via_va_args(*this, level, "%s", msg);
}
-void DlogLogger::vlog(LogLevel level, const std::string &fmt, va_list args)
+void DlogLogger::vlog(LogLevel level, const char *fmt, va_list args)
{
- dlog_vprint(MapLogLevel(level), "NETCOREDBG", fmt.c_str(), args);
+ dlog_vprint(MapLogLevel(level), "NETCOREDBG", fmt, args);
}
+#endif // Tizen specific
-#endif
+const char *const levelNames[] =
+{
+ "DEBUG",
+ "INFO",
+ "WARN",
+ "ERROR"
+};
class NoLogger : public LoggerImpl
public:
NoLogger() {}
~NoLogger() override {}
- void log(LogLevel level, const std::string& msg) override {}
- void vlog(LogLevel level, const std::string& fmt, va_list args) override {}
+ void log(LogLevel level, const char *msg) override {}
+ void vlog(LogLevel level, const char *fmt, va_list args) override {}
};
class FileLogger : public LoggerImpl
{
private:
static const std::string filenameBase;
- static const std::string debugStr;
- static const std::string infoStr;
- static const std::string warnStr;
- static const std::string errorStr;
-
FILE *logFile;
- static std::string FormatMessageString(LogLevel level, const std::string &str);
- static const std::string& LevelToString(LogLevel level);
-
public:
FileLogger();
~FileLogger() override;
- void log(LogLevel level, const std::string& msg) override;
- void vlog(LogLevel level, const std::string& fmt, va_list args) override;
+ void log(LogLevel level, const char *msg) override;
+ void vlog(LogLevel level, const char *fmt, va_list args) override;
};
+
const std::string FileLogger::filenameBase = "netcoredbg_";
-const std::string FileLogger::debugStr = "DEBUG";
-const std::string FileLogger::infoStr = "INFO";
-const std::string FileLogger::warnStr = "WARN";
-const std::string FileLogger::errorStr = "ERROR";
+
static void get_local_time(std::tm *tm_snapshot)
{
fclose(logFile);
}
-const std::string& FileLogger::LevelToString(LogLevel level)
-{
- switch (level) {
- case LOG_INFO:
- return infoStr;
- case LOG_WARN:
- return warnStr;
- case LOG_ERROR:
- return errorStr;
- case LOG_DEBUG:
- default:
- return debugStr;
- }
-}
-std::string FileLogger::FormatMessageString(LogLevel level, const std::string &str)
+void FileLogger::log(LogLevel level, const char *msg)
{
- std::ostringstream oss;
- std::tm tm_snapshot;
- get_local_time(&tm_snapshot);
- oss << std::put_time(&tm_snapshot, "%y-%m-%d %OH:%OM:%OS") << " " << LevelToString(level) << " " << str << std::endl;
-
- return oss.str();
+ log_via_va_args(*this, level, "%s", msg);
}
-void FileLogger::log(LogLevel level, const std::string& msg)
+void FileLogger::vlog(LogLevel level, const char *fmt, va_list args)
{
- if (logFile != NULL) {
- fprintf(logFile, "%s", FormatMessageString(level, msg).c_str());
- fflush(logFile);
- }
-}
+ if (logFile == NULL) return;
-void FileLogger::vlog(LogLevel level, const std::string& fmt, va_list args)
-{
- if (logFile != NULL) {
- vfprintf(logFile, FormatMessageString(level, fmt).c_str(), args);
- fflush(logFile);
- }
-}
+ const char *level_name = (unsigned(level) < sizeof(levelNames)/sizeof(levelNames[0]))
+ ? levelNames[level] : levelNames[LOG_DEBUG];
+ std::tm tm;
+ get_local_time(&tm);
+ fprintf(logFile, "%04u-%02u-%02u %02u:%02u:%02u %s ",
+ tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, level_name);
+ vfprintf(logFile, fmt, args);
+ fputc('\n', logFile);
+ fflush(logFile);
+}
std::shared_ptr<LoggerImpl> Logger::logger = std::make_shared<NoLogger>();
-const std::string Logger::fileStr = "file";
-const std::string Logger::nologStr = "off";
-#ifdef DEBUGGER_FOR_TIZEN
-const std::string Logger::dlogStr = "dlog";
-#endif
-int Logger::setLogging(const std::string &type)
+
+int Logger::setLogging(const char *type)
{
- if (type == Logger::fileStr)
+ if (!strcmp(type, "file"))
{
logger = std::make_shared<FileLogger>();
}
#ifdef DEBUGGER_FOR_TIZEN
- else if (type == Logger::dlogStr)
+ else if (!strcmp(type, "dlog"))
{
logger = std::make_shared<DlogLogger>();
}
{
logger = std::make_shared<NoLogger>();
- if (type != Logger::nologStr)
+ if (strcmp(type, "off") != 0)
return -1;
}
return 0;
}
-void Logger::levelLog(LogLevel level, const std::string fmt, ...)
+void Logger::levelLog(LogLevel level, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
va_end(args);
}
-void Logger::log(const std::string fmt, ...)
+void Logger::log(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
va_end(args);
}
-FuncLogger Logger::getFuncLogger(const std::string &func)
+
+void FuncLogger::log(LoggerImpl *logger, LogLevel level, const char *fmt, ...)
{
- return FuncLogger(logger, func);
+ if (logger == nullptr) return;
+
+ va_list args;
+ va_start(args, fmt);
+ logger->vlog(level, fmt, args);
+ va_end(args);
}
#pragma once
-#include <string>
+#include <stdio.h>
#include <memory>
#include <cstdarg>
-
enum LogType {
NO_LOG = 0,
FILE_LOG,
{
public:
virtual ~LoggerImpl() {};
- virtual void vlog(LogLevel level, const std::string& fmt, va_list args) = 0;
- virtual void log(LogLevel level, const std::string& msg) = 0;
+ virtual void vlog(LogLevel level, const char *fmt, va_list args) = 0;
+ virtual void log(LogLevel level, const char *msg) = 0;
};
class FuncLogger
{
private:
const std::shared_ptr<LoggerImpl> &logger;
- const std::string func;
+ unsigned len;
+ const char *func;
+
+ void log(LoggerImpl* logger, LogLevel level, const char *fmt, ...);
public:
- FuncLogger(const std::shared_ptr<LoggerImpl> &logger, const std::string &func) : logger(logger), func(func)
+ FuncLogger(const std::shared_ptr<LoggerImpl> &logger, unsigned len, const char *func)
+ : logger(logger), len(len), func(func)
{
- logger->log(LOG_DEBUG, "> " + func);
+ log(logger.get(), LOG_DEBUG, "> %.*s", len, func);
}
~FuncLogger()
{
- logger->log(LOG_DEBUG, "< " + func);
+ log(logger.get(), LOG_DEBUG, "< %.*s", len, func);
}
};
class Logger
{
private:
- static const std::string fileStr;
- static const std::string nologStr;
-#ifdef DEBUGGER_FOR_TIZEN
- static const std::string dlogStr;
-#endif
-
static std::shared_ptr<LoggerImpl> logger;
public:
Logger() {}
- static int setLogging(const std::string &type);
- static void levelLog(LogLevel level, const std::string fmt, ...);
- static void log(const std::string fmt, ...);
- static FuncLogger getFuncLogger(const std::string &func);
+ static int setLogging(const char *type);
+ static void levelLog(LogLevel level, const char *fmt, ...);
+ static void log(const char *fmt, ...);
+
+ static FuncLogger getFuncLogger(unsigned len, const char *func)
+ {
+ return FuncLogger(logger, len, func);
+ }
};
#ifdef WIN32
#endif // WIN32
#define LogFuncEntry() \
- FuncLogger __funcLogger__ = Logger::getFuncLogger(std::string(__CROSS_FUNCTION__));
+ FuncLogger __funcLogger__ = Logger::getFuncLogger(sizeof(__CROSS_FUNCTION__)-1, __CROSS_FUNCTION__);
#define __FILENAME__ (strrchr(DIRECTORY_SEPARATOR_STR_A __FILE__, DIRECTORY_SEPARATOR_STR_A[0]) + 1)
-#define LogWithLine(fmt, ...) \
- Logger::log("[" + std::string(__FILENAME__) + ":" + std::to_string(__LINE__) + "] " + fmt, ##__VA_ARGS__);
-#define LogLevelWithLine(level, fmt, ...) \
- Logger::levelLog(level, "[" + std::string(__FILENAME__) + ":" + std::to_string(__LINE__) + "] " + fmt, ##__VA_ARGS__);
+namespace LoggerInternal
+{
+ template <size_t N>
+ constexpr size_t path_len(const char (&s)[N], size_t pos = N-1)
+ {
+ return (s[pos] == '/' || s[pos] == '\\') ? pos + 1 : pos ? path_len(s, pos - 1) : 0;
+ }
+}
+
+#define LogWithLine(fmt, ...) (false ? (void)printf((fmt), ##__VA_ARGS__) : \
+ Logger::log(("[%s:%u] " fmt),&__FILE__[LoggerInternal::path_len(__FILE__)], __LINE__, ##__VA_ARGS__))
+
+#define LogLevelWithLine(level, fmt, ...) (false ? (void)printf((fmt), ##__VA_ARGS__) : \
+ Logger::levelLog(level, ("[%s:%u] " fmt),&__FILE__[LoggerInternal::path_len(__FILE__)], __LINE__, ##__VA_ARGS__))
+
}
}
- if (Logger::setLogging(logType))
+ if (Logger::setLogging(logType.c_str()))
{
fprintf(stderr, "Error: Invalid log type\n");
return EXIT_FAILURE;
{
server.reset(new IORedirectServer (
serverPort,
- [&protocol](std::string text) { protocol->EmitOutputEvent(OutputEvent(OutputStdOut, text)); },
- [&protocol](std::string text) { protocol->EmitOutputEvent(OutputEvent(OutputStdOut, text)); }
+ [&protocol](const std::string& text) { protocol->EmitOutputEvent(OutputEvent(OutputStdOut, text)); },
+ [&protocol](const std::string& text) { protocol->EmitOutputEvent(OutputEvent(OutputStdOut, text)); }
));
}
- Logger::log("pidDebugee = " + std::to_string(pidDebuggee));
+ Logger::log("pidDebugee = %d", pidDebuggee);
if (pidDebuggee != 0)
{
debugger.Initialize();
return true;
}
-HRESULT ManagedDebugger::RunProcess(string fileExec, std::vector<string> execArgs)
+HRESULT ManagedDebugger::RunProcess(const string& fileExec, const std::vector<string>& execArgs)
{
static const auto startupCallbackWaitTimeout = std::chrono::milliseconds(5000);
HRESULT Status;
HRESULT GetStackTrace(ICorDebugThread *pThread, FrameLevel startFrame, unsigned maxFrames, std::vector<StackFrame> &stackFrames, int &totalFrames);
HRESULT GetFrameLocation(ICorDebugFrame *pFrame, ThreadId threadId, FrameLevel level, StackFrame &stackFrame);
- HRESULT RunProcess(std::string fileExec, std::vector<std::string> execArgs);
+ HRESULT RunProcess(const std::string& fileExec, const std::vector<std::string>& execArgs);
HRESULT AttachToProcess(DWORD pid);
HRESULT DetachFromProcess();
HRESULT TerminateProcess();
HRESULT Continue(ThreadId threadId) override;
HRESULT Pause() override;
HRESULT GetThreads(std::vector<Thread> &threads) override;
- HRESULT SetBreakpoints(std::string filename, const std::vector<SourceBreakpoint> &srcBreakpoints, std::vector<Breakpoint> &breakpoints) override;
+ HRESULT SetBreakpoints(const std::string& filename, const std::vector<SourceBreakpoint> &srcBreakpoints, std::vector<Breakpoint> &breakpoints) override;
HRESULT SetFunctionBreakpoints(const std::vector<FunctionBreakpoint> &funcBreakpoints, std::vector<Breakpoint> &breakpoints) override;
HRESULT GetStackTrace(ThreadId threadId, FrameLevel startFrame, unsigned maxFrames, std::vector<StackFrame> &stackFrames, int &totalFrames) override;
HRESULT StepCommand(ThreadId threadId, StepType stepType) override;
output = ss.str();
}
-void MIProtocol::PrintNewVar(std::string varobjName, Variable &v, ThreadId threadId, int print_values, std::string &output)
+void MIProtocol::PrintNewVar(const std::string& varobjName, Variable &v, ThreadId threadId, int print_values, std::string &output)
{
+ std::string name;
if (varobjName.empty() || varobjName == "-")
{
- varobjName = "var" + std::to_string(m_varCounter++);
+ name = "var" + std::to_string(m_varCounter++);
+ }
+ else {
+ name = varobjName;
}
- m_vars[varobjName] = v;
+ m_vars[name] = v;
- PrintVar(varobjName, v, threadId, print_values, output);
+ PrintVar(name, v, threadId, print_values, output);
}
HRESULT MIProtocol::CreateVar(ThreadId threadId, FrameLevel level, int evalFlags, const std::string &varobjName, const std::string &expression, std::string &output)
for (auto &child : children)
{
std::string varout;
- PrintNewVar("-", child, threadId, print_values, varout);
+ std::string minus("-");
+ PrintNewVar(minus, child, threadId, print_values, varout);
ss << sep;
sep = ",";
MIProtocol::EscapeMIValue(event.source).c_str());
}
-HRESULT MIProtocol::HandleCommand(std::string command,
+HRESULT MIProtocol::HandleCommand(const std::string& command,
const std::vector<std::string> &args,
std::string &output)
{
}
private:
- HRESULT HandleCommand(std::string command,
+ HRESULT HandleCommand(const std::string& command,
const std::vector<std::string> &args,
std::string &output);
HRESULT DeleteVar(const std::string &varobjName);
HRESULT FindVar(const std::string &varobjName, Variable &variable);
void PrintChildren(std::vector<Variable> &children, ThreadId threadId, int print_values, bool has_more, std::string &output);
- void PrintNewVar(std::string varobjName, Variable &v, ThreadId threadId, int print_values, std::string &output);
+ void PrintNewVar(const std::string& varobjName, Variable &v, ThreadId threadId, int print_values, std::string &output);
HRESULT ListChildren(ThreadId threadId, FrameLevel level, int childStart, int childEnd, const std::string &varName, int print_values, std::string &output);
HRESULT SetBreakpoint(const std::string &filename, int linenum, const std::string &condition, Breakpoint &breakpoints);
HRESULT SetFunctionBreakpoint(const std::string &module, const std::string &funcname, const std::string ¶ms, const std::string &condition, Breakpoint &breakpoint);
std::string name;
bool running;
- Thread(ThreadId id, std::string name, bool running) : id(id), name(name), running(running) {}
+ Thread(ThreadId id, const std::string& name, bool running) : id(id), name(name), running(running) {}
};
struct Source
std::string name;
std::string path;
- Source(std::string path = std::string()) : name(GetFileName(path)), path(path) {}
+ Source(const std::string& path = std::string()) : name(GetFileName(path)), path(path) {}
bool IsNull() const { return name.empty() && path.empty(); }
};
std::string source; // exposed for MI protocol
- OutputEvent(OutputCategory category, std::string output) : category(category), output(output) {}
+ OutputEvent(OutputCategory category, const std::string& output) : category(category), output(output) {}
};
enum ModuleReason
std::string name;
std::string ownerType;
ToRelease<ICorDebugValue> value;
- Member(const std::string &name, const std::string ownerType, ToRelease<ICorDebugValue> value) :
+ Member(const std::string &name, const std::string& ownerType, ToRelease<ICorDebugValue> value) :
name(name),
ownerType(ownerType),
value(std::move(value))