blob: 8a1688e7052c1a3c1dd39592b00cf45bee971452 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- CommandObjectLog.cpp ------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "CommandObjectLog.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "lldb/lldb-private-log.h"
17
Jim Ingham84cdc152010-06-15 19:49:27 +000018#include "lldb/Interpreter/Args.h"
Chris Lattner24943d22010-06-08 16:52:24 +000019#include "lldb/Core/Debugger.h"
Greg Clayton5f54ac32011-02-08 05:05:52 +000020#include "lldb/Host/FileSpec.h"
Chris Lattner24943d22010-06-08 16:52:24 +000021#include "lldb/Core/Log.h"
22#include "lldb/Core/Module.h"
Jim Ingham84cdc152010-06-15 19:49:27 +000023#include "lldb/Interpreter/Options.h"
Chris Lattner24943d22010-06-08 16:52:24 +000024#include "lldb/Core/RegularExpression.h"
25#include "lldb/Core/Stream.h"
26#include "lldb/Core/StreamFile.h"
27#include "lldb/Core/Timer.h"
28
Greg Clayton63094e02010-06-23 01:19:29 +000029#include "lldb/Core/Debugger.h"
Sean Callanan705d6782010-06-23 21:28:25 +000030#include "lldb/Interpreter/CommandInterpreter.h"
Chris Lattner24943d22010-06-08 16:52:24 +000031#include "lldb/Interpreter/CommandReturnObject.h"
32
33#include "lldb/Symbol/LineTable.h"
34#include "lldb/Symbol/ObjectFile.h"
35#include "lldb/Symbol/SymbolFile.h"
36#include "lldb/Symbol/SymbolVendor.h"
37
38#include "lldb/Target/Process.h"
39#include "lldb/Target/Target.h"
40
41using namespace lldb;
42using namespace lldb_private;
43
44
Chris Lattner24943d22010-06-08 16:52:24 +000045class CommandObjectLogEnable : public CommandObject
46{
47public:
48 //------------------------------------------------------------------
49 // Constructors and Destructors
50 //------------------------------------------------------------------
Greg Clayton238c0a12010-09-18 01:14:36 +000051 CommandObjectLogEnable(CommandInterpreter &interpreter) :
52 CommandObject (interpreter,
53 "log enable",
Chris Lattner24943d22010-06-08 16:52:24 +000054 "Enable logging for a single log channel.",
Greg Claytonf15996e2011-04-07 22:46:35 +000055 NULL),
56 m_options (interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +000057 {
Caroline Tice7826c882010-10-26 03:11:13 +000058
59 CommandArgumentEntry arg1;
60 CommandArgumentEntry arg2;
Caroline Tice43b014a2010-10-04 22:28:36 +000061 CommandArgumentData channel_arg;
Caroline Tice7826c882010-10-26 03:11:13 +000062 CommandArgumentData category_arg;
Caroline Tice43b014a2010-10-04 22:28:36 +000063
64 // Define the first (and only) variant of this arg.
65 channel_arg.arg_type = eArgTypeLogChannel;
66 channel_arg.arg_repetition = eArgRepeatPlain;
67
68 // There is only one variant this argument could be; put it into the argument entry.
Caroline Tice7826c882010-10-26 03:11:13 +000069 arg1.push_back (channel_arg);
Caroline Tice43b014a2010-10-04 22:28:36 +000070
Caroline Tice7826c882010-10-26 03:11:13 +000071 category_arg.arg_type = eArgTypeLogCategory;
72 category_arg.arg_repetition = eArgRepeatPlus;
73
74 arg2.push_back (category_arg);
75
Caroline Tice43b014a2010-10-04 22:28:36 +000076 // Push the data for the first argument into the m_arguments vector.
Caroline Tice7826c882010-10-26 03:11:13 +000077 m_arguments.push_back (arg1);
78 m_arguments.push_back (arg2);
Chris Lattner24943d22010-06-08 16:52:24 +000079 }
80
81 virtual
82 ~CommandObjectLogEnable()
83 {
84 }
85
86 Options *
87 GetOptions ()
88 {
89 return &m_options;
90 }
91
Greg Clayton5e342f52011-04-13 22:47:15 +000092// int
93// HandleArgumentCompletion (Args &input,
94// int &cursor_index,
95// int &cursor_char_position,
96// OptionElementVector &opt_element_vector,
97// int match_start_point,
98// int max_return_elements,
99// bool &word_complete,
100// StringList &matches)
101// {
102// std::string completion_str (input.GetArgumentAtIndex(cursor_index));
103// completion_str.erase (cursor_char_position);
104//
105// if (cursor_index == 1)
106// {
107// //
108// Log::AutoCompleteChannelName (completion_str.c_str(), matches);
109// }
110// return matches.GetSize();
111// }
112//
Chris Lattner24943d22010-06-08 16:52:24 +0000113 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000114 Execute (Args& args,
Chris Lattner24943d22010-06-08 16:52:24 +0000115 CommandReturnObject &result)
116 {
117 if (args.GetArgumentCount() < 1)
118 {
Caroline Ticeabb507a2010-09-08 21:06:11 +0000119 result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str());
Chris Lattner24943d22010-06-08 16:52:24 +0000120 }
121 else
122 {
123 Log::Callbacks log_callbacks;
124
125 std::string channel(args.GetArgumentAtIndex(0));
126 args.Shift (); // Shift off the channel
127 StreamSP log_stream_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000128 if (m_options.log_file.empty())
129 {
Greg Clayton58928562011-02-09 01:08:52 +0000130 log_stream_sp.reset(new StreamFile(m_interpreter.GetDebugger().GetOutputFile().GetDescriptor(), false));
Chris Lattner24943d22010-06-08 16:52:24 +0000131 }
132 else
133 {
134 LogStreamMap::iterator pos = m_log_streams.find(m_options.log_file);
135 if (pos == m_log_streams.end())
136 {
Greg Clayton58928562011-02-09 01:08:52 +0000137 log_stream_sp.reset (new StreamFile (m_options.log_file.c_str()));
Chris Lattner24943d22010-06-08 16:52:24 +0000138 m_log_streams[m_options.log_file] = log_stream_sp;
139 }
140 else
141 log_stream_sp = pos->second;
142 }
143 assert (log_stream_sp.get());
Jim Inghamd1eb73f2011-01-24 04:09:25 +0000144
Chris Lattner24943d22010-06-08 16:52:24 +0000145 uint32_t log_options = m_options.log_options;
146 if (log_options == 0)
147 log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
148 if (Log::GetLogChannelCallbacks (channel.c_str(), log_callbacks))
149 {
150 log_callbacks.enable (log_stream_sp, log_options, args, &result.GetErrorStream());
151 result.SetStatus(eReturnStatusSuccessFinishNoResult);
152 }
153 else
154 {
Greg Clayton5e342f52011-04-13 22:47:15 +0000155 LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel.c_str()));
Chris Lattner24943d22010-06-08 16:52:24 +0000156 if (log_channel_sp)
157 {
158 if (log_channel_sp->Enable (log_stream_sp, log_options, &result.GetErrorStream(), args))
159 {
160 result.SetStatus (eReturnStatusSuccessFinishNoResult);
161 }
162 else
163 {
164 result.AppendErrorWithFormat("Invalid log channel '%s'.\n", channel.c_str());
165 result.SetStatus (eReturnStatusFailed);
166 }
167 }
168 else
169 {
170 result.AppendErrorWithFormat("Invalid log channel '%s'.\n", channel.c_str());
171 result.SetStatus (eReturnStatusFailed);
172 }
173 }
174 }
175 return result.Succeeded();
176 }
177
178
179 class CommandOptions : public Options
180 {
181 public:
182
Greg Claytonf15996e2011-04-07 22:46:35 +0000183 CommandOptions (CommandInterpreter &interpreter) :
184 Options (interpreter),
Chris Lattner24943d22010-06-08 16:52:24 +0000185 log_file (),
186 log_options (0)
187 {
188 }
189
190
191 virtual
192 ~CommandOptions ()
193 {
194 }
195
196 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000197 SetOptionValue (uint32_t option_idx, const char *option_arg)
Chris Lattner24943d22010-06-08 16:52:24 +0000198 {
199 Error error;
200 char short_option = (char) m_getopt_table[option_idx].val;
201
202 switch (short_option)
203 {
204 case 'f': log_file = option_arg; break;
205 case 't': log_options |= LLDB_LOG_OPTION_THREADSAFE; break;
206 case 'v': log_options |= LLDB_LOG_OPTION_VERBOSE; break;
207 case 'g': log_options |= LLDB_LOG_OPTION_DEBUG; break;
208 case 's': log_options |= LLDB_LOG_OPTION_PREPEND_SEQUENCE; break;
209 case 'T': log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP; break;
210 case 'p': log_options |= LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD;break;
211 case 'n': log_options |= LLDB_LOG_OPTION_PREPEND_THREAD_NAME; break;
212 default:
Greg Clayton9c236732011-10-26 00:56:27 +0000213 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
Chris Lattner24943d22010-06-08 16:52:24 +0000214 break;
215 }
216
217 return error;
218 }
219
220 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000221 OptionParsingStarting ()
Chris Lattner24943d22010-06-08 16:52:24 +0000222 {
Chris Lattner24943d22010-06-08 16:52:24 +0000223 log_file.clear();
224 log_options = 0;
225 }
226
Greg Claytonb3448432011-03-24 21:19:54 +0000227 const OptionDefinition*
Chris Lattner24943d22010-06-08 16:52:24 +0000228 GetDefinitions ()
229 {
230 return g_option_table;
231 }
232
233 // Options table: Required for subclasses of Options.
234
Greg Claytonb3448432011-03-24 21:19:54 +0000235 static OptionDefinition g_option_table[];
Chris Lattner24943d22010-06-08 16:52:24 +0000236
237 // Instance variables to hold the values for command options.
238
239 std::string log_file;
240 uint32_t log_options;
241 };
242
243protected:
244 typedef std::map<std::string, StreamSP> LogStreamMap;
245 CommandOptions m_options;
246 LogStreamMap m_log_streams;
247};
248
Greg Claytonb3448432011-03-24 21:19:54 +0000249OptionDefinition
Chris Lattner24943d22010-06-08 16:52:24 +0000250CommandObjectLogEnable::CommandOptions::g_option_table[] =
251{
Caroline Tice4d6675c2010-10-01 19:59:14 +0000252{ LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, 0, eArgTypeFilename, "Set the destination file to log to."},
253{ LLDB_OPT_SET_1, false, "threadsafe", 't', no_argument, NULL, 0, eArgTypeNone, "Enable thread safe logging to avoid interweaved log lines." },
254{ LLDB_OPT_SET_1, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone, "Enable verbose logging." },
255{ LLDB_OPT_SET_1, false, "debug", 'g', no_argument, NULL, 0, eArgTypeNone, "Enable debug logging." },
256{ LLDB_OPT_SET_1, false, "sequence", 's', no_argument, NULL, 0, eArgTypeNone, "Prepend all log lines with an increasing integer sequence id." },
257{ LLDB_OPT_SET_1, false, "timestamp", 'T', no_argument, NULL, 0, eArgTypeNone, "Prepend all log lines with a timestamp." },
258{ LLDB_OPT_SET_1, false, "pid-tid", 'p', no_argument, NULL, 0, eArgTypeNone, "Prepend all log lines with the process and thread ID that generates the log line." },
259{ LLDB_OPT_SET_1, false, "thread-name",'n', no_argument, NULL, 0, eArgTypeNone, "Prepend all log lines with the thread name for the thread that generates the log line." },
260{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +0000261};
262
263class CommandObjectLogDisable : public CommandObject
264{
265public:
266 //------------------------------------------------------------------
267 // Constructors and Destructors
268 //------------------------------------------------------------------
Greg Clayton238c0a12010-09-18 01:14:36 +0000269 CommandObjectLogDisable(CommandInterpreter &interpreter) :
270 CommandObject (interpreter,
271 "log disable",
Caroline Tice6a9e5c22010-10-29 21:56:41 +0000272 "Disable one or more log channel categories.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000273 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000274 {
Caroline Tice6a9e5c22010-10-29 21:56:41 +0000275 CommandArgumentEntry arg1;
276 CommandArgumentEntry arg2;
Caroline Tice43b014a2010-10-04 22:28:36 +0000277 CommandArgumentData channel_arg;
Caroline Tice6a9e5c22010-10-29 21:56:41 +0000278 CommandArgumentData category_arg;
Caroline Tice43b014a2010-10-04 22:28:36 +0000279
280 // Define the first (and only) variant of this arg.
281 channel_arg.arg_type = eArgTypeLogChannel;
Caroline Tice6a9e5c22010-10-29 21:56:41 +0000282 channel_arg.arg_repetition = eArgRepeatPlain;
Caroline Tice43b014a2010-10-04 22:28:36 +0000283
284 // There is only one variant this argument could be; put it into the argument entry.
Caroline Tice6a9e5c22010-10-29 21:56:41 +0000285 arg1.push_back (channel_arg);
Caroline Tice43b014a2010-10-04 22:28:36 +0000286
Caroline Tice6a9e5c22010-10-29 21:56:41 +0000287 category_arg.arg_type = eArgTypeLogCategory;
288 category_arg.arg_repetition = eArgRepeatPlus;
289
290 arg2.push_back (category_arg);
291
Caroline Tice43b014a2010-10-04 22:28:36 +0000292 // Push the data for the first argument into the m_arguments vector.
Caroline Tice6a9e5c22010-10-29 21:56:41 +0000293 m_arguments.push_back (arg1);
294 m_arguments.push_back (arg2);
Chris Lattner24943d22010-06-08 16:52:24 +0000295 }
296
297 virtual
298 ~CommandObjectLogDisable()
299 {
300 }
301
302 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000303 Execute (Args& args,
Chris Lattner24943d22010-06-08 16:52:24 +0000304 CommandReturnObject &result)
305 {
306 const size_t argc = args.GetArgumentCount();
307 if (argc == 0)
308 {
Caroline Ticeabb507a2010-09-08 21:06:11 +0000309 result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str());
Chris Lattner24943d22010-06-08 16:52:24 +0000310 }
311 else
312 {
Caroline Tice926060e2010-10-29 21:48:37 +0000313 Log::Callbacks log_callbacks;
Chris Lattner24943d22010-06-08 16:52:24 +0000314
Caroline Tice926060e2010-10-29 21:48:37 +0000315 std::string channel(args.GetArgumentAtIndex(0));
316 args.Shift (); // Shift off the channel
317 if (Log::GetLogChannelCallbacks (channel.c_str(), log_callbacks))
318 {
319 log_callbacks.disable (args, &result.GetErrorStream());
320 result.SetStatus(eReturnStatusSuccessFinishNoResult);
321 }
322 else if (channel == "all")
323 {
324 Log::DisableAllLogChannels(&result.GetErrorStream());
325 }
326 else
327 {
Greg Clayton5e342f52011-04-13 22:47:15 +0000328 LogChannelSP log_channel_sp (LogChannel::FindPlugin(channel.c_str()));
Caroline Tice926060e2010-10-29 21:48:37 +0000329 if (log_channel_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000330 {
Caroline Tice926060e2010-10-29 21:48:37 +0000331 log_channel_sp->Disable(args, &result.GetErrorStream());
Chris Lattner24943d22010-06-08 16:52:24 +0000332 result.SetStatus(eReturnStatusSuccessFinishNoResult);
333 }
Chris Lattner24943d22010-06-08 16:52:24 +0000334 else
Caroline Tice926060e2010-10-29 21:48:37 +0000335 result.AppendErrorWithFormat("Invalid log channel '%s'.\n", args.GetArgumentAtIndex(0));
Chris Lattner24943d22010-06-08 16:52:24 +0000336 }
337 }
338 return result.Succeeded();
339 }
340};
341
342class CommandObjectLogList : public CommandObject
343{
344public:
345 //------------------------------------------------------------------
346 // Constructors and Destructors
347 //------------------------------------------------------------------
Greg Clayton238c0a12010-09-18 01:14:36 +0000348 CommandObjectLogList(CommandInterpreter &interpreter) :
349 CommandObject (interpreter,
350 "log list",
Caroline Tice43b014a2010-10-04 22:28:36 +0000351 "List the log categories for one or more log channels. If none specified, lists them all.",
352 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000353 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000354 CommandArgumentEntry arg;
355 CommandArgumentData channel_arg;
356
357 // Define the first (and only) variant of this arg.
358 channel_arg.arg_type = eArgTypeLogChannel;
359 channel_arg.arg_repetition = eArgRepeatStar;
360
361 // There is only one variant this argument could be; put it into the argument entry.
362 arg.push_back (channel_arg);
363
364 // Push the data for the first argument into the m_arguments vector.
365 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000366 }
367
368 virtual
369 ~CommandObjectLogList()
370 {
371 }
372
373 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000374 Execute (Args& args,
Chris Lattner24943d22010-06-08 16:52:24 +0000375 CommandReturnObject &result)
376 {
377 const size_t argc = args.GetArgumentCount();
378 if (argc == 0)
379 {
380 Log::ListAllLogChannels (&result.GetOutputStream());
381 result.SetStatus(eReturnStatusSuccessFinishResult);
382 }
383 else
384 {
385 for (size_t i=0; i<argc; ++i)
386 {
387 Log::Callbacks log_callbacks;
388
389 std::string channel(args.GetArgumentAtIndex(i));
390 if (Log::GetLogChannelCallbacks (channel.c_str(), log_callbacks))
391 {
392 log_callbacks.list_categories (&result.GetOutputStream());
393 result.SetStatus(eReturnStatusSuccessFinishResult);
394 }
395 else if (channel == "all")
396 {
397 Log::ListAllLogChannels (&result.GetOutputStream());
398 result.SetStatus(eReturnStatusSuccessFinishResult);
399 }
400 else
401 {
Greg Clayton5e342f52011-04-13 22:47:15 +0000402 LogChannelSP log_channel_sp (LogChannel::FindPlugin(channel.c_str()));
Chris Lattner24943d22010-06-08 16:52:24 +0000403 if (log_channel_sp)
404 {
405 log_channel_sp->ListCategories(&result.GetOutputStream());
406 result.SetStatus(eReturnStatusSuccessFinishNoResult);
407 }
408 else
409 result.AppendErrorWithFormat("Invalid log channel '%s'.\n", args.GetArgumentAtIndex(0));
410 }
411 }
412 }
413 return result.Succeeded();
414 }
415};
416
417class CommandObjectLogTimer : public CommandObject
418{
419public:
420 //------------------------------------------------------------------
421 // Constructors and Destructors
422 //------------------------------------------------------------------
Greg Clayton238c0a12010-09-18 01:14:36 +0000423 CommandObjectLogTimer(CommandInterpreter &interpreter) :
424 CommandObject (interpreter,
425 "log timers",
Chris Lattner24943d22010-06-08 16:52:24 +0000426 "Enable, disable, dump, and reset LLDB internal performance timers.",
Jim Ingham4ba39992010-11-04 23:19:21 +0000427 "log timers < enable <depth> | disable | dump | increment <bool> | reset >")
Chris Lattner24943d22010-06-08 16:52:24 +0000428 {
429 }
430
431 virtual
432 ~CommandObjectLogTimer()
433 {
434 }
435
436 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000437 Execute (Args& args,
Chris Lattner24943d22010-06-08 16:52:24 +0000438 CommandReturnObject &result)
439 {
440 const size_t argc = args.GetArgumentCount();
441 result.SetStatus(eReturnStatusFailed);
442
443 if (argc == 1)
444 {
445 const char *sub_command = args.GetArgumentAtIndex(0);
446
447 if (strcasecmp(sub_command, "enable") == 0)
448 {
449 Timer::SetDisplayDepth (UINT32_MAX);
450 result.SetStatus(eReturnStatusSuccessFinishNoResult);
451 }
452 else if (strcasecmp(sub_command, "disable") == 0)
453 {
454 Timer::DumpCategoryTimes (&result.GetOutputStream());
455 Timer::SetDisplayDepth (0);
456 result.SetStatus(eReturnStatusSuccessFinishResult);
457 }
458 else if (strcasecmp(sub_command, "dump") == 0)
459 {
460 Timer::DumpCategoryTimes (&result.GetOutputStream());
461 result.SetStatus(eReturnStatusSuccessFinishResult);
462 }
463 else if (strcasecmp(sub_command, "reset") == 0)
464 {
465 Timer::ResetCategoryTimes ();
466 result.SetStatus(eReturnStatusSuccessFinishResult);
467 }
468
469 }
Jim Ingham19e29a82010-11-04 23:08:26 +0000470 else if (argc == 2)
471 {
472 const char *sub_command = args.GetArgumentAtIndex(0);
473
474 if (strcasecmp(sub_command, "enable") == 0)
475 {
476 bool success;
477 uint32_t depth = Args::StringToUInt32(args.GetArgumentAtIndex(1), 0, 0, &success);
478 if (success)
479 {
480 Timer::SetDisplayDepth (depth);
481 result.SetStatus(eReturnStatusSuccessFinishNoResult);
482 }
483 else
484 result.AppendError("Could not convert enable depth to an unsigned integer.");
485 }
Jim Ingham4ba39992010-11-04 23:19:21 +0000486 if (strcasecmp(sub_command, "increment") == 0)
487 {
488 bool success;
489 bool increment = Args::StringToBoolean(args.GetArgumentAtIndex(1), false, &success);
490 if (success)
491 {
492 Timer::SetQuiet (!increment);
493 result.SetStatus(eReturnStatusSuccessFinishNoResult);
494 }
495 else
496 result.AppendError("Could not convert increment value to boolean.");
497 }
Jim Ingham19e29a82010-11-04 23:08:26 +0000498 }
499
Chris Lattner24943d22010-06-08 16:52:24 +0000500 if (!result.Succeeded())
501 {
502 result.AppendError("Missing subcommand");
503 result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str());
504 }
505 return result.Succeeded();
506 }
507};
508
509//----------------------------------------------------------------------
510// CommandObjectLog constructor
511//----------------------------------------------------------------------
Greg Clayton63094e02010-06-23 01:19:29 +0000512CommandObjectLog::CommandObjectLog(CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000513 CommandObjectMultiword (interpreter,
514 "log",
Chris Lattner24943d22010-06-08 16:52:24 +0000515 "A set of commands for operating on logs.",
516 "log <command> [<command-options>]")
517{
Greg Clayton238c0a12010-09-18 01:14:36 +0000518 LoadSubCommand ("enable", CommandObjectSP (new CommandObjectLogEnable (interpreter)));
519 LoadSubCommand ("disable", CommandObjectSP (new CommandObjectLogDisable (interpreter)));
520 LoadSubCommand ("list", CommandObjectSP (new CommandObjectLogList (interpreter)));
521 LoadSubCommand ("timers", CommandObjectSP (new CommandObjectLogTimer (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +0000522}
523
524//----------------------------------------------------------------------
525// Destructor
526//----------------------------------------------------------------------
527CommandObjectLog::~CommandObjectLog()
528{
529}
530
531
532
533