summaryrefslogtreecommitdiffstats
path: root/lldb/source/Commands/CommandObjectLog.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-06-08 16:52:24 +0000
committerChris Lattner <sabre@nondot.org>2010-06-08 16:52:24 +0000
commit30fdc8d841c9d24ac5f3d452b6ece84ee0ac991c (patch)
treef70013106f6a461a14abcd71c65f48a95a2979a6 /lldb/source/Commands/CommandObjectLog.cpp
parent312c4c799da215b337f790fda330f70c4aa757cf (diff)
downloadbcm5719-llvm-30fdc8d841c9d24ac5f3d452b6ece84ee0ac991c.tar.gz
bcm5719-llvm-30fdc8d841c9d24ac5f3d452b6ece84ee0ac991c.zip
Initial checkin of lldb code from internal Apple repo.
llvm-svn: 105619
Diffstat (limited to 'lldb/source/Commands/CommandObjectLog.cpp')
-rw-r--r--lldb/source/Commands/CommandObjectLog.cpp452
1 files changed, 452 insertions, 0 deletions
diff --git a/lldb/source/Commands/CommandObjectLog.cpp b/lldb/source/Commands/CommandObjectLog.cpp
new file mode 100644
index 00000000000..6b54badd7fc
--- /dev/null
+++ b/lldb/source/Commands/CommandObjectLog.cpp
@@ -0,0 +1,452 @@
+//===-- CommandObjectLog.cpp ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CommandObjectLog.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private-log.h"
+
+#include "lldb/Core/Args.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/FileSpec.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/Options.h"
+#include "lldb/Core/RegularExpression.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/StreamFile.h"
+#include "lldb/Core/Timer.h"
+
+#include "lldb/Interpreter/CommandContext.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+
+#include "lldb/Symbol/LineTable.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Symbol/SymbolVendor.h"
+
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+
+static LogChannelSP
+GetLogChannelPluginForChannel (const char *channel)
+{
+ std::string log_channel_plugin_name(channel);
+ log_channel_plugin_name += LogChannel::GetPluginSuffix();
+ LogChannelSP log_channel_sp (LogChannel::FindPlugin (log_channel_plugin_name.c_str()));
+ return log_channel_sp;
+}
+
+
+class CommandObjectLogEnable : public CommandObject
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ CommandObjectLogEnable() :
+ CommandObject ("log enable",
+ "Enable logging for a single log channel.",
+ "log enable [<cmd-options>] <channel>")
+ {
+ }
+
+ virtual
+ ~CommandObjectLogEnable()
+ {
+ }
+
+ Options *
+ GetOptions ()
+ {
+ return &m_options;
+ }
+
+ virtual bool
+ Execute (Args& args,
+ CommandContext *context,
+ CommandInterpreter *interpreter,
+ CommandReturnObject &result)
+ {
+ if (args.GetArgumentCount() < 1)
+ {
+ result.GetErrorStream() << m_cmd_syntax.c_str();
+ }
+ else
+ {
+ Log::Callbacks log_callbacks;
+
+ std::string channel(args.GetArgumentAtIndex(0));
+ args.Shift (); // Shift off the channel
+ StreamSP log_stream_sp;
+
+ if (m_options.log_file.empty())
+ {
+ std::string log_file("<lldb.debugger>");
+ LogStreamMap::iterator pos = m_log_streams.find(log_file);
+ if (pos == m_log_streams.end())
+ {
+ log_stream_sp = Log::GetStreamForSTDOUT ();
+ if (log_stream_sp)
+ m_log_streams[log_file] = log_stream_sp;
+ }
+ else
+ log_stream_sp = pos->second;
+ }
+ else
+ {
+ LogStreamMap::iterator pos = m_log_streams.find(m_options.log_file);
+ if (pos == m_log_streams.end())
+ {
+ log_stream_sp.reset (new StreamFile (m_options.log_file.c_str(), "w"));
+ m_log_streams[m_options.log_file] = log_stream_sp;
+ }
+ else
+ log_stream_sp = pos->second;
+ }
+ assert (log_stream_sp.get());
+ uint32_t log_options = m_options.log_options;
+ if (log_options == 0)
+ log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
+ if (Log::GetLogChannelCallbacks (channel.c_str(), log_callbacks))
+ {
+ log_callbacks.enable (log_stream_sp, log_options, args, &result.GetErrorStream());
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ }
+ else
+ {
+ LogChannelSP log_channel_sp (GetLogChannelPluginForChannel(channel.c_str()));
+ if (log_channel_sp)
+ {
+ if (log_channel_sp->Enable (log_stream_sp, log_options, &result.GetErrorStream(), args))
+ {
+ result.SetStatus (eReturnStatusSuccessFinishNoResult);
+ }
+ else
+ {
+ result.AppendErrorWithFormat("Invalid log channel '%s'.\n", channel.c_str());
+ result.SetStatus (eReturnStatusFailed);
+ }
+ }
+ else
+ {
+ result.AppendErrorWithFormat("Invalid log channel '%s'.\n", channel.c_str());
+ result.SetStatus (eReturnStatusFailed);
+ }
+ }
+ }
+ return result.Succeeded();
+ }
+
+
+ class CommandOptions : public Options
+ {
+ public:
+
+ CommandOptions () :
+ Options (),
+ log_file (),
+ log_options (0)
+ {
+ }
+
+
+ virtual
+ ~CommandOptions ()
+ {
+ }
+
+ virtual Error
+ SetOptionValue (int option_idx, const char *option_arg)
+ {
+ Error error;
+ char short_option = (char) m_getopt_table[option_idx].val;
+
+ switch (short_option)
+ {
+ case 'f': log_file = option_arg; break;
+ case 't': log_options |= LLDB_LOG_OPTION_THREADSAFE; break;
+ case 'v': log_options |= LLDB_LOG_OPTION_VERBOSE; break;
+ case 'g': log_options |= LLDB_LOG_OPTION_DEBUG; break;
+ case 's': log_options |= LLDB_LOG_OPTION_PREPEND_SEQUENCE; break;
+ case 'T': log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP; break;
+ case 'p': log_options |= LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD;break;
+ case 'n': log_options |= LLDB_LOG_OPTION_PREPEND_THREAD_NAME; break;
+ default:
+ error.SetErrorStringWithFormat ("Unrecognized option '%c'\n", short_option);
+ break;
+ }
+
+ return error;
+ }
+
+ void
+ ResetOptionValues ()
+ {
+ Options::ResetOptionValues();
+ log_file.clear();
+ log_options = 0;
+ }
+
+ const lldb::OptionDefinition*
+ GetDefinitions ()
+ {
+ return g_option_table;
+ }
+
+ // Options table: Required for subclasses of Options.
+
+ static lldb::OptionDefinition g_option_table[];
+
+ // Instance variables to hold the values for command options.
+
+ std::string log_file;
+ uint32_t log_options;
+ };
+
+protected:
+ typedef std::map<std::string, StreamSP> LogStreamMap;
+ CommandOptions m_options;
+ LogStreamMap m_log_streams;
+};
+
+lldb::OptionDefinition
+CommandObjectLogEnable::CommandOptions::g_option_table[] =
+{
+{ 0, false, "file", 'f', required_argument, NULL, 0, "<filename>", "Set the destination file to log to."},
+{ 0, false, "threadsafe", 't', no_argument, NULL, 0, NULL, "Enable thread safe logging to avoid interweaved log lines." },
+{ 0, false, "verbose", 'v', no_argument, NULL, 0, NULL, "Enable verbose logging." },
+{ 0, false, "debug", 'g', no_argument, NULL, 0, NULL, "Enable debug logging." },
+{ 0, false, "sequence", 's', no_argument, NULL, 0, NULL, "Prepend all log lines with an increasing integer sequence id." },
+{ 0, false, "timestamp", 'T', no_argument, NULL, 0, NULL, "Prepend all log lines with a timestamp." },
+{ 0, false, "pid-tid", 'p', no_argument, NULL, 0, NULL, "Prepend all log lines with the process and thread ID that generates the log line." },
+{ 0, false, "thread-name",'n', no_argument, NULL, 0, NULL, "Prepend all log lines with the thread name for the thread that generates the log line." },
+{ 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
+};
+
+class CommandObjectLogDisable : public CommandObject
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ CommandObjectLogDisable() :
+ CommandObject ("log disable",
+ "Disable one or more log channels.",
+ "log disable <channel> [<channel> ...]")
+ {
+ }
+
+ virtual
+ ~CommandObjectLogDisable()
+ {
+ }
+
+ virtual bool
+ Execute (Args& args,
+ CommandContext *context,
+ CommandInterpreter *interpreter,
+ CommandReturnObject &result)
+ {
+ const size_t argc = args.GetArgumentCount();
+ if (argc == 0)
+ {
+ result.GetErrorStream() << m_cmd_syntax.c_str();
+ }
+ else
+ {
+ for (size_t i=0; i<argc; ++i)
+ {
+ Log::Callbacks log_callbacks;
+
+ std::string channel(args.GetArgumentAtIndex(i));
+ if (Log::GetLogChannelCallbacks (channel.c_str(), log_callbacks))
+ {
+ log_callbacks.disable ();
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ }
+ else if (channel == "all")
+ {
+ Log::DisableAllLogChannels();
+ }
+ else
+ {
+ LogChannelSP log_channel_sp (GetLogChannelPluginForChannel(channel.c_str()));
+ if (log_channel_sp)
+ {
+ log_channel_sp->Disable();
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ }
+ else
+ result.AppendErrorWithFormat("Invalid log channel '%s'.\n", args.GetArgumentAtIndex(0));
+ }
+ }
+ }
+ return result.Succeeded();
+ }
+};
+
+class CommandObjectLogList : public CommandObject
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ CommandObjectLogList() :
+ CommandObject ("log list",
+ "List the log categories for one or more log channels.",
+ "log list <channel> [<channel> ...]")
+ {
+ }
+
+ virtual
+ ~CommandObjectLogList()
+ {
+ }
+
+ virtual bool
+ Execute (Args& args,
+ CommandContext *context,
+ CommandInterpreter *interpreter,
+ CommandReturnObject &result)
+ {
+ const size_t argc = args.GetArgumentCount();
+ if (argc == 0)
+ {
+ Log::ListAllLogChannels (&result.GetOutputStream());
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ }
+ else
+ {
+ for (size_t i=0; i<argc; ++i)
+ {
+ Log::Callbacks log_callbacks;
+
+ std::string channel(args.GetArgumentAtIndex(i));
+ if (Log::GetLogChannelCallbacks (channel.c_str(), log_callbacks))
+ {
+ log_callbacks.list_categories (&result.GetOutputStream());
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ }
+ else if (channel == "all")
+ {
+ Log::ListAllLogChannels (&result.GetOutputStream());
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ }
+ else
+ {
+ LogChannelSP log_channel_sp (GetLogChannelPluginForChannel(channel.c_str()));
+ if (log_channel_sp)
+ {
+ log_channel_sp->ListCategories(&result.GetOutputStream());
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ }
+ else
+ result.AppendErrorWithFormat("Invalid log channel '%s'.\n", args.GetArgumentAtIndex(0));
+ }
+ }
+ }
+ return result.Succeeded();
+ }
+};
+
+class CommandObjectLogTimer : public CommandObject
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ CommandObjectLogTimer() :
+ CommandObject ("log timers",
+ "Enable, disable, dump, and reset LLDB internal performance timers.",
+ "log timers < enable | disable | dump | reset >")
+ {
+ }
+
+ virtual
+ ~CommandObjectLogTimer()
+ {
+ }
+
+ virtual bool
+ Execute (Args& args,
+ CommandContext *context,
+ CommandInterpreter *interpreter,
+ CommandReturnObject &result)
+ {
+ const size_t argc = args.GetArgumentCount();
+ result.SetStatus(eReturnStatusFailed);
+
+ if (argc == 1)
+ {
+ const char *sub_command = args.GetArgumentAtIndex(0);
+
+ if (strcasecmp(sub_command, "enable") == 0)
+ {
+ Timer::SetDisplayDepth (UINT32_MAX);
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ }
+ else if (strcasecmp(sub_command, "disable") == 0)
+ {
+ Timer::DumpCategoryTimes (&result.GetOutputStream());
+ Timer::SetDisplayDepth (0);
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ }
+ else if (strcasecmp(sub_command, "dump") == 0)
+ {
+ Timer::DumpCategoryTimes (&result.GetOutputStream());
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ }
+ else if (strcasecmp(sub_command, "reset") == 0)
+ {
+ Timer::ResetCategoryTimes ();
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ }
+
+ }
+ if (!result.Succeeded())
+ {
+ result.AppendError("Missing subcommand");
+ result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str());
+ }
+ return result.Succeeded();
+ }
+};
+
+//----------------------------------------------------------------------
+// CommandObjectLog constructor
+//----------------------------------------------------------------------
+CommandObjectLog::CommandObjectLog(CommandInterpreter *interpreter) :
+ CommandObjectMultiword ("log",
+ "A set of commands for operating on logs.",
+ "log <command> [<command-options>]")
+{
+ LoadSubCommand (CommandObjectSP (new CommandObjectLogEnable), "enable", interpreter);
+ LoadSubCommand (CommandObjectSP (new CommandObjectLogDisable), "disable", interpreter);
+ LoadSubCommand (CommandObjectSP (new CommandObjectLogList), "list", interpreter);
+ LoadSubCommand (CommandObjectSP (new CommandObjectLogTimer), "timers", interpreter);
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+CommandObjectLog::~CommandObjectLog()
+{
+}
+
+
+
+
OpenPOWER on IntegriCloud