[Lldb-commits] [lldb] r161785 - in /lldb/trunk: include/lldb/Breakpoint/Watchpoint.h lldb.xcodeproj/project.pbxproj source/Breakpoint/Watchpoint.cpp source/Breakpoint/WatchpointOptions.cpp source/Commands/CommandObjectWatchpoint.cpp source/Target/StopInfo.cpp test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandLLDB.py test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandPython.py test/functionalities/watchpoint/watchpoint_commands/command/main.cpp
Johnny Chen
johnny.chen at apple.com
Mon Aug 13 14:09:54 PDT 2012
Author: johnny
Date: Mon Aug 13 16:09:54 2012
New Revision: 161785
URL: http://llvm.org/viewvc/llvm-project?rev=161785&view=rev
Log:
rdar://problem/12007576
Record the snapshot of our watched value when the watchpoint is set or hit.
And report the old/new values when watchpoint is triggered. Add some test scenarios.
Modified:
lldb/trunk/include/lldb/Breakpoint/Watchpoint.h
lldb/trunk/lldb.xcodeproj/project.pbxproj
lldb/trunk/source/Breakpoint/Watchpoint.cpp
lldb/trunk/source/Breakpoint/WatchpointOptions.cpp
lldb/trunk/source/Commands/CommandObjectWatchpoint.cpp
lldb/trunk/source/Target/StopInfo.cpp
lldb/trunk/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandLLDB.py
lldb/trunk/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandPython.py
lldb/trunk/test/functionalities/watchpoint/watchpoint_commands/command/main.cpp
Modified: lldb/trunk/include/lldb/Breakpoint/Watchpoint.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/Watchpoint.h?rev=161785&r1=161784&r2=161785&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Breakpoint/Watchpoint.h (original)
+++ lldb/trunk/include/lldb/Breakpoint/Watchpoint.h Mon Aug 13 16:09:54 2012
@@ -53,10 +53,25 @@
uint32_t GetIgnoreCount () const;
void SetIgnoreCount (uint32_t n);
void SetWatchpointType (uint32_t type);
- void SetDeclInfo (std::string &str);
- void SetWatchSpec (std::string &str);
+ void SetDeclInfo (const std::string &str);
+ std::string GetWatchSpec();
+ void SetWatchSpec (const std::string &str);
+
+ // Snapshot management interface.
+ bool IsWatchVariable() const;
+ void SetWatchVariable(bool val);
+ std::string GetOldSnapshot() const;
+ void SetOldSnapshot (const std::string &str);
+ std::string GetNewSnapshot() const;
+ void SetNewSnapshot (const std::string &str);
+ uint64_t GetOldSnapshotVal() const;
+ void SetOldSnapshotVal (uint64_t val);
+ uint64_t GetNewSnapshotVal() const;
+ void SetNewSnapshotVal (uint64_t val);
+
void GetDescription (Stream *s, lldb::DescriptionLevel level);
void Dump (Stream *s) const;
+ void DumpSnapshots (const char * prefix, Stream *s) const;
void DumpWithLevel (Stream *s, lldb::DescriptionLevel description_level) const;
Target &GetTarget() { return *m_target; }
const Error &GetError() { return m_error; }
@@ -136,19 +151,23 @@
friend class WatchpointList;
void SetTarget(Target *target_ptr) { m_target = target_ptr; }
- std::string GetWatchSpec() { return m_watch_spec_str; }
void ResetHitCount() { m_hit_count = 0; }
Target *m_target;
bool m_enabled; // Is this watchpoint enabled
bool m_is_hardware; // Is this a hardware watchpoint
+ bool m_is_watch_variable; // True if set via 'watchpoint set variable'.
uint32_t m_watch_read:1, // 1 if we stop when the watched data is read from
m_watch_write:1, // 1 if we stop when the watched data is written to
m_watch_was_read:1, // Set to 1 when watchpoint is hit for a read access
m_watch_was_written:1; // Set to 1 when watchpoint is hit for a write access
uint32_t m_ignore_count; // Number of times to ignore this breakpoint
std::string m_decl_str; // Declaration information, if any.
- std::string m_watch_spec_str; // Spec for the watchpoint (for future use).
+ std::string m_watch_spec_str; // Spec for the watchpoint.
+ std::string m_snapshot_old_str; // Old snapshot for the watchpoint value as by ValueObject::DumpValueObject().
+ std::string m_snapshot_new_str; // New Snapshot for the watchpoint value as by ValueObject::DumpValueObject().
+ uint64_t m_snapshot_old_val; // Old snapshot for the watchpoint bytes.
+ uint64_t m_snapshot_new_val; // New Snapshot for the watchpoint bytes.
Error m_error; // An error object describing errors associated with this watchpoint.
WatchpointOptions m_options; // Settable watchpoint options, which is a delegate to handle
// the callback machinery.
Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=161785&r1=161784&r2=161785&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Mon Aug 13 16:09:54 2012
@@ -4407,7 +4407,7 @@
HEADER_SEARCH_PATHS = /usr/include/libxml2;
LD_DYLIB_INSTALL_NAME = "$(DEVELOPER_DIR)/Library/PrivateFrameworks/LLDB.framework/Resources/lldb-core.a";
MACH_O_TYPE = staticlib;
- MACOSX_DEPLOYMENT_TARGET = "10.7";
+ MACOSX_DEPLOYMENT_TARGET = 10.7;
OTHER_CPLUSPLUSFLAGS = (
"-fno-rtti",
"-Wglobal-constructors",
@@ -4438,7 +4438,7 @@
HEADER_SEARCH_PATHS = /usr/include/libxml2;
LD_DYLIB_INSTALL_NAME = "$(DEVELOPER_DIR)/Library/PrivateFrameworks/LLDB.framework/Resources/lldb-core.a";
MACH_O_TYPE = staticlib;
- MACOSX_DEPLOYMENT_TARGET = "10.7";
+ MACOSX_DEPLOYMENT_TARGET = 10.7;
OTHER_CPLUSPLUSFLAGS = (
"-fno-rtti",
"-Wglobal-constructors",
@@ -4469,7 +4469,7 @@
HEADER_SEARCH_PATHS = /usr/include/libxml2;
LD_DYLIB_INSTALL_NAME = "$(DEVELOPER_DIR)/Library/PrivateFrameworks/LLDB.framework/Resources/lldb-core.a";
MACH_O_TYPE = staticlib;
- MACOSX_DEPLOYMENT_TARGET = "10.7";
+ MACOSX_DEPLOYMENT_TARGET = 10.7;
OTHER_CPLUSPLUSFLAGS = (
"-fno-rtti",
"-Wglobal-constructors",
Modified: lldb/trunk/source/Breakpoint/Watchpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/Watchpoint.cpp?rev=161785&r1=161784&r2=161785&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/Watchpoint.cpp (original)
+++ lldb/trunk/source/Breakpoint/Watchpoint.cpp Mon Aug 13 16:09:54 2012
@@ -28,6 +28,7 @@
m_target(NULL),
m_enabled(false),
m_is_hardware(hardware),
+ m_is_watch_variable(false),
m_watch_read(0),
m_watch_write(0),
m_watch_was_read(0),
@@ -35,6 +36,10 @@
m_ignore_count(0),
m_decl_str(),
m_watch_spec_str(),
+ m_snapshot_old_str(),
+ m_snapshot_new_str(),
+ m_snapshot_old_val(0),
+ m_snapshot_new_val(0),
m_error(),
m_options ()
{
@@ -70,19 +75,79 @@
}
void
-Watchpoint::SetDeclInfo (std::string &str)
+Watchpoint::SetDeclInfo (const std::string &str)
{
m_decl_str = str;
return;
}
+std::string
+Watchpoint::GetWatchSpec()
+{
+ return m_watch_spec_str;
+}
+
void
-Watchpoint::SetWatchSpec (std::string &str)
+Watchpoint::SetWatchSpec (const std::string &str)
{
m_watch_spec_str = str;
return;
}
+std::string
+Watchpoint::GetOldSnapshot() const
+{
+ return m_snapshot_old_str;
+}
+
+void
+Watchpoint::SetOldSnapshot (const std::string &str)
+{
+ m_snapshot_old_str = str;
+ return;
+}
+
+std::string
+Watchpoint::GetNewSnapshot() const
+{
+ return m_snapshot_new_str;
+}
+
+void
+Watchpoint::SetNewSnapshot (const std::string &str)
+{
+ m_snapshot_old_str = m_snapshot_new_str;
+ m_snapshot_new_str = str;
+ return;
+}
+
+uint64_t
+Watchpoint::GetOldSnapshotVal() const
+{
+ return m_snapshot_old_val;
+}
+
+void
+Watchpoint::SetOldSnapshotVal (uint64_t val)
+{
+ m_snapshot_old_val = val;
+ return;
+}
+
+uint64_t
+Watchpoint::GetNewSnapshotVal() const
+{
+ return m_snapshot_new_val;
+}
+
+void
+Watchpoint::SetNewSnapshotVal (uint64_t val)
+{
+ m_snapshot_old_val = m_snapshot_new_val;
+ m_snapshot_new_val = val;
+ return;
+}
+
// Override default impl of StoppointLocation::IsHardware() since m_is_hardware
// member field is more accurate.
bool
@@ -91,6 +156,18 @@
return m_is_hardware;
}
+bool
+Watchpoint::IsWatchVariable() const
+{
+ return m_is_watch_variable;
+}
+
+void
+Watchpoint::SetWatchVariable(bool val)
+{
+ m_is_watch_variable = val;
+}
+
// RETURNS - true if we should stop at this breakpoint, false if we
// should continue.
@@ -122,6 +199,24 @@
}
void
+Watchpoint::DumpSnapshots(const char *prefix, Stream *s) const
+{
+ if (IsWatchVariable())
+ {
+ if (!m_snapshot_old_str.empty())
+ s->Printf("\n%swatchpoint old value:\n\t%s", prefix, m_snapshot_old_str.c_str());
+ if (!m_snapshot_new_str.empty())
+ s->Printf("\n%swatchpoint new value:\n\t%s", prefix, m_snapshot_new_str.c_str());
+ }
+ else
+ {
+ uint32_t num_hex_digits = GetByteSize() * 2;
+ s->Printf("\n%swatchpoint old value:0x%0*.*llx", prefix, num_hex_digits, num_hex_digits, m_snapshot_old_val);
+ s->Printf("\n%swatchpoint new value:0x%0*.*llx", prefix, num_hex_digits, num_hex_digits, m_snapshot_new_val);
+ }
+}
+
+void
Watchpoint::DumpWithLevel(Stream *s, lldb::DescriptionLevel description_level) const
{
if (s == NULL)
@@ -142,7 +237,11 @@
if (!m_decl_str.empty())
s->Printf("\n declare @ '%s'", m_decl_str.c_str());
if (!m_watch_spec_str.empty())
- s->Printf("\n static watchpoint spec = '%s'", m_watch_spec_str.c_str());
+ s->Printf("\n watchpoint spec = '%s'", m_watch_spec_str.c_str());
+
+ // Dump the snapshots we have taken.
+ DumpSnapshots(" ", s);
+
if (GetConditionText())
s->Printf("\n condition = '%s'", GetConditionText());
m_options.GetCallbackDescription(s, description_level);
Modified: lldb/trunk/source/Breakpoint/WatchpointOptions.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/WatchpointOptions.cpp?rev=161785&r1=161784&r2=161785&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/WatchpointOptions.cpp (original)
+++ lldb/trunk/source/Breakpoint/WatchpointOptions.cpp Mon Aug 13 16:09:54 2012
@@ -168,11 +168,8 @@
{
if (m_callback_baton_sp.get())
{
- if (level != eDescriptionLevelBrief)
- {
- s->EOL();
- m_callback_baton_sp->GetDescription (s, level);
- }
+ s->EOL();
+ m_callback_baton_sp->GetDescription (s, level);
}
}
void
@@ -222,7 +219,7 @@
}
s->IndentMore ();
- s->Indent("Watchpoint commands:\n");
+ s->Indent("watchpoint commands:\n");
s->IndentMore ();
if (data && data->user_source.GetSize() > 0)
Modified: lldb/trunk/source/Commands/CommandObjectWatchpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectWatchpoint.cpp?rev=161785&r1=161784&r2=161785&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectWatchpoint.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectWatchpoint.cpp Mon Aug 13 16:09:54 2012
@@ -1047,6 +1047,8 @@
error.Clear();
Watchpoint *wp = target->CreateWatchpoint(addr, size, watch_type, error).get();
if (wp) {
+ wp->SetWatchSpec(command.GetArgumentAtIndex(0));
+ wp->SetWatchVariable(true);
if (var_sp && var_sp->GetDeclaration().GetFile()) {
StreamString ss;
// True to show fullpath for declaration file.
@@ -1054,13 +1056,15 @@
wp->SetDeclInfo(ss.GetString());
}
StreamString ss;
+ ValueObject::DumpValueObject(ss, valobj_sp.get());
+ wp->SetNewSnapshot(ss.GetString());
output_stream.Printf("Watchpoint created: ");
wp->GetDescription(&output_stream, lldb::eDescriptionLevelFull);
output_stream.EOL();
result.SetStatus(eReturnStatusSuccessFinishResult);
} else {
- result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%llx, size=%lu).\n",
- addr, size);
+ result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%llx, size=%lu, variable expression='%s').\n",
+ addr, size, command.GetArgumentAtIndex(0));
if (error.AsCString(NULL))
result.AppendError(error.AsCString());
result.SetStatus(eReturnStatusFailed);
@@ -1238,8 +1242,12 @@
var_sp->GetDeclaration().DumpStopContext(&ss, true);
wp->SetDeclInfo(ss.GetString());
}
- StreamString ss;
output_stream.Printf("Watchpoint created: ");
+ uint64_t val = target->GetProcessSP()->ReadUnsignedIntegerFromMemory(addr, size, 0, error);
+ if (error.Success())
+ wp->SetNewSnapshotVal(val);
+ else
+ output_stream.Printf("watchpoint snapshot failed: %s", error.AsCString());
wp->GetDescription(&output_stream, lldb::eDescriptionLevelFull);
output_stream.EOL();
result.SetStatus(eReturnStatusSuccessFinishResult);
Modified: lldb/trunk/source/Target/StopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StopInfo.cpp?rev=161785&r1=161784&r2=161785&view=diff
==============================================================================
--- lldb/trunk/source/Target/StopInfo.cpp (original)
+++ lldb/trunk/source/Target/StopInfo.cpp Mon Aug 13 16:09:54 2012
@@ -451,7 +451,7 @@
virtual void
PerformAction (Event *event_ptr)
{
- LogSP log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
+ LogSP log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS);
// We're going to calculate if we should stop or not in some way during the course of
// this code. Also by default we're going to stop, so set that here.
m_should_stop = true;
@@ -461,11 +461,11 @@
if (wp_sp)
{
ExecutionContext exe_ctx (m_thread.GetStackFrameAtIndex(0));
+ Process* process = exe_ctx.GetProcessPtr();
{
// check if this process is running on an architecture where watchpoints trigger
// before the associated instruction runs. if so, disable the WP, single-step and then
// re-enable the watchpoint
- Process* process = exe_ctx.GetProcessPtr();
if (process)
{
uint32_t num; bool wp_triggers_after;
@@ -491,7 +491,62 @@
}
}
}
- StoppointCallbackContext context (event_ptr, exe_ctx, false);
+
+ // Record the snapshot of our watchpoint.
+ VariableSP var_sp;
+ ValueObjectSP valobj_sp;
+ StackFrame *frame = exe_ctx.GetFramePtr();
+ if (frame)
+ {
+ if (!wp_sp->IsWatchVariable())
+ {
+ assert (process);
+ Error error;
+ uint64_t val = process->ReadUnsignedIntegerFromMemory(wp_sp->GetLoadAddress(),
+ wp_sp->GetByteSize(),
+ 0,
+ error);
+ if (log)
+ {
+ if (error.Success())
+ log->Printf("Watchpoint snapshot val taken: 0x%llx\n", val);
+ else
+ log->Printf("Watchpoint snapshot val taking failed.\n");
+ }
+ wp_sp->SetNewSnapshotVal(val);
+ }
+ else if (!wp_sp->GetWatchSpec().empty())
+ {
+ // Things have checked out ok...
+ Error error;
+ uint32_t expr_path_options = StackFrame::eExpressionPathOptionCheckPtrVsMember |
+ StackFrame::eExpressionPathOptionsAllowDirectIVarAccess;
+ valobj_sp = frame->GetValueForVariableExpressionPath (wp_sp->GetWatchSpec().c_str(),
+ eNoDynamicValues,
+ expr_path_options,
+ var_sp,
+ error);
+ if (valobj_sp)
+ {
+ // We're in business.
+ StreamString ss;
+ ValueObject::DumpValueObject(ss, valobj_sp.get());
+ wp_sp->SetNewSnapshot(ss.GetString());
+ }
+ else
+ wp_sp->SetNewSnapshot("snapshot attempt failed.");
+
+ if (log)
+ log->Printf("Watchpoint snapshot taken: '%s'\n", wp_sp->GetNewSnapshot().c_str());
+ }
+
+ // Now dump the snapshots we have taken.
+ Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger();
+ StreamSP output_sp = debugger.GetAsyncOutputStream ();
+ wp_sp->DumpSnapshots("!!! ", output_sp.get());
+ //output_sp->EOL();
+ output_sp->Flush();
+ }
if (m_should_stop && wp_sp->GetConditionText() != NULL)
{
@@ -564,6 +619,7 @@
// If the condition says to stop, we run the callback to further decide whether to stop.
if (m_should_stop)
{
+ StoppointCallbackContext context (event_ptr, exe_ctx, false);
bool stop_requested = wp_sp->InvokeCallback (&context);
// Also make sure that the callback hasn't continued the target.
// If it did, when we'll set m_should_stop to false and get out of here.
Modified: lldb/trunk/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandLLDB.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandLLDB.py?rev=161785&r1=161784&r2=161785&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandLLDB.py (original)
+++ lldb/trunk/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandLLDB.py Mon Aug 13 16:09:54 2012
@@ -63,11 +63,11 @@
substrs = ['Watchpoint created', 'size = 4', 'type = w',
'%s:%d' % (self.source, self.decl)])
- self.runCmd('watchpoint command add 1 -o "expr -- global = 777"')
+ self.runCmd('watchpoint command add 1 -o "expr -- cookie = 777"')
# List the watchpoint command we just added.
self.expect("watchpoint command list 1",
- substrs = ['expr -- global = 777'])
+ substrs = ['expr -- cookie = 777'])
# Use the '-v' option to do verbose listing of the watchpoint.
# The hit count should be 0 initially.
@@ -81,9 +81,14 @@
self.expect("thread backtrace", STOPPED_DUE_TO_WATCHPOINT,
substrs = ['stop reason = watchpoint'])
- # The watchpoint command "forced" our global variable to become 777.
- self.expect("frame variable -g global",
- substrs = ['(int32_t)', 'global = 777'])
+ # Check that the watchpoint snapshoting mechanism is working.
+ self.expect("watchpoint list -v",
+ substrs = ['watchpoint old value:', 'global = 0',
+ 'watchpoint new value:', 'global = 1'])
+
+ # The watchpoint command "forced" our global variable 'cookie' to become 777.
+ self.expect("frame variable -g cookie",
+ substrs = ['(int32_t)', 'cookie = 777'])
if __name__ == '__main__':
Modified: lldb/trunk/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandPython.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandPython.py?rev=161785&r1=161784&r2=161785&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandPython.py (original)
+++ lldb/trunk/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandPython.py Mon Aug 13 16:09:54 2012
@@ -63,11 +63,11 @@
substrs = ['Watchpoint created', 'size = 4', 'type = w',
'%s:%d' % (self.source, self.decl)])
- self.runCmd('watchpoint command add -s python 1 -o \'frame.EvaluateExpression("global = 777")\'')
+ self.runCmd('watchpoint command add -s python 1 -o \'frame.EvaluateExpression("cookie = 777")\'')
# List the watchpoint command we just added.
self.expect("watchpoint command list 1",
- substrs = ['frame.EvaluateExpression', 'global = 777'])
+ substrs = ['frame.EvaluateExpression', 'cookie = 777'])
# Use the '-v' option to do verbose listing of the watchpoint.
# The hit count should be 0 initially.
@@ -81,9 +81,14 @@
self.expect("thread backtrace", STOPPED_DUE_TO_WATCHPOINT,
substrs = ['stop reason = watchpoint'])
- # The watchpoint command "forced" our global variable to become 777.
- self.expect("frame variable -g global",
- substrs = ['(int32_t)', 'global = 777'])
+ # Check that the watchpoint snapshoting mechanism is working.
+ self.expect("watchpoint list -v",
+ substrs = ['watchpoint old value:', 'global = 0',
+ 'watchpoint new value:', 'global = 1'])
+
+ # The watchpoint command "forced" our global variable 'cookie' to become 777.
+ self.expect("frame variable -g cookie",
+ substrs = ['(int32_t)', 'cookie = 777'])
if __name__ == '__main__':
Modified: lldb/trunk/test/functionalities/watchpoint/watchpoint_commands/command/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/watchpoint/watchpoint_commands/command/main.cpp?rev=161785&r1=161784&r2=161785&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/watchpoint/watchpoint_commands/command/main.cpp (original)
+++ lldb/trunk/test/functionalities/watchpoint/watchpoint_commands/command/main.cpp Mon Aug 13 16:09:54 2012
@@ -10,6 +10,7 @@
#include <stdint.h>
int32_t global = 0; // Watchpoint variable declaration.
+int32_t cookie = 0;
static void modify(int32_t &var) {
++var;
@@ -19,10 +20,9 @@
int local = 0;
printf("&global=%p\n", &global);
printf("about to write to 'global'...\n"); // Set break point at this line.
- // When stopped, watch 'global',
- // for the condition "global == 5".
for (int i = 0; i < 10; ++i)
modify(global);
printf("global=%d\n", global);
+ printf("cookie=%d\n", cookie);
}
More information about the lldb-commits
mailing list