mirror of
https://github.com/intel/llvm.git
synced 2026-01-13 11:02:04 +08:00
Support for truncate/append on log files
Summary: Presently, if a log file already exists, lldb simply starts overwriting bits of it, without truncating or anything. This patch makes it use eFileOptionFileTruncate by default. It also adds an --append option, which will append to the file without truncating. A test is included. Reviewers: clayborg Subscribers: lldb-commits Differential Revision: http://reviews.llvm.org/D8450 llvm-svn: 232801
This commit is contained in:
@@ -47,6 +47,7 @@
|
||||
#define LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD (1u << 5)
|
||||
#define LLDB_LOG_OPTION_PREPEND_THREAD_NAME (1U << 6)
|
||||
#define LLDB_LOG_OPTION_BACKTRACE (1U << 7)
|
||||
#define LLDB_LOG_OPTION_APPEND (1U << 8)
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Logging Functions
|
||||
|
||||
@@ -37,6 +37,10 @@ public:
|
||||
|
||||
StreamFile (const char *path);
|
||||
|
||||
StreamFile (const char *path,
|
||||
uint32_t options,
|
||||
uint32_t permissions = lldb::eFilePermissionsFileDefault);
|
||||
|
||||
StreamFile (FILE *fh, bool transfer_ownership);
|
||||
|
||||
virtual
|
||||
|
||||
@@ -146,6 +146,7 @@ public:
|
||||
case 'p': log_options |= LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD;break;
|
||||
case 'n': log_options |= LLDB_LOG_OPTION_PREPEND_THREAD_NAME; break;
|
||||
case 'S': log_options |= LLDB_LOG_OPTION_BACKTRACE; break;
|
||||
case 'a': log_options |= LLDB_LOG_OPTION_APPEND; break;
|
||||
default:
|
||||
error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
|
||||
break;
|
||||
@@ -223,6 +224,7 @@ CommandObjectLogEnable::CommandOptions::g_option_table[] =
|
||||
{ LLDB_OPT_SET_1, false, "pid-tid", 'p', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Prepend all log lines with the process and thread ID that generates the log line." },
|
||||
{ LLDB_OPT_SET_1, false, "thread-name",'n', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Prepend all log lines with the thread name for the thread that generates the log line." },
|
||||
{ LLDB_OPT_SET_1, false, "stack", 'S', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Append a stack backtrace to each log line." },
|
||||
{ LLDB_OPT_SET_1, false, "append", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Append to the log file instead of overwriting." },
|
||||
{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
|
||||
};
|
||||
|
||||
|
||||
@@ -1331,7 +1331,12 @@ Debugger::EnableLog (const char *channel, const char **categories, const char *l
|
||||
log_stream_sp = pos->second.lock();
|
||||
if (!log_stream_sp)
|
||||
{
|
||||
log_stream_sp.reset (new StreamFile (log_file));
|
||||
uint32_t options = File::eOpenOptionWrite | File::eOpenOptionCanCreate
|
||||
| File::eOpenOptionCloseOnExec | File::eOpenOptionAppend;
|
||||
if (! (log_options & LLDB_LOG_OPTION_APPEND))
|
||||
options |= File::eOpenOptionTruncate;
|
||||
|
||||
log_stream_sp.reset (new StreamFile (log_file, options));
|
||||
m_log_streams[log_file] = log_stream_sp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,13 @@ StreamFile::StreamFile (const char *path) :
|
||||
{
|
||||
}
|
||||
|
||||
StreamFile::StreamFile (const char *path,
|
||||
uint32_t options,
|
||||
uint32_t permissions) :
|
||||
Stream(),
|
||||
m_file(path, options, permissions)
|
||||
{
|
||||
}
|
||||
|
||||
StreamFile::~StreamFile()
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
Test lldb logging. This test just makes sure logging doesn't crash, and produces some output.
|
||||
"""
|
||||
|
||||
import os, time
|
||||
import os, time, string
|
||||
import unittest2
|
||||
import lldb
|
||||
from lldbtest import *
|
||||
@@ -10,6 +10,15 @@ from lldbtest import *
|
||||
class LogTestCase(TestBase):
|
||||
|
||||
mydir = TestBase.compute_mydir(__file__)
|
||||
append_log_file = "lldb-commands-log-append.txt"
|
||||
truncate_log_file = "lldb-commands-log-truncate.txt"
|
||||
|
||||
|
||||
@classmethod
|
||||
def classCleanup(cls):
|
||||
"""Cleanup the test byproducts."""
|
||||
cls.RemoveTempFile(cls.truncate_log_file)
|
||||
cls.RemoveTempFile(cls.append_log_file)
|
||||
|
||||
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
|
||||
@dsym_test
|
||||
@@ -56,6 +65,48 @@ class LogTestCase(TestBase):
|
||||
|
||||
self.assertTrue(log_lines > 0, "Something was written to the log file.")
|
||||
|
||||
# Check that lldb truncates its log files
|
||||
def test_log_truncate (self):
|
||||
if (os.path.exists (self.truncate_log_file)):
|
||||
os.remove (self.truncate_log_file)
|
||||
|
||||
# put something in our log file
|
||||
with open(self.truncate_log_file, "w") as f:
|
||||
for i in range(1, 1000):
|
||||
f.write("bacon\n")
|
||||
|
||||
self.runCmd ("log enable -t -f '%s' lldb commands" % (self.truncate_log_file))
|
||||
self.runCmd ("help log")
|
||||
self.runCmd ("log disable lldb")
|
||||
|
||||
self.assertTrue (os.path.isfile (self.truncate_log_file))
|
||||
with open(self.truncate_log_file, "r") as f:
|
||||
contents = f.read ()
|
||||
|
||||
# check that it got removed
|
||||
self.assertTrue(string.find(contents, "bacon") == -1)
|
||||
|
||||
# Check that lldb can append to a log file
|
||||
def test_log_append (self):
|
||||
if (os.path.exists (self.append_log_file)):
|
||||
os.remove (self.append_log_file)
|
||||
|
||||
# put something in our log file
|
||||
with open(self.append_log_file, "w") as f:
|
||||
f.write("bacon\n")
|
||||
|
||||
self.runCmd ("log enable -t -a -f '%s' lldb commands" % (self.append_log_file))
|
||||
self.runCmd ("help log")
|
||||
self.runCmd ("log disable lldb")
|
||||
|
||||
self.assertTrue (os.path.isfile (self.append_log_file))
|
||||
with open(self.append_log_file, "r") as f:
|
||||
contents = f.read ()
|
||||
|
||||
# check that it is still there
|
||||
self.assertTrue(string.find(contents, "bacon") == 0)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import atexit
|
||||
lldb.SBDebugger.Initialize()
|
||||
|
||||
Reference in New Issue
Block a user