+
+
+ This feature, however, is not enabled for pointers because there is no
+ way for LLDB to detect the end of the pointed data.
+
+ This also does not work for other formats (e.g. boolean), and you must
+ specify the square brackets operator to get the expected output.
+
+
+
+
+
+
As you noticed, in order to associate the custom
summary string to the array types, one must give the
array size as part of the typename. This can long become
@@ -651,9 +731,17 @@
[12], ...
If you use the -x option, type names are
treated as regular expressions instead of type names.
- This would let you rephrase the above example as:
- (lldb) type summary add -f "${var[].x}"
- -x "Simple \[[0-9]+\]"
+ This would let you rephrase the above example
+ for arrays of type Simple [3] as:
+
+
+ |
+ (lldb) type summary add -f "${var[].x}"
+ -x "Simple \[[0-9]+\]"
+ |
+
+
+
(lldb) fr var sarray
(Simple [3]) sarray = [1,4,7]
The above scenario works for Simple [3]
@@ -670,6 +758,36 @@
regular expression match for your type itself.
+
+
+
+
+
For a given datatype, there may be different meaningful summary
+ representations. However, currently, only one summary can be associated
+ to a given datatype. If you need to temporarily override the association
+ for a variable, without changing the summary string bound to the datatype,
+ you can use named summaries.
+
+
Named summaries work by attaching a name to a summary string when creating
+ it. Then, when there is a need to attach the summary string to a variable, the
+ frame variable command, supports a --summary option
+ that tells LLDB to use the named summary given instead of the default one.
+
+
+ |
+ (lldb) type summary add -f "x=${var.integer}" --name NamedSummary
+ |
+
+ (lldb) fr var one
+ (i_am_cool) one = int = 3, float = 3.14159, char = 69
+ (lldb) fr var one --summary NamedSummary
+ (i_am_cool) one = x=3
+
+
+
+
+
+
From johnny.chen at apple.com Tue Jul 12 19:31:31 2011
From: johnny.chen at apple.com (Johnny Chen)
Date: Wed, 13 Jul 2011 00:31:31 -0000
Subject: [Lldb-commits] [lldb] r135016 - in
/lldb/trunk/test/functionalities/target_command: TestTargetCommand.py
globals.c
Message-ID: <20110713003131.5F3392A6C12C@llvm.org>
Author: johnny
Date: Tue Jul 12 19:31:31 2011
New Revision: 135016
URL: http://llvm.org/viewvc/llvm-project?rev=135016&view=rev
Log:
Add display of a static int variable to the test scenario.
Modified:
lldb/trunk/test/functionalities/target_command/TestTargetCommand.py
lldb/trunk/test/functionalities/target_command/globals.c
Modified: lldb/trunk/test/functionalities/target_command/TestTargetCommand.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/target_command/TestTargetCommand.py?rev=135016&r1=135015&r2=135016&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/target_command/TestTargetCommand.py (original)
+++ lldb/trunk/test/functionalities/target_command/TestTargetCommand.py Tue Jul 12 19:31:31 2011
@@ -107,6 +107,8 @@
substrs = ["my_global_char", "'X'"])
self.expect("target variable my_global_str", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ['my_global_str', '"abc"'])
+ self.expect("target variable my_static_int", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['my_static_int', '228'])
self.runCmd("run")
@@ -116,6 +118,8 @@
substrs = ["my_global_char", "'X'"])
self.expect("target variable my_global_str", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ['my_global_str', '"abc"'])
+ self.expect("target variable my_static_int", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['my_static_int', '228'])
if __name__ == '__main__':
Modified: lldb/trunk/test/functionalities/target_command/globals.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/target_command/globals.c?rev=135016&r1=135015&r2=135016&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/target_command/globals.c (original)
+++ lldb/trunk/test/functionalities/target_command/globals.c Tue Jul 12 19:31:31 2011
@@ -10,12 +10,15 @@
char my_global_char = 'X';
const char* my_global_str = "abc";
+static int my_static_int = 228;
int main (int argc, char const *argv[])
{
printf("global char: %c\n", my_global_char);
printf("global str: %s\n", my_global_str);
+
+ printf("argc + my_static_int = %d\n", (argc + my_static_int));
return 0;
}
From johnny.chen at apple.com Tue Jul 12 19:46:49 2011
From: johnny.chen at apple.com (Johnny Chen)
Date: Wed, 13 Jul 2011 00:46:49 -0000
Subject: [Lldb-commits] [lldb] r135019 - in /lldb/trunk/include/lldb/API:
SBModule.h SBTarget.h
Message-ID: <20110713004649.972802A6C12C@llvm.org>
Author: johnny
Date: Tue Jul 12 19:46:49 2011
New Revision: 135019
URL: http://llvm.org/viewvc/llvm-project?rev=135019&view=rev
Log:
Update docstrings for SBModeule/SBTarget::FindGlobalVariables().
Modified:
lldb/trunk/include/lldb/API/SBModule.h
lldb/trunk/include/lldb/API/SBTarget.h
Modified: lldb/trunk/include/lldb/API/SBModule.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBModule.h?rev=135019&r1=135018&r2=135019&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBModule.h (original)
+++ lldb/trunk/include/lldb/API/SBModule.h Tue Jul 12 19:46:49 2011
@@ -175,12 +175,15 @@
//------------------------------------------------------------------
/// Find global and static variables by name.
///
+ /// @param[in] target
+ /// A valid SBTarget instance representing the debuggee.
+ ///
/// @param[in] name
/// The name of the global or static variable we are looking
/// for.
///
- /// @param[in] target
- /// The target program where the variables reside.
+ /// @param[in] max_matches
+ /// Allow the number of matches to be limited to \a max_matches.
///
/// @return
/// A list of matched variables in an SBValueList.
Modified: lldb/trunk/include/lldb/API/SBTarget.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBTarget.h?rev=135019&r1=135018&r2=135019&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBTarget.h (original)
+++ lldb/trunk/include/lldb/API/SBTarget.h Tue Jul 12 19:46:49 2011
@@ -290,6 +290,25 @@
bool append,
lldb::SBSymbolContextList& sc_list);
+#ifdef SWIG
+ %feature("autodoc", "
+#endif
+ //------------------------------------------------------------------
+ /// Find global and static variables by name.
+ ///
+ /// @param[in] name
+ /// The name of the global or static variable we are looking
+ /// for.
+ ///
+ /// @param[in] max_matches
+ /// Allow the number of matches to be limited to \a max_matches.
+ ///
+ /// @return
+ /// A list of matched variables in an SBValueList.
+ //------------------------------------------------------------------
+#ifdef SWIG
+ ") FindGlobalVariables;
+#endif
lldb::SBValueList
FindGlobalVariables (const char *name,
uint32_t max_matches);
From johnny.chen at apple.com Wed Jul 13 15:03:51 2011
From: johnny.chen at apple.com (Johnny Chen)
Date: Wed, 13 Jul 2011 20:03:51 -0000
Subject: [Lldb-commits] [lldb] r135069 -
/lldb/trunk/test/functionalities/target_command/TestTargetCommand.py
Message-ID: <20110713200351.91D962A6C12C@llvm.org>
Author: johnny
Date: Wed Jul 13 15:03:51 2011
New Revision: 135069
URL: http://llvm.org/viewvc/llvm-project?rev=135069&view=rev
Log:
Add @expectedFailure decorator for test_target_variable_command_with_dsym().
rdar://problem/9763907
Modified:
lldb/trunk/test/functionalities/target_command/TestTargetCommand.py
Modified: lldb/trunk/test/functionalities/target_command/TestTargetCommand.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/target_command/TestTargetCommand.py?rev=135069&r1=135068&r2=135069&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/target_command/TestTargetCommand.py (original)
+++ lldb/trunk/test/functionalities/target_command/TestTargetCommand.py Wed Jul 13 15:03:51 2011
@@ -36,7 +36,7 @@
# rdar://problem/9763907
# 'target variable' command fails if the target program has been run
- #@unittest2.expectedFailure
+ @unittest2.expectedFailure
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
def test_target_variable_command_with_dsym(self):
"""Test 'target variable' command before and after starting the inferior."""
From johnny.chen at apple.com Wed Jul 13 17:34:29 2011
From: johnny.chen at apple.com (Johnny Chen)
Date: Wed, 13 Jul 2011 22:34:29 -0000
Subject: [Lldb-commits] [lldb] r135100 - in /lldb/trunk/test: lldbutil.py
python_api/frame/inlines/TestInlinedFrame.py
python_api/frame/inlines/inlines.c
Message-ID: <20110713223429.9E2132A6C12C@llvm.org>
Author: johnny
Date: Wed Jul 13 17:34:29 2011
New Revision: 135100
URL: http://llvm.org/viewvc/llvm-project?rev=135100&view=rev
Log:
Modify the test script to better handle the different inlining behaviors of
clang/gcc/llvm-gcc. If the first breakpoint is due to stop at an inlined
frame, test that the call site corresponds to where it should be. Also add
an expecr for a second break stop, if the first break stop corresponds to an
inlined call frame #0.
rdar://problem/9741470
Modified:
lldb/trunk/test/lldbutil.py
lldb/trunk/test/python_api/frame/inlines/TestInlinedFrame.py
lldb/trunk/test/python_api/frame/inlines/inlines.c
Modified: lldb/trunk/test/lldbutil.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbutil.py?rev=135100&r1=135099&r2=135100&view=diff
==============================================================================
--- lldb/trunk/test/lldbutil.py (original)
+++ lldb/trunk/test/lldbutil.py Wed Jul 13 17:34:29 2011
@@ -395,7 +395,8 @@
print >> output, " frame #{num}: {addr:#016x} {mod}`{func} at {file}:{line} {args}".format(
num=i, addr=load_addr, mod=mods[i],
func='%s [inlined]' % funcs[i] if frame.IsInlined() else funcs[i],
- file=files[i], line=lines[i], args=get_args_as_string(frame, showFuncName=False))
+ file=files[i], line=lines[i],
+ args=get_args_as_string(frame, showFuncName=False) if not frame.IsInlined() else '()')
if string_buffer:
return output.getvalue()
Modified: lldb/trunk/test/python_api/frame/inlines/TestInlinedFrame.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/frame/inlines/TestInlinedFrame.py?rev=135100&r1=135099&r2=135100&view=diff
==============================================================================
--- lldb/trunk/test/python_api/frame/inlines/TestInlinedFrame.py (original)
+++ lldb/trunk/test/python_api/frame/inlines/TestInlinedFrame.py Wed Jul 13 17:34:29 2011
@@ -25,6 +25,15 @@
self.buildDwarf()
self.do_stop_at_outer_inline()
+ def setUp(self):
+
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to of function 'c'.
+ self.source = 'inlines.c'
+ self.first_stop = line_number(self.source, '// This should correspond to the first break stop.')
+ self.second_stop = line_number(self.source, '// This should correspond to the second break stop.')
+
def do_stop_at_outer_inline(self):
"""Exercise SBFrame.IsInlined() and SBFrame.GetFunctionName()."""
exe = os.path.join(os.getcwd(), "a.out")
@@ -33,8 +42,8 @@
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
- # Now create a breakpoint on main.c by name 'c'.
- breakpoint = target.BreakpointCreateByName('outer_inline', 'a.out')
+ # Now create a breakpoint on main.c by the name of 'inner_inline'.
+ breakpoint = target.BreakpointCreateByName('inner_inline', 'a.out')
#print "breakpoint:", breakpoint
self.assertTrue(breakpoint and
breakpoint.GetNumLocations() > 1,
@@ -47,17 +56,35 @@
self.assertTrue(process.GetState() == lldb.eStateStopped,
PROCESS_STOPPED)
- self.runCmd("bt")
+ import lldbutil
+ stack_traces1 = lldbutil.print_stacktraces(process, string_buffer=True)
if self.TraceOn():
- print "Full stack traces when first stopped on the breakpoint 'outer_inline':"
- import lldbutil
- print lldbutil.print_stacktraces(process, string_buffer=True)
+ print "Full stack traces when first stopped on the breakpoint 'inner_inline':"
+ print stack_traces1
# The first breakpoint should correspond to an inlined call frame.
+ # If it's an inlined call frame, expect to find, in the stack trace,
+ # that there is a frame which corresponds to the following call site:
+ #
+ # outer_inline (argc);
+ #
frame0 = process.GetThreadAtIndex(0).GetFrameAtIndex(0)
- self.assertTrue(frame0.IsInlined() and
- frame0.GetFunctionName() == 'outer_inline')
-
+ if frame0.IsInlined():
+ filename = frame0.GetLineEntry().GetFileSpec().GetFilename()
+ self.assertTrue(filename == self.source)
+ self.expect(stack_traces1, "First stop at %s:%d" % (self.source, self.first_stop), exe=False,
+ substrs = ['%s:%d' % (self.source, self.first_stop)])
+
+ # Expect to break again for the second time.
+ process.Continue()
+ self.assertTrue(process.GetState() == lldb.eStateStopped,
+ PROCESS_STOPPED)
+ stack_traces2 = lldbutil.print_stacktraces(process, string_buffer=True)
+ if self.TraceOn():
+ print "Full stack traces when stopped on the breakpoint 'inner_inline' for the second time:"
+ print stack_traces2
+ self.expect(stack_traces2, "Second stop at %s:%d" % (self.source, self.second_stop), exe=False,
+ substrs = ['%s:%d' % (self.source, self.second_stop)])
if __name__ == '__main__':
import atexit
Modified: lldb/trunk/test/python_api/frame/inlines/inlines.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/frame/inlines/inlines.c?rev=135100&r1=135099&r2=135100&view=diff
==============================================================================
--- lldb/trunk/test/python_api/frame/inlines/inlines.c (original)
+++ lldb/trunk/test/python_api/frame/inlines/inlines.c Wed Jul 13 17:34:29 2011
@@ -43,9 +43,9 @@
int (*func_ptr) (int);
func_ptr = outer_inline;
- outer_inline (argc);
+ outer_inline (argc); // This should correspond to the first break stop.
- func_ptr (argc);
+ func_ptr (argc); // This should correspond to the second break stop.
return 0;
}
From johnny.chen at apple.com Wed Jul 13 18:17:13 2011
From: johnny.chen at apple.com (Johnny Chen)
Date: Wed, 13 Jul 2011 23:17:13 -0000
Subject: [Lldb-commits] [lldb] r135105 -
/lldb/trunk/include/lldb/API/SBModule.h
Message-ID: <20110713231713.A8E772A6C12C@llvm.org>
Author: johnny
Date: Wed Jul 13 18:17:13 2011
New Revision: 135105
URL: http://llvm.org/viewvc/llvm-project?rev=135105&view=rev
Log:
Use %feature("docstring") for methods of SBModule class so that the methods signature also gets generated in the Python docstring.
Modified:
lldb/trunk/include/lldb/API/SBModule.h
Modified: lldb/trunk/include/lldb/API/SBModule.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBModule.h?rev=135105&r1=135104&r2=135105&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBModule.h (original)
+++ lldb/trunk/include/lldb/API/SBModule.h Wed Jul 13 18:17:13 2011
@@ -49,7 +49,7 @@
IsValid () const;
#ifdef SWIG
- %feature("autodoc", "
+ %feature("docstring", "
#endif
//------------------------------------------------------------------
/// Get const accessor for the module file specification.
@@ -68,7 +68,7 @@
GetFileSpec () const;
#ifdef SWIG
- %feature("autodoc", "
+ %feature("docstring", "
#endif
//------------------------------------------------------------------
/// Get accessor for the module platform file specification.
@@ -100,7 +100,7 @@
#endif
#ifdef SWIG
- %feature("autodoc",
+ %feature("docstring",
"Returns the UUID of the module as a Python string."
) GetUUIDString;
#endif
@@ -134,7 +134,7 @@
GetSymbolAtIndex (size_t idx);
#ifdef SWIG
- %feature("autodoc", "
+ %feature("docstring", "
#endif
//------------------------------------------------------------------
/// Find functions by name.
@@ -170,7 +170,7 @@
lldb::SBSymbolContextList& sc_list);
#ifdef SWIG
- %feature("autodoc", "
+ %feature("docstring", "
#endif
//------------------------------------------------------------------
/// Find global and static variables by name.
From johnny.chen at apple.com Wed Jul 13 18:35:34 2011
From: johnny.chen at apple.com (Johnny Chen)
Date: Wed, 13 Jul 2011 23:35:34 -0000
Subject: [Lldb-commits] [lldb] r135108 -
/lldb/trunk/include/lldb/API/SBTarget.h
Message-ID: <20110713233534.1E53C2A6C12C@llvm.org>
Author: johnny
Date: Wed Jul 13 18:35:33 2011
New Revision: 135108
URL: http://llvm.org/viewvc/llvm-project?rev=135108&view=rev
Log:
Add some more docstrings for SBTarget.
Modified:
lldb/trunk/include/lldb/API/SBTarget.h
Modified: lldb/trunk/include/lldb/API/SBTarget.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBTarget.h?rev=135108&r1=135107&r2=135108&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBTarget.h (original)
+++ lldb/trunk/include/lldb/API/SBTarget.h Wed Jul 13 18:35:33 2011
@@ -175,7 +175,7 @@
const char *working_directory);
#ifdef SWIG
- %feature("autodoc", "
+ %feature("docstring", "
#endif
//------------------------------------------------------------------
/// Attach to process with pid.
@@ -204,7 +204,7 @@
lldb::SBError& error);
#ifdef SWIG
- %feature("autodoc", "
+ %feature("docstring", "
#endif
//------------------------------------------------------------------
/// Attach to process with name.
@@ -237,7 +237,7 @@
lldb::SBError& error);
#ifdef SWIG
- %feature("autodoc", "
+ %feature("docstring", "
#endif
//------------------------------------------------------------------
/// Attach to process with name.
@@ -284,6 +284,36 @@
lldb::SBModule
FindModule (const lldb::SBFileSpec &file_spec);
+#ifdef SWIG
+ %feature("docstring", "
+#endif
+ //------------------------------------------------------------------
+ /// Find functions by name.
+ ///
+ /// @param[in] name
+ /// The name of the function we are looking for.
+ ///
+ /// @param[in] name_type_mask
+ /// A logical OR of one or more FunctionNameType enum bits that
+ /// indicate what kind of names should be used when doing the
+ /// lookup. Bits include fully qualified names, base names,
+ /// C++ methods, or ObjC selectors.
+ /// See FunctionNameType for more details.
+ ///
+ /// @param[in] append
+ /// If true, any matches will be appended to \a sc_list, else
+ /// matches replace the contents of \a sc_list.
+ ///
+ /// @param[out] sc_list
+ /// A symbol context list that gets filled in with all of the
+ /// matches.
+ ///
+ /// @return
+ /// The number of matches added to \a sc_list.
+ //------------------------------------------------------------------
+#ifdef SWIG
+ ") FindFunctions;
+#endif
uint32_t
FindFunctions (const char *name,
uint32_t name_type_mask, // Logical OR one or more FunctionNameType enum bits
@@ -291,7 +321,7 @@
lldb::SBSymbolContextList& sc_list);
#ifdef SWIG
- %feature("autodoc", "
+ %feature("docstring", "
#endif
//------------------------------------------------------------------
/// Find global and static variables by name.
From johnny.chen at apple.com Wed Jul 13 19:17:49 2011
From: johnny.chen at apple.com (Johnny Chen)
Date: Thu, 14 Jul 2011 00:17:49 -0000
Subject: [Lldb-commits] [lldb] r135114 - in /lldb/trunk:
include/lldb/API/SBTarget.h scripts/Python/modify-python-lldb.py
Message-ID: <20110714001749.9393A2A6C12C@llvm.org>
Author: johnny
Date: Wed Jul 13 19:17:49 2011
New Revision: 135114
URL: http://llvm.org/viewvc/llvm-project?rev=135114&view=rev
Log:
Add some more docstrings (includng example usages) to SBTarget.h.
Add logic to modify-python-lldb to correct swig's transformation of 'char **argv' and 'char **envp'
to 'char argv' and 'char envp' by morphing them into the 'list argv' and 'list envp' (as a list of
Python strings).
Modified:
lldb/trunk/include/lldb/API/SBTarget.h
lldb/trunk/scripts/Python/modify-python-lldb.py
Modified: lldb/trunk/include/lldb/API/SBTarget.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBTarget.h?rev=135114&r1=135113&r2=135114&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBTarget.h (original)
+++ lldb/trunk/include/lldb/API/SBTarget.h Wed Jul 13 19:17:49 2011
@@ -63,7 +63,7 @@
GetProcess ();
#ifdef SWIG
- %feature("autodoc", "
+ %feature("docstring", "
#endif
//------------------------------------------------------------------
/// Launch a new process.
@@ -122,6 +122,20 @@
/// A process object for the newly created process.
//------------------------------------------------------------------
#ifdef SWIG
+
+For example,
+
+ process = target.Launch(self.dbg.GetListener(), None, None,
+ None, '/tmp/stdout.txt', None,
+ None, 0, False, error)
+
+launches a new process by passing nothing for both the args and the envs
+and redirect the standard output of the inferior to the /tmp/stdout.txt
+file. It does not specify a working directory so that the debug server
+will use its idea of what the current working directory is for the
+inferior. Also, we ask the debugger not to stop the inferior at the
+entry point. If no breakpoint is specified for the inferior, it should
+run to completion if no user interaction is required.
") Launch;
#endif
lldb::SBProcess
@@ -138,7 +152,7 @@
#ifdef SWIG
- %feature("autodoc", "
+ %feature("docstring", "
#endif
//------------------------------------------------------------------
/// Launch a new process with sensible defaults.
@@ -167,6 +181,13 @@
/// A process object for the newly created process.
//------------------------------------------------------------------
#ifdef SWIG
+
+For example,
+
+ process = target.LaunchSimple(['X', 'Y', 'Z'], None, os.getcwd())
+
+launches a new process by passing 'X', 'Y', 'Z' as the args to the
+executable.
") LaunchSimple;
#endif
lldb::SBProcess
Modified: lldb/trunk/scripts/Python/modify-python-lldb.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/modify-python-lldb.py?rev=135114&r1=135113&r2=135114&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/modify-python-lldb.py (original)
+++ lldb/trunk/scripts/Python/modify-python-lldb.py Wed Jul 13 19:17:49 2011
@@ -47,6 +47,9 @@
"""This transforms the 'char', i.e, 'char *' to 'str', Python string."""
line = line.replace(' char', ' str')
line = line.replace('char ', 'str ')
+ # Special case handling of 'char **argv' and 'char **envp'.
+ line = line.replace('str argv', 'list argv')
+ line = line.replace('str envp', 'list envp')
return line
#
From johnny.chen at apple.com Thu Jul 14 16:17:28 2011
From: johnny.chen at apple.com (Johnny Chen)
Date: Thu, 14 Jul 2011 21:17:28 -0000
Subject: [Lldb-commits] [lldb] r135188 -
/lldb/trunk/include/lldb/API/SBTarget.h
Message-ID: <20110714211728.B7CBF2A6C12C@llvm.org>
Author: johnny
Date: Thu Jul 14 16:17:28 2011
New Revision: 135188
URL: http://llvm.org/viewvc/llvm-project?rev=135188&view=rev
Log:
Fix typo in ConnectRemote() docstring.
Modified:
lldb/trunk/include/lldb/API/SBTarget.h
Modified: lldb/trunk/include/lldb/API/SBTarget.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBTarget.h?rev=135188&r1=135187&r2=135188&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBTarget.h (original)
+++ lldb/trunk/include/lldb/API/SBTarget.h Thu Jul 14 16:17:28 2011
@@ -261,7 +261,7 @@
%feature("docstring", "
#endif
//------------------------------------------------------------------
- /// Attach to process with name.
+ /// Connect to a remote debug server with url.
///
/// @param[in] listener
/// An optional listener that will receive all process events.
From johnny.chen at apple.com Thu Jul 14 16:23:24 2011
From: johnny.chen at apple.com (Johnny Chen)
Date: Thu, 14 Jul 2011 21:23:24 -0000
Subject: [Lldb-commits] [lldb] r135190 - /lldb/trunk/scripts/lldb.swig
Message-ID: <20110714212324.4F0242A6C12C@llvm.org>
Author: johnny
Date: Thu Jul 14 16:23:24 2011
New Revision: 135190
URL: http://llvm.org/viewvc/llvm-project?rev=135190&view=rev
Log:
Minor wording change.
Modified:
lldb/trunk/scripts/lldb.swig
Modified: lldb/trunk/scripts/lldb.swig
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/lldb.swig?rev=135190&r1=135189&r2=135190&view=diff
==============================================================================
--- lldb/trunk/scripts/lldb.swig (original)
+++ lldb/trunk/scripts/lldb.swig Thu Jul 14 16:23:24 2011
@@ -21,7 +21,7 @@
o SBValue: Represents the value of a variable, a register, or an expression.
o SBModule: Represents an executable image and its associated object and symbol
files.
-o SBSymbol: Represents the symbol associated with a stack frame.
+o SBSymbol: Represents the symbol possibly associated with a stack frame.
o SBCompileUnit: Represents a compilation unit, or compiled source file.
o SBFunction: Represents a generic function, which can be inlined or not.
o SBBlock: Represents a lexical block. SBFunction contains SBBlock(s).
From johnny.chen at apple.com Thu Jul 14 16:32:11 2011
From: johnny.chen at apple.com (Johnny Chen)
Date: Thu, 14 Jul 2011 21:32:11 -0000
Subject: [Lldb-commits] [lldb] r135194 - /lldb/trunk/scripts/lldb.swig
Message-ID: <20110714213211.6A72A2A6C12C@llvm.org>
Author: johnny
Date: Thu Jul 14 16:32:11 2011
New Revision: 135194
URL: http://llvm.org/viewvc/llvm-project?rev=135194&view=rev
Log:
Add summary info for SBBreakpoint to the lldb module level docstring.
Modified:
lldb/trunk/scripts/lldb.swig
Modified: lldb/trunk/scripts/lldb.swig
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/lldb.swig?rev=135194&r1=135193&r2=135194&view=diff
==============================================================================
--- lldb/trunk/scripts/lldb.swig (original)
+++ lldb/trunk/scripts/lldb.swig Thu Jul 14 16:32:11 2011
@@ -20,7 +20,9 @@
o SBSymbolContext: A container that stores various debugger related info.
o SBValue: Represents the value of a variable, a register, or an expression.
o SBModule: Represents an executable image and its associated object and symbol
- files.
+ files. SBTarget conatins SBModule(s).
+o SBBreakpoint: Represents a logical breakpoint and its associated settings.
+ SBTarget conatins SBBreakpoint(s).
o SBSymbol: Represents the symbol possibly associated with a stack frame.
o SBCompileUnit: Represents a compilation unit, or compiled source file.
o SBFunction: Represents a generic function, which can be inlined or not.
From johnny.chen at apple.com Thu Jul 14 17:20:12 2011
From: johnny.chen at apple.com (Johnny Chen)
Date: Thu, 14 Jul 2011 22:20:12 -0000
Subject: [Lldb-commits] [lldb] r135206 - in /lldb/trunk:
source/Interpreter/CommandObject.cpp test/help/TestHelp.py
Message-ID: <20110714222012.A71A12A6C12C@llvm.org>
Author: johnny
Date: Thu Jul 14 17:20:12 2011
New Revision: 135206
URL: http://llvm.org/viewvc/llvm-project?rev=135206&view=rev
Log:
Fixed a crasher where entering 'help disasm' on the command line would crash lldb.
The reasom of the crash is because of a missing entry in the argument table corresponding to eArgTypeUnsignedInteger.
Add such entry and modify the call site of the crash to go through a fail-fast API to retrieve the argument table.
Add a regression test to TestHelp.py.
Modified:
lldb/trunk/source/Interpreter/CommandObject.cpp
lldb/trunk/test/help/TestHelp.py
Modified: lldb/trunk/source/Interpreter/CommandObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandObject.cpp?rev=135206&r1=135205&r2=135206&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/CommandObject.cpp (original)
+++ lldb/trunk/source/Interpreter/CommandObject.cpp Thu Jul 14 17:20:12 2011
@@ -623,8 +623,9 @@
&& arg_name[len-1] == '>')
arg_name_str = arg_name_str.substr (1, len-2);
+ const ArgumentTableEntry *table = GetArgumentTable();
for (int i = 0; i < eArgTypeLastArg; ++i)
- if (arg_name_str.compare (g_arguments_data[i].arg_name) == 0)
+ if (arg_name_str.compare (table[i].arg_name) == 0)
return_type = g_arguments_data[i].arg_type;
return return_type;
@@ -778,6 +779,7 @@
{ eArgTypeThreadID, "thread-id", CommandCompletions::eNoCompletion, { NULL, false }, "Thread ID number." },
{ eArgTypeThreadIndex, "thread-index", CommandCompletions::eNoCompletion, { NULL, false }, "Index into the process' list of threads." },
{ eArgTypeThreadName, "thread-name", CommandCompletions::eNoCompletion, { NULL, false }, "The thread's name." },
+ { eArgTypeUnsignedInteger, "unsigned-integer", CommandCompletions::eNoCompletion, { NULL, false }, "An unsigned integer." },
{ eArgTypeUnixSignal, "unix-signal", CommandCompletions::eNoCompletion, { NULL, false }, "A valid Unix signal name or number (e.g. SIGKILL, KILL or 9)." },
{ eArgTypeVarName, "variable-name", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a variable in your program." },
{ eArgTypeValue, "value", CommandCompletions::eNoCompletion, { NULL, false }, "A value could be anything, depending on where and how it is used." },
Modified: lldb/trunk/test/help/TestHelp.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/help/TestHelp.py?rev=135206&r1=135205&r2=135206&view=diff
==============================================================================
--- lldb/trunk/test/help/TestHelp.py (original)
+++ lldb/trunk/test/help/TestHelp.py Thu Jul 14 17:20:12 2011
@@ -61,6 +61,11 @@
self.expect("version",
patterns = ['LLDB-' + (version_str if version_str else '[0-9]+')])
+ def test_help_should_not_crash_lldb(self):
+ """Command 'help disasm' should not crash lldb."""
+ self.runCmd("help disasm", check=False)
+ self.runCmd("help unsigned-integer")
+
def test_help_should_not_hang_emacsshell(self):
"""Command 'settings set term-width 0' should not hang the help command."""
self.runCmd("settings set term-width 0")
From johnny.chen at apple.com Thu Jul 14 18:33:34 2011
From: johnny.chen at apple.com (Johnny Chen)
Date: Thu, 14 Jul 2011 23:33:34 -0000
Subject: [Lldb-commits] [lldb] r135214 -
/lldb/trunk/test/python_api/lldbutil/iter/TestLLDBIterator.py
Message-ID: <20110714233334.DFCCB2A6C12C@llvm.org>
Author: johnny
Date: Thu Jul 14 18:33:34 2011
New Revision: 135214
URL: http://llvm.org/viewvc/llvm-project?rev=135214&view=rev
Log:
Minor change of variable name, from m to b (for breakpoint).
Modified:
lldb/trunk/test/python_api/lldbutil/iter/TestLLDBIterator.py
Modified: lldb/trunk/test/python_api/lldbutil/iter/TestLLDBIterator.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/lldbutil/iter/TestLLDBIterator.py?rev=135214&r1=135213&r2=135214&view=diff
==============================================================================
--- lldb/trunk/test/python_api/lldbutil/iter/TestLLDBIterator.py (original)
+++ lldb/trunk/test/python_api/lldbutil/iter/TestLLDBIterator.py Thu Jul 14 18:33:34 2011
@@ -83,8 +83,8 @@
for i in range(target.GetNumBreakpoints()):
yours.append(target.GetBreakpointAtIndex(i))
mine = []
- for m in target.breakpoint_iter():
- mine.append(m)
+ for b in target.breakpoint_iter():
+ mine.append(b)
self.assertTrue(len(yours) == len(mine))
for i in range(len(yours)):
From johnny.chen at apple.com Thu Jul 14 18:56:51 2011
From: johnny.chen at apple.com (Johnny Chen)
Date: Thu, 14 Jul 2011 23:56:51 -0000
Subject: [Lldb-commits] [lldb] r135221 - in /lldb/trunk/include/lldb/API:
SBProcess.h SBTarget.h SBThread.h
Message-ID: <20110714235651.466E52A6C12C@llvm.org>
Author: johnny
Date: Thu Jul 14 18:56:51 2011
New Revision: 135221
URL: http://llvm.org/viewvc/llvm-project?rev=135221&view=rev
Log:
Add usage docstrings to SBTarget, SBProcess, and SBThread.
Modified:
lldb/trunk/include/lldb/API/SBProcess.h
lldb/trunk/include/lldb/API/SBTarget.h
lldb/trunk/include/lldb/API/SBThread.h
Modified: lldb/trunk/include/lldb/API/SBProcess.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBProcess.h?rev=135221&r1=135220&r2=135221&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBProcess.h (original)
+++ lldb/trunk/include/lldb/API/SBProcess.h Thu Jul 14 18:56:51 2011
@@ -21,7 +21,27 @@
#ifdef SWIG
%feature("docstring",
- "Represents the process associated with the target program."
+"Represents the process associated with the target program.
+
+SBProcess supports thread iteration. For example (from test/lldbutil.py),
+
+# ==================================================
+# Utility functions related to Threads and Processes
+# ==================================================
+
+def get_stopped_threads(process, reason):
+ '''Returns the thread(s) with the specified stop reason in a list.
+
+ The list can be empty if no such thread exists.
+ '''
+ threads = []
+ for t in process:
+ if t.GetStopReason() == reason:
+ threads.append(t)
+ return threads
+
+...
+"
) SBProcess;
#endif
class SBProcess
Modified: lldb/trunk/include/lldb/API/SBTarget.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBTarget.h?rev=135221&r1=135220&r2=135221&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBTarget.h (original)
+++ lldb/trunk/include/lldb/API/SBTarget.h Thu Jul 14 18:56:51 2011
@@ -20,7 +20,32 @@
#ifdef SWIG
%feature("docstring",
- "Represents the target program running under the debugger."
+"Represents the target program running under the debugger.
+
+SBTarget supports module and breakpoint iterations. For example,
+
+ for m in target.module_iter():
+ print m
+
+produces:
+
+(x86_64) /Volumes/data/lldb/svn/trunk/test/python_api/lldbutil/iter/a.out
+(x86_64) /usr/lib/dyld
+(x86_64) /usr/lib/libstdc++.6.dylib
+(x86_64) /usr/lib/libSystem.B.dylib
+(x86_64) /usr/lib/system/libmathCommon.A.dylib
+(x86_64) /usr/lib/libSystem.B.dylib(__commpage)
+
+and,
+
+ for b in target.breakpoint_iter():
+ print b
+
+produces:
+
+SBBreakpoint: id = 1, file ='main.cpp', line = 66, locations = 1
+SBBreakpoint: id = 2, file ='main.cpp', line = 85, locations = 1
+"
) SBTarget;
#endif
class SBTarget
Modified: lldb/trunk/include/lldb/API/SBThread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBThread.h?rev=135221&r1=135220&r2=135221&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBThread.h (original)
+++ lldb/trunk/include/lldb/API/SBThread.h Thu Jul 14 18:56:51 2011
@@ -22,24 +22,25 @@
%feature("docstring",
"Represents a thread of execution. SBProcess contains SBThread(s).
-For example (from test/lldbutil.py),
+SBThread supports frame iteration. For example (from test/python_api/
+lldbutil/iter/TestLLDBIterator.py),
-# ==================================================
-# Utility functions related to Threads and Processes
-# ==================================================
-
-def get_stopped_threads(process, reason):
- '''Returns the thread(s) with the specified stop reason in a list.
-
- The list can be empty if no such thread exists.
- '''
- threads = []
- for t in process:
- if t.GetStopReason() == reason:
- threads.append(t)
- return threads
+ from lldbutil import print_stacktrace
+ stopped_due_to_breakpoint = False
+ for thread in process:
+ if self.TraceOn():
+ print_stacktrace(thread)
+ ID = thread.GetThreadID()
+ if thread.GetStopReason() == lldb.eStopReasonBreakpoint:
+ stopped_due_to_breakpoint = True
+ for frame in thread:
+ self.assertTrue(frame.GetThread().GetThreadID() == ID)
+ if self.TraceOn():
+ print frame
-...
+ self.assertTrue(stopped_due_to_breakpoint)
+
+See also SBProcess and SBFrame.
"
) SBThread;
#endif
From johnny.chen at apple.com Thu Jul 14 19:27:47 2011
From: johnny.chen at apple.com (Johnny Chen)
Date: Fri, 15 Jul 2011 00:27:47 -0000
Subject: [Lldb-commits] [lldb] r135230 - in /lldb/trunk:
examples/python/disasm.py include/lldb/API/SBValue.h
include/lldb/API/SBValueList.h
Message-ID: <20110715002747.5BA4E2A6C12C@llvm.org>
Author: johnny
Date: Thu Jul 14 19:27:47 2011
New Revision: 135230
URL: http://llvm.org/viewvc/llvm-project?rev=135230&view=rev
Log:
Add usage docstring to SBValue.h, and minor update of docstrings for SBValueList.h.
Modified:
lldb/trunk/examples/python/disasm.py
lldb/trunk/include/lldb/API/SBValue.h
lldb/trunk/include/lldb/API/SBValueList.h
Modified: lldb/trunk/examples/python/disasm.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/python/disasm.py?rev=135230&r1=135229&r2=135230&view=diff
==============================================================================
--- lldb/trunk/examples/python/disasm.py (original)
+++ lldb/trunk/examples/python/disasm.py Thu Jul 14 19:27:47 2011
@@ -95,7 +95,7 @@
#print value
print "%s (number of children = %d):" % (value.GetName(), value.GetNumChildren())
for child in value:
- print "Name: ", child.GetName(), " Value: ", child.GetValue(frame)
+ print "Name: ", child.GetName(), " Value: ", child.GetValue()
print "Hit the breakpoint at main, enter to continue and wait for program to exit or 'Ctrl-D'/'quit' to terminate the program"
next = sys.stdin.readline()
Modified: lldb/trunk/include/lldb/API/SBValue.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBValue.h?rev=135230&r1=135229&r2=135230&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBValue.h (original)
+++ lldb/trunk/include/lldb/API/SBValue.h Thu Jul 14 19:27:47 2011
@@ -18,7 +18,47 @@
#ifdef SWIG
%feature("docstring",
- "Represents the value of a variable, a register, or an expression."
+"Represents the value of a variable, a register, or an expression.
+
+SBValue supports iteration through its child, which in turn is represented
+as an SBValue. For example, we can get the general purpose registers of a
+frame as an SBValue, and iterate through all the registers,
+
+ registerSet = frame.GetRegisters() # Returns an SBValueList.
+ for regs in registerSet:
+ if 'general purpose registers' in regs.getName().lower():
+ GPRs = regs
+ break
+
+ print '%s (number of children = %d):' % (GPRs.GetName(), GPRs.GetNumChildren())
+ for reg in GPRs:
+ print 'Name: ', reg.GetName(), ' Value: ', reg.GetValue()
+
+produces the output:
+
+General Purpose Registers (number of children = 21):
+Name: rax Value: 0x0000000100000c5c
+Name: rbx Value: 0x0000000000000000
+Name: rcx Value: 0x00007fff5fbffec0
+Name: rdx Value: 0x00007fff5fbffeb8
+Name: rdi Value: 0x0000000000000001
+Name: rsi Value: 0x00007fff5fbffea8
+Name: rbp Value: 0x00007fff5fbffe80
+Name: rsp Value: 0x00007fff5fbffe60
+Name: r8 Value: 0x0000000008668682
+Name: r9 Value: 0x0000000000000000
+Name: r10 Value: 0x0000000000001200
+Name: r11 Value: 0x0000000000000206
+Name: r12 Value: 0x0000000000000000
+Name: r13 Value: 0x0000000000000000
+Name: r14 Value: 0x0000000000000000
+Name: r15 Value: 0x0000000000000000
+Name: rip Value: 0x0000000100000dae
+Name: rflags Value: 0x0000000000000206
+Name: cs Value: 0x0000000000000027
+Name: fs Value: 0x0000000000000010
+Name: gs Value: 0x0000000000000048
+"
) SBValue;
#endif
class SBValue
Modified: lldb/trunk/include/lldb/API/SBValueList.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBValueList.h?rev=135230&r1=135229&r2=135230&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBValueList.h (original)
+++ lldb/trunk/include/lldb/API/SBValueList.h Thu Jul 14 19:27:47 2011
@@ -19,7 +19,7 @@
"Represents a collection of SBValues. Both SBFrame's GetVariables() and
GetRegisters() return a SBValueList.
-For example (from test/lldbutil.py),
+SBValueList supports SBValue iteration. For example (from test/lldbutil.py),
def get_registers(frame, kind):
'''Returns the registers given the frame and the kind of registers desired.
From granata.enrico at gmail.com Thu Jul 14 21:26:42 2011
From: granata.enrico at gmail.com (Enrico Granata)
Date: Fri, 15 Jul 2011 02:26:42 -0000
Subject: [Lldb-commits] [lldb] r135238 - in /lldb/trunk: include/lldb/
include/lldb/API/ include/lldb/Core/ include/lldb/Interpreter/
include/lldb/Utility/ lldb.xcodeproj/ scripts/ source/API/ source/Commands/
source/Core/ source/Interpreter/ source/Plugins/Process/gdb-remote/
test/functionalities/data-formatter/data-formatter-script/ www/
Message-ID: <20110715022642.A25C12A6C12C@llvm.org>
Author: enrico
Date: Thu Jul 14 21:26:42 2011
New Revision: 135238
URL: http://llvm.org/viewvc/llvm-project?rev=135238&view=rev
Log:
Python summary strings:
- you can use a Python script to write a summary string for data-types, in one of
three ways:
-P option and typing the script a line at a time
-s option and passing a one-line Python script
-F option and passing the name of a Python function
these options all work for the "type summary add" command
your Python code (if provided through -P or -s) is wrapped in a function
that accepts two parameters: valobj (a ValueObject) and dict (an LLDB
internal dictionary object). if you use -F and give a function name,
you're expected to define the function on your own and with the right
prototype. your function, however defined, must return a Python string
- test case for the Python summary feature
- a few quirks:
Python summaries cannot have names, and cannot use regex as type names
both issues will be fixed ASAP
major redesign of type summary code:
- type summary working with strings and type summary working with Python code
are two classes, with a common base class SummaryFormat
- SummaryFormat classes now are able to actively format objects rather than
just aggregating data
- cleaner code to print descriptions for summaries
the public API now exports a method to easily navigate a ValueObject hierarchy
New InputReaderEZ and PriorityPointerPair classes
Several minor fixes and improvements
Added:
lldb/trunk/include/lldb/Core/InputReaderEZ.h
lldb/trunk/include/lldb/Utility/PriorityPointerPair.h
lldb/trunk/source/Core/InputReaderEZ.cpp
lldb/trunk/test/functionalities/data-formatter/data-formatter-script/
lldb/trunk/test/functionalities/data-formatter/data-formatter-script/Makefile
lldb/trunk/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py
lldb/trunk/test/functionalities/data-formatter/data-formatter-script/main.cpp
Modified:
lldb/trunk/include/lldb/API/SBValue.h
lldb/trunk/include/lldb/Core/Debugger.h
lldb/trunk/include/lldb/Core/Error.h
lldb/trunk/include/lldb/Core/FormatManager.h
lldb/trunk/include/lldb/Core/InputReader.h
lldb/trunk/include/lldb/Core/StringList.h
lldb/trunk/include/lldb/Core/ValueObject.h
lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
lldb/trunk/include/lldb/Utility/RefCounter.h
lldb/trunk/include/lldb/lldb-forward-rtti.h
lldb/trunk/include/lldb/lldb-forward.h
lldb/trunk/lldb.xcodeproj/project.pbxproj
lldb/trunk/scripts/lldb.swig
lldb/trunk/source/API/SBCommandInterpreter.cpp
lldb/trunk/source/API/SBValue.cpp
lldb/trunk/source/Commands/CommandObjectType.cpp
lldb/trunk/source/Core/Debugger.cpp
lldb/trunk/source/Core/Error.cpp
lldb/trunk/source/Core/FormatManager.cpp
lldb/trunk/source/Core/InputReader.cpp
lldb/trunk/source/Core/StringList.cpp
lldb/trunk/source/Core/ValueObject.cpp
lldb/trunk/source/Interpreter/ScriptInterpreter.cpp
lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
lldb/trunk/www/varformats.html
Modified: lldb/trunk/include/lldb/API/SBValue.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBValue.h?rev=135238&r1=135237&r2=135238&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBValue.h (original)
+++ lldb/trunk/include/lldb/API/SBValue.h Thu Jul 14 21:26:42 2011
@@ -167,6 +167,10 @@
// classes.
lldb::SBValue
GetChildMemberWithName (const char *name, lldb::DynamicValueType use_dynamic);
+
+ // Expands nested expressions like .a->b[0].c[1]->d
+ lldb::SBValue
+ GetValueForExpressionPath(const char* expr_path);
uint32_t
GetNumChildren ();
@@ -190,12 +194,12 @@
bool
GetExpressionPath (lldb::SBStream &description, bool qualify_cxx_base_classes);
+ SBValue (const lldb::ValueObjectSP &value_sp);
+
protected:
friend class SBValueList;
friend class SBFrame;
- SBValue (const lldb::ValueObjectSP &value_sp);
-
#ifndef SWIG
// Mimic shared pointer...
Modified: lldb/trunk/include/lldb/Core/Debugger.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Debugger.h?rev=135238&r1=135237&r2=135238&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Debugger.h (original)
+++ lldb/trunk/include/lldb/Core/Debugger.h Thu Jul 14 21:26:42 2011
@@ -576,8 +576,6 @@
static uint32_t
GetCount();
};
-
-
};
} // namespace lldb_private
Modified: lldb/trunk/include/lldb/Core/Error.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Error.h?rev=135238&r1=135237&r2=135238&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Error.h (original)
+++ lldb/trunk/include/lldb/Core/Error.h Thu Jul 14 21:26:42 2011
@@ -69,6 +69,9 @@
explicit
Error (ValueType err, lldb::ErrorType type = lldb::eErrorTypeGeneric);
+ explicit
+ Error (const char* err_str);
+
Error (const Error &rhs);
//------------------------------------------------------------------
/// Assignment operator.
Modified: lldb/trunk/include/lldb/Core/FormatManager.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/FormatManager.h?rev=135238&r1=135237&r2=135238&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/FormatManager.h (original)
+++ lldb/trunk/include/lldb/Core/FormatManager.h Thu Jul 14 21:26:42 2011
@@ -50,8 +50,10 @@
#include "lldb/Core/UserID.h"
#include "lldb/Core/UserSettingsController.h"
#include "lldb/Core/ValueObject.h"
+#include "lldb/Interpreter/ScriptInterpreterPython.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Platform.h"
+#include "lldb/Target/StackFrame.h"
#include "lldb/Target/TargetList.h"
namespace lldb_private {
@@ -67,8 +69,263 @@
};
+struct ValueFormat
+{
+ bool m_cascades;
+ bool m_skip_pointers;
+ bool m_skip_references;
+ lldb::Format m_format;
+ ValueFormat (lldb::Format f = lldb::eFormatInvalid,
+ bool casc = false,
+ bool skipptr = false,
+ bool skipref = false) :
+ m_cascades(casc),
+ m_skip_pointers(skipptr),
+ m_skip_references(skipref),
+ m_format (f)
+ {
+ }
+
+ typedef lldb::SharedPtr
::Type SharedPointer;
+ typedef bool(*ValueCallback)(void*, const char*, const ValueFormat::SharedPointer&);
+
+ ~ValueFormat()
+ {
+ }
+
+ bool
+ Cascades()
+ {
+ return m_cascades;
+ }
+ bool
+ SkipsPointers()
+ {
+ return m_skip_pointers;
+ }
+ bool
+ SkipsReferences()
+ {
+ return m_skip_references;
+ }
+
+ lldb::Format
+ GetFormat()
+ {
+ return m_format;
+ }
+
+ std::string
+ FormatObject(lldb::ValueObjectSP object)
+ {
+ if (!object.get())
+ return "NULL";
+
+ StreamString sstr;
+
+ if (ClangASTType::DumpTypeValue (object->GetClangAST(), // The clang AST
+ object->GetClangType(), // The clang type to display
+ &sstr,
+ m_format, // Format to display this type with
+ object->GetDataExtractor(), // Data to extract from
+ 0, // Byte offset into "data"
+ object->GetByteSize(), // Byte size of item in "data"
+ object->GetBitfieldBitSize(), // Bitfield bit size
+ object->GetBitfieldBitOffset())) // Bitfield bit offset
+ return (sstr.GetString());
+ else
+ {
+ return ("unsufficient data for value");
+ }
+
+ }
+
+};
+
struct SummaryFormat
{
+ bool m_cascades;
+ bool m_skip_pointers;
+ bool m_skip_references;
+ bool m_dont_show_children;
+ bool m_dont_show_value;
+ bool m_show_members_oneliner;
+
+ SummaryFormat(bool casc = false,
+ bool skipptr = false,
+ bool skipref = false,
+ bool nochildren = true,
+ bool novalue = true,
+ bool oneliner = false) :
+ m_cascades(casc),
+ m_skip_pointers(skipptr),
+ m_skip_references(skipref),
+ m_dont_show_children(nochildren),
+ m_dont_show_value(novalue),
+ m_show_members_oneliner(oneliner)
+ {
+ }
+
+ bool
+ Cascades()
+ {
+ return m_cascades;
+ }
+ bool
+ SkipsPointers()
+ {
+ return m_skip_pointers;
+ }
+ bool
+ SkipsReferences()
+ {
+ return m_skip_references;
+ }
+
+ bool
+ DoesPrintChildren() const
+ {
+ return !m_dont_show_children;
+ }
+
+ bool
+ DoesPrintValue() const
+ {
+ return !m_dont_show_value;
+ }
+
+ bool
+ IsOneliner() const
+ {
+ return m_show_members_oneliner;
+ }
+
+ virtual
+ ~SummaryFormat()
+ {
+ }
+
+ virtual std::string
+ FormatObject(lldb::ValueObjectSP object) = 0;
+
+ virtual std::string
+ GetDescription() = 0;
+
+ typedef lldb::SharedPtr::Type SharedPointer;
+ typedef bool(*SummaryCallback)(void*, const char*, const SummaryFormat::SharedPointer&);
+ typedef bool(*RegexSummaryCallback)(void*, lldb::RegularExpressionSP, const SummaryFormat::SharedPointer&);
+
+};
+
+// simple string-based summaries, using ${var to show data
+struct StringSummaryFormat : public SummaryFormat
+{
+ std::string m_format;
+
+ StringSummaryFormat(bool casc = false,
+ bool skipptr = false,
+ bool skipref = false,
+ bool nochildren = true,
+ bool novalue = true,
+ bool oneliner = false,
+ std::string f = "") :
+ SummaryFormat(casc,skipptr,skipref,nochildren,novalue,oneliner),
+ m_format(f)
+ {
+ }
+
+ std::string
+ GetFormat()
+ {
+ return m_format;
+ }
+
+ virtual
+ ~StringSummaryFormat()
+ {
+ }
+
+ virtual std::string
+ FormatObject(lldb::ValueObjectSP object);
+
+ virtual std::string
+ GetDescription()
+ {
+ StreamString sstr;
+ sstr.Printf ("`%s`%s%s%s%s%s%s\n", m_format.c_str(),
+ m_cascades ? "" : " (not cascading)",
+ m_dont_show_children ? "" : " (show children)",
+ m_dont_show_value ? " (hide value)" : "",
+ m_show_members_oneliner ? " (one-line printout)" : "",
+ m_skip_pointers ? " (skip pointers)" : "",
+ m_skip_references ? " (skip references)" : "");
+ return sstr.GetString();
+ }
+
+};
+
+// Python-based summaries, running script code to show data
+struct ScriptSummaryFormat : public SummaryFormat
+{
+ std::string m_function_name;
+ std::string m_python_script;
+
+ ScriptSummaryFormat(bool casc = false,
+ bool skipptr = false,
+ bool skipref = false,
+ bool nochildren = true,
+ bool novalue = true,
+ bool oneliner = false,
+ std::string fname = "",
+ std::string pscri = "") :
+ SummaryFormat(casc,skipptr,skipref,nochildren,novalue,oneliner),
+ m_function_name(fname),
+ m_python_script(pscri)
+ {
+ }
+
+ std::string
+ GetFunctionName()
+ {
+ return m_function_name;
+ }
+
+ std::string
+ GetPythonScript()
+ {
+ return m_python_script;
+ }
+
+ virtual
+ ~ScriptSummaryFormat()
+ {
+ }
+
+ virtual std::string
+ FormatObject(lldb::ValueObjectSP object)
+ {
+ return std::string(ScriptInterpreterPython::CallPythonScriptFunction(m_function_name.c_str(),
+ object).c_str());
+ }
+
+ virtual std::string
+ GetDescription()
+ {
+ StreamString sstr;
+ sstr.Printf ("%s%s%s\n%s\n", m_cascades ? "" : " (not cascading)",
+ m_skip_pointers ? " (skip pointers)" : "",
+ m_skip_references ? " (skip references)" : "",
+ m_python_script.c_str());
+ return sstr.GetString();
+
+ }
+
+ typedef lldb::SharedPtr::Type SharedPointer;
+
+};
+
+/*struct SummaryFormat
+{
std::string m_format;
bool m_dont_show_children;
bool m_dont_show_value;
@@ -116,32 +373,35 @@
typedef bool(*RegexSummaryCallback)(void*, lldb::RegularExpressionSP, const SummaryFormat::SharedPointer&);
};
-
-struct ValueFormat
+
+struct ScriptFormat
{
- lldb::Format m_format;
+ std::string m_function_name;
+ std::string m_python_script;
bool m_cascades;
bool m_skip_references;
bool m_skip_pointers;
- ValueFormat (lldb::Format f = lldb::eFormatInvalid,
- bool c = false,
- bool skipptr = false,
- bool skipref = false) :
- m_format (f),
+ ScriptFormat (std::string n,
+ std::string s = "",
+ bool c = false,
+ bool skipptr = false,
+ bool skipref = false) :
+ m_function_name (n),
+ m_python_script(s),
m_cascades (c),
m_skip_references(skipref),
m_skip_pointers(skipptr)
{
}
- typedef lldb::SharedPtr::Type SharedPointer;
- typedef bool(*ValueCallback)(void*, const char*, const ValueFormat::SharedPointer&);
+ typedef lldb::SharedPtr::Type SharedPointer;
+ typedef bool(*ScriptCallback)(void*, const char*, const ScriptFormat::SharedPointer&);
- ~ValueFormat()
+ ~ScriptFormat()
{
}
-};
+};*/
template
class FormatNavigator;
@@ -457,11 +717,13 @@
typedef FormatNavigator ValueNavigator;
typedef FormatNavigator SummaryNavigator;
typedef FormatNavigator RegexSummaryNavigator;
+ typedef FormatNavigator ScriptNavigator;
typedef ValueNavigator::MapType ValueMap;
typedef SummaryNavigator::MapType SummaryMap;
typedef RegexSummaryNavigator::MapType RegexSummaryMap;
typedef FormatMap NamedSummariesMap;
+ typedef ScriptNavigator::MapType ScriptMap;
ValueNavigator m_value_nav;
SummaryNavigator m_summary_nav;
@@ -469,6 +731,8 @@
NamedSummariesMap m_named_summaries_map;
+ ScriptNavigator m_script_nav;
+
uint32_t m_last_revision;
public:
@@ -478,6 +742,7 @@
m_summary_nav(this),
m_regex_summary_nav(this),
m_named_summaries_map(this),
+ m_script_nav(this),
m_last_revision(0)
{
}
@@ -487,6 +752,7 @@
SummaryNavigator& Summary() { return m_summary_nav; }
RegexSummaryNavigator& RegexSummary() { return m_regex_summary_nav; }
NamedSummariesMap& NamedSummary() { return m_named_summaries_map; }
+ ScriptNavigator& Script() { return m_script_nav; }
static bool
GetFormatFromCString (const char *format_cstr,
Modified: lldb/trunk/include/lldb/Core/InputReader.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/InputReader.h?rev=135238&r1=135237&r2=135238&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/InputReader.h (original)
+++ lldb/trunk/include/lldb/Core/InputReader.h Thu Jul 14 21:26:42 2011
@@ -12,7 +12,7 @@
#include "lldb/lldb-public.h"
#include "lldb/lldb-enumerations.h"
-#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Error.h"
#include "lldb/Host/Predicate.h"
@@ -27,6 +27,31 @@
lldb::InputReaderAction notification,
const char *bytes,
size_t bytes_len);
+
+ struct HandlerData
+ {
+ InputReader& reader;
+ const char *bytes;
+ size_t bytes_len;
+ void* baton;
+
+ HandlerData(InputReader& r,
+ const char* b,
+ size_t l,
+ void* t) :
+ reader(r),
+ bytes(b),
+ bytes_len(l),
+ baton(t)
+ {
+ }
+
+ lldb::StreamSP
+ GetOutStream();
+
+ bool
+ GetBatchMode();
+ };
InputReader (Debugger &debugger);
@@ -41,6 +66,41 @@
const char *prompt,
bool echo);
+ virtual Error Initialize(void* baton,
+ lldb::InputReaderGranularity token_size = lldb::eInputReaderGranularityLine,
+ const char* end_token = "DONE",
+ const char *prompt = "> ",
+ bool echo = true)
+ {
+ return Error("unimplemented");
+ }
+
+ // to use these handlers instead of the Callback function, you must subclass
+ // InputReaderEZ, and redefine the handlers for the events you care about
+ virtual void
+ ActivateHandler(HandlerData&) {}
+
+ virtual void
+ DeactivateHandler(HandlerData&) {}
+
+ virtual void
+ ReactivateHandler(HandlerData&) {}
+
+ virtual void
+ AsynchronousOutputWrittenHandler(HandlerData&) {}
+
+ virtual void
+ GotTokenHandler(HandlerData&) {}
+
+ virtual void
+ InterruptHandler(HandlerData&) {}
+
+ virtual void
+ EOFHandler(HandlerData&) {}
+
+ virtual void
+ DoneHandler(HandlerData&) {}
+
bool
IsDone () const
{
Added: lldb/trunk/include/lldb/Core/InputReaderEZ.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/InputReaderEZ.h?rev=135238&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Core/InputReaderEZ.h (added)
+++ lldb/trunk/include/lldb/Core/InputReaderEZ.h Thu Jul 14 21:26:42 2011
@@ -0,0 +1,81 @@
+//===-- InputReaderEZ.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_InputReaderEZ_h_
+#define liblldb_InputReaderEZ_h_
+
+#include "lldb/lldb-public.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/InputReader.h"
+#include "lldb/Host/Predicate.h"
+
+
+namespace lldb_private {
+
+class InputReaderEZ : public InputReader
+{
+
+private:
+
+ static size_t Callback_Impl(void *baton,
+ InputReader &reader,
+ lldb::InputReaderAction notification,
+ const char *bytes,
+ size_t bytes_len);
+public:
+
+ InputReaderEZ (Debugger &debugger) :
+ InputReader(debugger)
+ {}
+
+ virtual
+ ~InputReaderEZ ();
+
+ virtual Error Initialize(void* baton,
+ lldb::InputReaderGranularity token_size = lldb::eInputReaderGranularityLine,
+ const char* end_token = "DONE",
+ const char *prompt = "> ",
+ bool echo = true);
+
+ virtual void
+ ActivateHandler(HandlerData&) {}
+
+ virtual void
+ DeactivateHandler(HandlerData&) {}
+
+ virtual void
+ ReactivateHandler(HandlerData&) {}
+
+ virtual void
+ AsynchronousOutputWrittenHandler(HandlerData&) {}
+
+ virtual void
+ GotTokenHandler(HandlerData&) {}
+
+ virtual void
+ InterruptHandler(HandlerData&) {}
+
+ virtual void
+ EOFHandler(HandlerData&) {}
+
+ virtual void
+ DoneHandler(HandlerData&) {}
+
+protected:
+ friend class Debugger;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN (InputReaderEZ);
+
+};
+
+} // namespace lldb_private
+
+#endif // #ifndef liblldb_InputReaderEZ_h_
Modified: lldb/trunk/include/lldb/Core/StringList.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/StringList.h?rev=135238&r1=135237&r2=135238&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/StringList.h (original)
+++ lldb/trunk/include/lldb/Core/StringList.h Thu Jul 14 21:26:42 2011
@@ -68,7 +68,17 @@
size_t
SplitIntoLines (const char *lines, size_t len);
+
+ std::string
+ CopyList(const char* item_preamble = NULL,
+ const char* items_sep = "\n");
+
+ StringList&
+ operator << (const char* str);
+ StringList&
+ operator << (StringList strings);
+
private:
STLStringArray m_strings;
Modified: lldb/trunk/include/lldb/Core/ValueObject.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=135238&r1=135237&r2=135238&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObject.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObject.h Thu Jul 14 21:26:42 2011
@@ -27,6 +27,7 @@
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/ExecutionContextScope.h"
#include "lldb/Target/StackID.h"
+#include "lldb/Utility/PriorityPointerPair.h"
#include "lldb/Utility/SharedCluster.h"
namespace lldb_private {
@@ -75,7 +76,8 @@
{
eDisplayValue = 1,
eDisplaySummary,
- eDisplayLanguageSpecific
+ eDisplayLanguageSpecific,
+ eDisplayLocation
};
enum ExpressionPathScanEndReason
@@ -731,8 +733,8 @@
lldb::Format m_format;
uint32_t m_last_format_mgr_revision;
lldb::SummaryFormatSP m_last_summary_format;
- lldb::ValueFormatSP m_last_value_format;
lldb::SummaryFormatSP m_forced_summary_format;
+ lldb::ValueFormatSP m_last_value_format;
lldb::user_id_t m_user_id_of_forced_summary;
bool m_value_is_valid:1,
m_value_did_change:1,
@@ -802,6 +804,9 @@
void
SetValueIsValid (bool valid);
+
+ void
+ ClearUserVisibleData();
public:
lldb::addr_t
Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h?rev=135238&r1=135237&r2=135238&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h (original)
+++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h Thu Jul 14 21:26:42 2011
@@ -26,6 +26,13 @@
const char *session_dictionary_name,
const lldb::StackFrameSP& frame_sp,
const lldb::BreakpointLocationSP &bp_loc_sp);
+
+ typedef
+
+ typedef std::string (*SWIGPythonTypeScriptCallbackFunction) (const char *python_function_name,
+ const char *session_dictionary_name,
+ const lldb::ValueObjectSP& valobj_sp);
+
typedef enum
{
eCharPtr,
@@ -77,6 +84,25 @@
{
return false;
}
+
+ virtual bool
+ GenerateTypeScriptFunction (StringList &input, StringList &output)
+ {
+ return false;
+ }
+
+ // use this if the function code is just a one-liner script
+ virtual bool
+ GenerateTypeScriptFunction (const char* oneliner, StringList &output)
+ {
+ return false;
+ }
+
+ virtual bool
+ GenerateFunction(std::string& signature, StringList &input, StringList &output)
+ {
+ return false;
+ }
virtual void
CollectDataForBreakpointCommandCallback (BreakpointOptions *bp_options,
@@ -104,7 +130,8 @@
static void
InitializeInterpreter (SWIGInitCallback python_swig_init_callback,
- SWIGBreakpointCallbackFunction python_swig_breakpoint_callback);
+ SWIGBreakpointCallbackFunction python_swig_breakpoint_callback,
+ SWIGPythonTypeScriptCallbackFunction python_swig_typescript_callback);
static void
TerminateInterpreter ();
Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h?rev=135238&r1=135237&r2=135238&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h (original)
+++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h Thu Jul 14 21:26:42 2011
@@ -50,6 +50,16 @@
ExportFunctionDefinitionToInterpreter (StringList &function_def);
bool
+ GenerateTypeScriptFunction (StringList &input, StringList &output);
+
+ // use this if the function code is just a one-liner script
+ bool
+ GenerateTypeScriptFunction (const char* oneliner, StringList &output);
+
+ bool
+ GenerateFunction(std::string& signature, StringList &input, StringList &output);
+
+ bool
GenerateBreakpointCommandCallbackData (StringList &input, StringList &output);
static size_t
@@ -64,6 +74,10 @@
StoppointCallbackContext *context,
lldb::user_id_t break_id,
lldb::user_id_t break_loc_id);
+
+ static std::string
+ CallPythonScriptFunction (const char *python_function_name,
+ lldb::ValueObjectSP valobj);
void
CollectDataForBreakpointCommandCallback (BreakpointOptions *bp_options,
@@ -88,7 +102,8 @@
static void
InitializeInterpreter (SWIGInitCallback python_swig_init_callback,
- SWIGBreakpointCallbackFunction python_swig_breakpoint_callback);
+ SWIGBreakpointCallbackFunction python_swig_breakpoint_callback,
+ SWIGPythonTypeScriptCallbackFunction python_swig_typescript_callback);
protected:
Added: lldb/trunk/include/lldb/Utility/PriorityPointerPair.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Utility/PriorityPointerPair.h?rev=135238&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Utility/PriorityPointerPair.h (added)
+++ lldb/trunk/include/lldb/Utility/PriorityPointerPair.h Thu Jul 14 21:26:42 2011
@@ -0,0 +1,150 @@
+//===-- PriorityPointerPair.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_PriorityPointerPair_h_
+#define liblldb_PriorityPointerPair_h_
+
+#include "lldb/lldb-public.h"
+#include "lldb/Utility/SharingPtr.h"
+
+namespace lldb_utility {
+
+//----------------------------------------------------------------------
+// A prioritized pair of SharedPtr. One of the two pointers is high
+// priority, the other is low priority.
+// The Get() method always returns high, if *high != NULL,
+// otherwise, low is returned (even if *low == NULL)
+//----------------------------------------------------------------------
+
+template
+class PriorityPointerPair
+{
+public:
+
+ typedef T& reference_type;
+ typedef T* pointer_type;
+
+ typedef typename lldb::SharedPtr::Type T_SP;
+
+ PriorityPointerPair() :
+ m_high(),
+ m_low()
+ {}
+
+ PriorityPointerPair(pointer_type high,
+ pointer_type low) :
+ m_high(high),
+ m_low(low)
+ {}
+
+ PriorityPointerPair(pointer_type low) :
+ m_high(),
+ m_low(low)
+ {}
+
+ PriorityPointerPair(T_SP& high,
+ T_SP& low) :
+ m_high(high),
+ m_low(low)
+ {}
+
+ PriorityPointerPair(T_SP& low) :
+ m_high(),
+ m_low(low)
+ {}
+
+ void
+ SwapLow(pointer_type l)
+ {
+ m_low.swap(l);
+ }
+
+ void
+ SwapHigh(pointer_type h)
+ {
+ m_high.swap(h);
+ }
+
+ void
+ SwapLow(T_SP l)
+ {
+ m_low.swap(l);
+ }
+
+ void
+ SwapHigh(T_SP h)
+ {
+ m_high.swap(h);
+ }
+
+ T_SP
+ GetLow()
+ {
+ return m_low;
+ }
+
+ T_SP
+ GetHigh()
+ {
+ return m_high;
+ }
+
+ T_SP
+ Get()
+ {
+ if (m_high.get())
+ return m_high;
+ return m_low;
+ }
+
+ void
+ ResetHigh()
+ {
+ m_high.reset();
+ }
+
+ void
+ ResetLow()
+ {
+ m_low.reset();
+ }
+
+ void
+ Reset()
+ {
+ ResetLow();
+ ResetHigh();
+ }
+
+ reference_type
+ operator*() const
+ {
+ return Get().operator*();
+ }
+
+ pointer_type
+ operator->() const
+ {
+ return Get().operator->();
+ }
+
+ ~PriorityPointerPair();
+
+private:
+
+ T_SP m_high;
+ T_SP m_low;
+
+ DISALLOW_COPY_AND_ASSIGN (PriorityPointerPair);
+
+};
+
+} // namespace lldb_utility
+
+#endif // #ifndef liblldb_PriorityPointerPair_h_
Modified: lldb/trunk/include/lldb/Utility/RefCounter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Utility/RefCounter.h?rev=135238&r1=135237&r2=135238&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Utility/RefCounter.h (original)
+++ lldb/trunk/include/lldb/Utility/RefCounter.h Thu Jul 14 21:26:42 2011
@@ -20,8 +20,6 @@
// RefCounter ref(ptr);
// (of course, the pointer is a shared resource, and must be accessible to
// everyone who needs it). Synchronization is handled by RefCounter itself
-// To check if more than 1 RefCounter is attached to the same value, you can
-// either call shared(), or simply cast ref to bool
// The counter is decreased each time a RefCounter to it goes out of scope
//----------------------------------------------------------------------
class RefCounter
Modified: lldb/trunk/include/lldb/lldb-forward-rtti.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward-rtti.h?rev=135238&r1=135237&r2=135238&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-forward-rtti.h (original)
+++ lldb/trunk/include/lldb/lldb-forward-rtti.h Thu Jul 14 21:26:42 2011
@@ -56,11 +56,13 @@
typedef SharedPtr::Type RegularExpressionSP;
typedef SharedPtr::Type SectionSP;
typedef SharedPtr::Type SearchFilterSP;
+ typedef SharedPtr::Type ScriptFormatSP;
typedef SharedPtr::Type StackFrameSP;
typedef SharedPtr::Type StackFrameListSP;
typedef SharedPtr::Type StopInfoSP;
typedef SharedPtr::Type StoppointLocationSP;
typedef SharedPtr::Type StreamSP;
+ typedef SharedPtr::Type StringSummaryFormatSP;
typedef SharedPtr::Type SummaryFormatSP;
typedef SharedPtr::Type SymbolFileSP;
typedef SharedPtr::Type SymbolContextSpecifierSP;
Modified: lldb/trunk/include/lldb/lldb-forward.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward.h?rev=135238&r1=135237&r2=135238&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-forward.h (original)
+++ lldb/trunk/include/lldb/lldb-forward.h Thu Jul 14 21:26:42 2011
@@ -114,6 +114,7 @@
class RegisterValue;
class RegularExpression;
class Scalar;
+class ScriptSummaryFormat;
class ScriptInterpreter;
class ScriptInterpreterPython;
class SearchFilter;
@@ -131,6 +132,7 @@
class StreamFile;
class StreamString;
class StringList;
+class StringSummaryFormat;
class SummaryFormat;
class Symbol;
class SymbolContext;
Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=135238&r1=135237&r2=135238&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Thu Jul 14 21:26:42 2011
@@ -402,6 +402,7 @@
4CCA645613B40B82003BDF98 /* AppleObjCTrampolineHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CCA644813B40B82003BDF98 /* AppleObjCTrampolineHandler.cpp */; };
4CCA645813B40B82003BDF98 /* AppleThreadPlanStepThroughObjCTrampoline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CCA644A13B40B82003BDF98 /* AppleThreadPlanStepThroughObjCTrampoline.cpp */; };
4CD0BD0F134BFADF00CB44D4 /* ValueObjectDynamicValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CD0BD0E134BFADF00CB44D4 /* ValueObjectDynamicValue.cpp */; };
+ 94031A9E13CF486700DCFF3C /* InputReaderEZ.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94031A9D13CF486600DCFF3C /* InputReaderEZ.cpp */; };
9415F61813B2C0EF00A52B36 /* FormatManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9415F61713B2C0EF00A52B36 /* FormatManager.cpp */; };
94611EB213CCA4A4003A22AF /* RefCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94611EB113CCA4A4003A22AF /* RefCounter.cpp */; };
9463D4CD13B1798800C230D4 /* CommandObjectType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9463D4CC13B1798800C230D4 /* CommandObjectType.cpp */; };
@@ -631,8 +632,8 @@
261B5A5311C3F2AD00AABD0A /* SharingPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SharingPtr.h; path = include/lldb/Utility/SharingPtr.h; sourceTree = ""; };
26217930133BC8640083B112 /* lldb-private-types.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "lldb-private-types.h"; path = "include/lldb/lldb-private-types.h"; sourceTree = ""; };
26217932133BCB850083B112 /* lldb-private-enumerations.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "lldb-private-enumerations.h"; path = "include/lldb/lldb-private-enumerations.h"; sourceTree = ""; };
- 263664921140A4930075843B /* Debugger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Debugger.cpp; path = source/Core/Debugger.cpp; sourceTree = ""; };
- 263664941140A4C10075843B /* Debugger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Debugger.h; path = include/lldb/Core/Debugger.h; sourceTree = ""; };
+ 263664921140A4930075843B /* Debugger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = Debugger.cpp; path = source/Core/Debugger.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
+ 263664941140A4C10075843B /* Debugger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = Debugger.h; path = include/lldb/Core/Debugger.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
26368A3B126B697600E8659F /* darwin-debug.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "darwin-debug.cpp"; path = "tools/darwin-debug/darwin-debug.cpp"; sourceTree = ""; };
263E949D13661AE400E7D1CE /* UnwindAssembly-x86.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = "UnwindAssembly-x86.cpp"; sourceTree = ""; };
263E949E13661AE400E7D1CE /* UnwindAssembly-x86.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UnwindAssembly-x86.h"; sourceTree = ""; };
@@ -677,7 +678,7 @@
266F5CBB12FC846200DFCE33 /* Config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Config.h; path = include/lldb/Host/Config.h; sourceTree = ""; };
2671A0CD134825F6003A87BB /* ConnectionMachPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ConnectionMachPort.h; path = include/lldb/Core/ConnectionMachPort.h; sourceTree = ""; };
2671A0CF13482601003A87BB /* ConnectionMachPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ConnectionMachPort.cpp; path = source/Core/ConnectionMachPort.cpp; sourceTree = ""; };
- 2672D8461189055500FF4019 /* CommandObjectFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectFrame.cpp; path = source/Commands/CommandObjectFrame.cpp; sourceTree = ""; };
+ 2672D8461189055500FF4019 /* CommandObjectFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = CommandObjectFrame.cpp; path = source/Commands/CommandObjectFrame.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
2672D8471189055500FF4019 /* CommandObjectFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectFrame.h; path = source/Commands/CommandObjectFrame.h; sourceTree = ""; };
26744EED1338317700EF765A /* GDBRemoteCommunicationClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GDBRemoteCommunicationClient.cpp; sourceTree = ""; };
26744EEE1338317700EF765A /* GDBRemoteCommunicationClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDBRemoteCommunicationClient.h; sourceTree = ""; };
@@ -724,7 +725,7 @@
26A0604811A5D03C00F75969 /* Baton.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Baton.cpp; path = source/Core/Baton.cpp; sourceTree = ""; };
26A3B4AC1181454800381BC2 /* ObjectContainerBSDArchive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ObjectContainerBSDArchive.cpp; sourceTree = ""; };
26A3B4AD1181454800381BC2 /* ObjectContainerBSDArchive.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjectContainerBSDArchive.h; sourceTree = ""; };
- 26A4EEB511682AAC007A372A /* LLDBWrapPython.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLDBWrapPython.cpp; path = source/LLDBWrapPython.cpp; sourceTree = ""; };
+ 26A4EEB511682AAC007A372A /* LLDBWrapPython.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = LLDBWrapPython.cpp; path = source/LLDBWrapPython.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
26A7A034135E6E4200FB369E /* NamedOptionValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NamedOptionValue.cpp; path = source/Interpreter/NamedOptionValue.cpp; sourceTree = ""; };
26A7A036135E6E5300FB369E /* NamedOptionValue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = NamedOptionValue.h; path = include/lldb/Interpreter/NamedOptionValue.h; sourceTree = ""; };
26B167A41123BF5500DC7B4F /* ThreadSafeValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadSafeValue.h; path = include/lldb/Core/ThreadSafeValue.h; sourceTree = ""; };
@@ -830,7 +831,7 @@
26BC7D7E10F1B77400F91463 /* Timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Timer.h; path = include/lldb/Core/Timer.h; sourceTree = ""; };
26BC7D8010F1B77400F91463 /* UserID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UserID.h; path = include/lldb/Core/UserID.h; sourceTree = ""; };
26BC7D8110F1B77400F91463 /* Value.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Value.h; path = include/lldb/Core/Value.h; sourceTree = ""; };
- 26BC7D8210F1B77400F91463 /* ValueObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ValueObject.h; path = include/lldb/Core/ValueObject.h; sourceTree = ""; };
+ 26BC7D8210F1B77400F91463 /* ValueObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = ValueObject.h; path = include/lldb/Core/ValueObject.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
26BC7D8310F1B77400F91463 /* ValueObjectChild.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ValueObjectChild.h; path = include/lldb/Core/ValueObjectChild.h; sourceTree = ""; };
26BC7D8410F1B77400F91463 /* ValueObjectList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ValueObjectList.h; path = include/lldb/Core/ValueObjectList.h; sourceTree = ""; };
26BC7D8510F1B77400F91463 /* ValueObjectVariable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ValueObjectVariable.h; path = include/lldb/Core/ValueObjectVariable.h; sourceTree = ""; };
@@ -928,7 +929,7 @@
26BC7E9610F1B85900F91463 /* Timer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Timer.cpp; path = source/Core/Timer.cpp; sourceTree = ""; };
26BC7E9810F1B85900F91463 /* UserID.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UserID.cpp; path = source/Core/UserID.cpp; sourceTree = ""; };
26BC7E9910F1B85900F91463 /* Value.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Value.cpp; path = source/Core/Value.cpp; sourceTree = ""; };
- 26BC7E9A10F1B85900F91463 /* ValueObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObject.cpp; path = source/Core/ValueObject.cpp; sourceTree = ""; };
+ 26BC7E9A10F1B85900F91463 /* ValueObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = ValueObject.cpp; path = source/Core/ValueObject.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
26BC7E9B10F1B85900F91463 /* ValueObjectChild.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectChild.cpp; path = source/Core/ValueObjectChild.cpp; sourceTree = ""; };
26BC7E9C10F1B85900F91463 /* ValueObjectList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectList.cpp; path = source/Core/ValueObjectList.cpp; sourceTree = ""; };
26BC7E9D10F1B85900F91463 /* ValueObjectVariable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectVariable.cpp; path = source/Core/ValueObjectVariable.cpp; sourceTree = ""; };
@@ -1019,8 +1020,8 @@
26DB3E141379E7AD0080DC73 /* ABISysV_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ABISysV_x86_64.h; sourceTree = ""; };
26DC6A101337FE6900FF7998 /* lldb-platform */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "lldb-platform"; sourceTree = BUILT_PRODUCTS_DIR; };
26DC6A1C1337FECA00FF7998 /* lldb-platform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "lldb-platform.cpp"; path = "tools/lldb-platform/lldb-platform.cpp"; sourceTree = ""; };
- 26DE1E6911616C2E00A093E2 /* lldb-forward-rtti.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "lldb-forward-rtti.h"; path = "include/lldb/lldb-forward-rtti.h"; sourceTree = ""; };
- 26DE1E6A11616C2E00A093E2 /* lldb-forward.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "lldb-forward.h"; path = "include/lldb/lldb-forward.h"; sourceTree = ""; };
+ 26DE1E6911616C2E00A093E2 /* lldb-forward-rtti.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = "lldb-forward-rtti.h"; path = "include/lldb/lldb-forward-rtti.h"; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
+ 26DE1E6A11616C2E00A093E2 /* lldb-forward.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = "lldb-forward.h"; path = "include/lldb/lldb-forward.h"; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
26DE204011618AB900A093E2 /* SBSymbolContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBSymbolContext.h; path = include/lldb/API/SBSymbolContext.h; sourceTree = ""; };
26DE204211618ACA00A093E2 /* SBAddress.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBAddress.h; path = include/lldb/API/SBAddress.h; sourceTree = ""; };
26DE204411618ADA00A093E2 /* SBAddress.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBAddress.cpp; path = source/API/SBAddress.cpp; sourceTree = ""; };
@@ -1169,11 +1170,14 @@
69A01E1E1236C5D400C660B5 /* Mutex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Mutex.cpp; sourceTree = ""; };
69A01E1F1236C5D400C660B5 /* Symbols.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Symbols.cpp; sourceTree = ""; };
69A01E201236C5D400C660B5 /* TimeValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TimeValue.cpp; sourceTree = ""; };
- 9415F61613B2C0DC00A52B36 /* FormatManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FormatManager.h; path = include/lldb/Core/FormatManager.h; sourceTree = ""; };
- 9415F61713B2C0EF00A52B36 /* FormatManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FormatManager.cpp; path = source/Core/FormatManager.cpp; sourceTree = ""; };
+ 94031A9B13CF484600DCFF3C /* InputReaderEZ.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = InputReaderEZ.h; path = include/lldb/Core/InputReaderEZ.h; sourceTree = ""; };
+ 94031A9D13CF486600DCFF3C /* InputReaderEZ.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InputReaderEZ.cpp; path = source/Core/InputReaderEZ.cpp; sourceTree = ""; };
+ 94031A9F13CF5B3D00DCFF3C /* PriorityPointerPair.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PriorityPointerPair.h; path = include/lldb/Utility/PriorityPointerPair.h; sourceTree = ""; };
+ 9415F61613B2C0DC00A52B36 /* FormatManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = FormatManager.h; path = include/lldb/Core/FormatManager.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
+ 9415F61713B2C0EF00A52B36 /* FormatManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = FormatManager.cpp; path = source/Core/FormatManager.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
94611EAF13CCA363003A22AF /* RefCounter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RefCounter.h; path = include/lldb/Utility/RefCounter.h; sourceTree = ""; };
94611EB113CCA4A4003A22AF /* RefCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RefCounter.cpp; path = source/Utility/RefCounter.cpp; sourceTree = ""; };
- 9463D4CC13B1798800C230D4 /* CommandObjectType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectType.cpp; path = source/Commands/CommandObjectType.cpp; sourceTree = ""; };
+ 9463D4CC13B1798800C230D4 /* CommandObjectType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = CommandObjectType.cpp; path = source/Commands/CommandObjectType.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
9463D4CE13B179A500C230D4 /* CommandObjectType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CommandObjectType.h; path = source/Commands/CommandObjectType.h; sourceTree = ""; };
9467E65113C3D97600B3B6F3 /* TypeHierarchyNavigator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TypeHierarchyNavigator.cpp; path = source/Symbol/TypeHierarchyNavigator.cpp; sourceTree = ""; };
9467E65413C3D98900B3B6F3 /* TypeHierarchyNavigator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TypeHierarchyNavigator.h; path = include/lldb/Symbol/TypeHierarchyNavigator.h; sourceTree = ""; };
@@ -1797,6 +1801,7 @@
2676A093119C93C8008A98EF /* StringExtractorGDBRemote.cpp */,
2682F16B115EDA0D00CCFF99 /* PseudoTerminal.h */,
2682F16A115EDA0D00CCFF99 /* PseudoTerminal.cpp */,
+ 94031A9F13CF5B3D00DCFF3C /* PriorityPointerPair.h */,
);
name = Utility;
sourceTree = "";
@@ -1929,6 +1934,8 @@
26F73061139D8FDB00FD51C7 /* History.cpp */,
9AA69DBB118A029E00D753A0 /* InputReader.h */,
9AA69DB5118A027A00D753A0 /* InputReader.cpp */,
+ 94031A9B13CF484600DCFF3C /* InputReaderEZ.h */,
+ 94031A9D13CF486600DCFF3C /* InputReaderEZ.cpp */,
9A9E1F0013980943005AC039 /* InputReaderStack.h */,
9A9E1EFE1398086D005AC039 /* InputReaderStack.cpp */,
26BC7D6510F1B77400F91463 /* IOStreamMacros.h */,
@@ -3271,6 +3278,7 @@
26ED3D6D13C563810017D45E /* OptionGroupVariable.cpp in Sources */,
26F4214413C6515B00E04E5E /* DynamicLoaderMacOSXKernel.cpp in Sources */,
94611EB213CCA4A4003A22AF /* RefCounter.cpp in Sources */,
+ 94031A9E13CF486700DCFF3C /* InputReaderEZ.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Modified: lldb/trunk/scripts/lldb.swig
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/lldb.swig?rev=135238&r1=135237&r2=135238&view=diff
==============================================================================
--- lldb/trunk/scripts/lldb.swig (original)
+++ lldb/trunk/scripts/lldb.swig Thu Jul 14 21:26:42 2011
@@ -359,4 +359,128 @@
return stop_at_breakpoint;
}
+SWIGEXPORT std::string
+LLDBSwigPythonCallTypeScript
+(
+ const char *python_function_name,
+ const char *session_dictionary_name,
+ const lldb::ValueObjectSP& valobj_sp
+)
+{
+ lldb::SBValue sb_value (valobj_sp);
+
+ std::string retval = "";
+
+ PyObject *ValObj_PyObj = SWIG_NewPointerObj((void *) &valobj_sp, SWIGTYPE_p_lldb__SBValue, 0);
+
+ if (ValObj_PyObj == NULL)
+ return retval;
+
+ if (!python_function_name || !session_dictionary_name)
+ return retval;
+
+ PyObject *pmodule, *main_dict, *session_dict, *pfunc;
+ PyObject *pargs, *pvalue;
+
+ pmodule = PyImport_AddModule ("__main__");
+ if (pmodule != NULL)
+ {
+ main_dict = PyModule_GetDict (pmodule);
+ if (main_dict != NULL)
+ {
+ PyObject *key, *value;
+ Py_ssize_t pos = 0;
+
+ // Find the current session's dictionary in the main module's dictionary.
+
+ if (PyDict_Check (main_dict))
+
+ {
+ session_dict = NULL;
+ while (PyDict_Next (main_dict, &pos, &key, &value))
+ {
+ // We have stolen references to the key and value objects in the dictionary; we need to increment
+ // them now so that Python's garbage collector doesn't collect them out from under us.
+ Py_INCREF (key);
+ Py_INCREF (value);
+ if (strcmp (PyString_AsString (key), session_dictionary_name) == 0)
+ {
+ session_dict = value;
+ break;
+ }
+ }
+ }
+
+ if (!session_dict || !PyDict_Check (session_dict))
+ return retval;
+
+ // Find the function we need to call in the current session's dictionary.
+
+ pos = 0;
+ pfunc = NULL;
+ while (PyDict_Next (session_dict, &pos, &key, &value))
+ {
+ if (PyString_Check (key))
+ {
+ // We have stolen references to the key and value objects in the dictionary; we need to increment
+ // them now so that Python's garbage collector doesn't collect them out from under us.
+ Py_INCREF (key);
+ Py_INCREF (value);
+ if (strcmp (PyString_AsString (key), python_function_name) == 0)
+ {
+ pfunc = value;
+ break;
+ }
+ }
+ }
+
+ // Set up the arguments and call the function.
+
+ if (pfunc && PyCallable_Check (pfunc))
+ {
+ pargs = PyTuple_New (2);
+ if (pargs == NULL)
+ {
+ if (PyErr_Occurred())
+ PyErr_Clear();
+ return retval;
+ }
+
+ PyTuple_SetItem (pargs, 0, ValObj_PyObj); // This "steals" a reference to ValObj_PyObj
+ PyTuple_SetItem (pargs, 1, session_dict); // This "steals" a reference to session_dict
+ pvalue = PyObject_CallObject (pfunc, pargs);
+ Py_DECREF (pargs);
+
+ if (pvalue != NULL)
+ {
+ if (pvalue != Py_None)
+ retval = std::string(PyString_AsString(pvalue));
+ else
+ retval = "None";
+ Py_DECREF (pvalue);
+ }
+ else if (PyErr_Occurred ())
+ {
+ PyErr_Clear();
+ }
+ Py_INCREF (session_dict);
+ }
+ else if (PyErr_Occurred())
+ {
+ PyErr_Clear();
+ }
+ }
+ else if (PyErr_Occurred())
+ {
+ PyErr_Clear();
+ }
+ }
+ else if (PyErr_Occurred ())
+ {
+ PyErr_Clear ();
+ }
+ return retval;
+}
+
+
%}
Modified: lldb/trunk/source/API/SBCommandInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBCommandInterpreter.cpp?rev=135238&r1=135237&r2=135238&view=diff
==============================================================================
--- lldb/trunk/source/API/SBCommandInterpreter.cpp (original)
+++ lldb/trunk/source/API/SBCommandInterpreter.cpp Thu Jul 14 21:26:42 2011
@@ -314,6 +314,15 @@
const lldb::BreakpointLocationSP& sb_bp_loc
);
+extern "C" std::string
+LLDBSwigPythonCallTypeScript
+(
+ const char *python_function_name,
+ const char *session_dictionary_name,
+ const lldb::ValueObjectSP& valobj_sp
+);
+
+
extern "C" void init_lldb(void);
void
@@ -324,6 +333,7 @@
{
g_initialized = true;
ScriptInterpreter::InitializeInterpreter (init_lldb,
- LLDBSwigPythonBreakpointCallbackFunction);
+ LLDBSwigPythonBreakpointCallbackFunction,
+ LLDBSwigPythonCallTypeScript);
}
}
Modified: lldb/trunk/source/API/SBValue.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBValue.cpp?rev=135238&r1=135237&r2=135238&view=diff
==============================================================================
--- lldb/trunk/source/API/SBValue.cpp (original)
+++ lldb/trunk/source/API/SBValue.cpp Thu Jul 14 21:26:42 2011
@@ -472,6 +472,28 @@
return sb_value;
}
+lldb::SBValue
+SBValue::GetValueForExpressionPath(const char* expr_path)
+{
+ lldb::ValueObjectSP child_sp;
+ if (m_opaque_sp)
+ {
+ if (m_opaque_sp->GetUpdatePoint().GetTarget())
+ {
+ Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
+ // using default values for all the fancy options, just do it if you can
+ child_sp = m_opaque_sp->GetValueForExpressionPath(expr_path);
+ }
+ }
+
+ SBValue sb_value (child_sp);
+
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ if (log)
+ log->Printf ("SBValue(%p)::GetValueForExpressionPath (expr_path=\"%s\") => SBValue(%p)", m_opaque_sp.get(), expr_path, sb_value.get());
+
+ return sb_value;
+}
uint32_t
SBValue::GetNumChildren ()
Modified: lldb/trunk/source/Commands/CommandObjectType.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectType.cpp?rev=135238&r1=135237&r2=135238&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectType.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectType.cpp Thu Jul 14 21:26:42 2011
@@ -15,8 +15,10 @@
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/FormatManager.h"
+#include "lldb/Core/InputReaderEZ.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/State.h"
+#include "lldb/Core/StringList.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandObject.h"
#include "lldb/Interpreter/CommandReturnObject.h"
@@ -416,6 +418,162 @@
// CommandObjectTypeSummaryAdd
//-------------------------------------------------------------------------
+class ScriptAddOptions
+{
+
+public:
+
+ bool m_skip_pointers;
+ bool m_skip_references;
+ bool m_cascade;
+ bool m_callback_is_synchronous;
+ StringList m_target_types;
+ StringList m_user_source;
+
+ ScriptAddOptions(bool p,
+ bool r,
+ bool c) :
+ m_skip_pointers(p),
+ m_skip_references(r),
+ m_cascade(c),
+ m_target_types(),
+ m_user_source()
+ {
+ }
+
+ typedef lldb::SharedPtr::Type SharedPointer;
+
+};
+
+static const char *g_reader_instructions = "Enter your Python command(s). Type 'DONE' to end.";
+
+class TypeScriptAddInputReader : public InputReaderEZ
+{
+private:
+ DISALLOW_COPY_AND_ASSIGN (TypeScriptAddInputReader);
+public:
+ TypeScriptAddInputReader(Debugger& debugger) :
+ InputReaderEZ(debugger)
+ {}
+
+ virtual
+ ~TypeScriptAddInputReader()
+ {
+ }
+
+ virtual void ActivateHandler(HandlerData& data)
+ {
+ StreamSP out_stream = data.reader.GetDebugger().GetAsyncOutputStream();
+ bool batch_mode = data.reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
+ if (!batch_mode)
+ {
+ out_stream->Printf ("%s\n", g_reader_instructions);
+ if (data.reader.GetPrompt())
+ out_stream->Printf ("%s", data.reader.GetPrompt());
+ out_stream->Flush();
+ }
+ }
+
+ virtual void ReactivateHandler(HandlerData& data)
+ {
+ StreamSP out_stream = data.reader.GetDebugger().GetAsyncOutputStream();
+ bool batch_mode = data.reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
+ if (data.reader.GetPrompt() && !batch_mode)
+ {
+ out_stream->Printf ("%s", data.reader.GetPrompt());
+ out_stream->Flush();
+ }
+ }
+ virtual void GotTokenHandler(HandlerData& data)
+ {
+ StreamSP out_stream = data.reader.GetDebugger().GetAsyncOutputStream();
+ bool batch_mode = data.reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
+ if (data.bytes && data.bytes_len && data.baton)
+ {
+ ((ScriptAddOptions*)data.baton)->m_user_source.AppendString(data.bytes, data.bytes_len);
+ }
+ if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode)
+ {
+ out_stream->Printf ("%s", data.reader.GetPrompt());
+ out_stream->Flush();
+ }
+ }
+ virtual void InterruptHandler(HandlerData& data)
+ {
+ StreamSP out_stream = data.reader.GetDebugger().GetAsyncOutputStream();
+ bool batch_mode = data.reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
+ data.reader.SetIsDone (true);
+ if (!batch_mode)
+ {
+ out_stream->Printf ("Warning: No command attached to breakpoint.\n");
+ out_stream->Flush();
+ }
+ }
+ virtual void EOFHandler(HandlerData& data)
+ {
+ data.reader.SetIsDone (true);
+ }
+ virtual void DoneHandler(HandlerData& data)
+ {
+ StreamSP out_stream = data.reader.GetDebugger().GetAsyncOutputStream();
+ ScriptAddOptions *options_ptr = ((ScriptAddOptions*)data.baton);
+ if (!options_ptr)
+ {
+ out_stream->Printf ("Internal error #1: no script attached.\n");
+ out_stream->Flush();
+ return;
+ }
+
+ ScriptAddOptions::SharedPointer options(options_ptr); // this will ensure that we get rid of the pointer when going out of scope
+
+ ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
+ if (!interpreter)
+ {
+ out_stream->Printf ("Internal error #2: no script attached.\n");
+ out_stream->Flush();
+ return;
+ }
+ StringList funct_name_sl;
+ if (!interpreter->GenerateTypeScriptFunction (options->m_user_source,
+ funct_name_sl))
+ {
+ out_stream->Printf ("Internal error #3: no script attached.\n");
+ out_stream->Flush();
+ return;
+ }
+ if (funct_name_sl.GetSize() == 0)
+ {
+ out_stream->Printf ("Internal error #4: no script attached.\n");
+ out_stream->Flush();
+ return;
+ }
+ const char *funct_name = funct_name_sl.GetStringAtIndex(0);
+ if (!funct_name || !funct_name[0])
+ {
+ out_stream->Printf ("Internal error #5: no script attached.\n");
+ out_stream->Flush();
+ return;
+ }
+ // now I have a valid function name, let's add this as script for every type in the list
+
+ SummaryFormatSP script_format;
+ script_format.reset(new ScriptSummaryFormat(options->m_cascade,
+ options->m_skip_pointers,
+ options->m_skip_references,
+ true,
+ true,
+ false,
+ std::string(funct_name),
+ options->m_user_source.CopyList(" ")));
+
+ for (int i = 0; i < options->m_target_types.GetSize(); i++)
+ {
+ const char *type_name = options->m_target_types.GetStringAtIndex(i);
+ Debugger::SummaryFormats::Add(ConstString(type_name), script_format);
+ }
+ }
+};
+
class CommandObjectTypeSummaryAdd : public CommandObject
{
@@ -471,6 +629,17 @@
case 'n':
m_name = new ConstString(option_arg);
break;
+ case 's':
+ m_python_script = std::string(option_arg);
+ m_is_add_script = true;
+ break;
+ case 'F':
+ m_python_function = std::string(option_arg);
+ m_is_add_script = true;
+ break;
+ case 'P':
+ m_is_add_script = true;
+ break;
default:
error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
break;
@@ -490,6 +659,9 @@
m_skip_pointers = false;
m_regex = false;
m_name = NULL;
+ m_python_script = "";
+ m_python_function = "";
+ m_is_add_script = false;
}
const OptionDefinition*
@@ -513,6 +685,9 @@
bool m_regex;
std::string m_format_string;
ConstString* m_name;
+ std::string m_python_script;
+ std::string m_python_function;
+ bool m_is_add_script;
};
CommandOptions m_options;
@@ -601,9 +776,170 @@
{
}
+ void
+ CollectPythonScript
+ (
+ ScriptAddOptions *options,
+ CommandReturnObject &result
+ )
+ {
+ InputReaderSP reader_sp (new TypeScriptAddInputReader(m_interpreter.GetDebugger()));
+ if (reader_sp && options)
+ {
+
+ Error err (reader_sp->Initialize (options));
+ if (err.Success())
+ {
+ m_interpreter.GetDebugger().PushInputReader (reader_sp);
+ result.SetStatus (eReturnStatusSuccessFinishNoResult);
+ }
+ else
+ {
+ result.AppendError (err.AsCString());
+ result.SetStatus (eReturnStatusFailed);
+ }
+ }
+ else
+ {
+ result.AppendError("out of memory");
+ result.SetStatus (eReturnStatusFailed);
+ }
+
+ }
+
bool
Execute (Args& command, CommandReturnObject &result)
{
+ if (m_options.m_is_add_script)
+ return Execute_ScriptSummary(command, result);
+ else
+ return Execute_StringSummary(command, result);
+ }
+
+ bool
+ Execute_ScriptSummary (Args& command, CommandReturnObject &result)
+ {
+ const size_t argc = command.GetArgumentCount();
+
+ if (argc < 1)
+ {
+ result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ if (!m_options.m_python_function.empty()) // we have a Python function ready to use
+ {
+ ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
+ if (!interpreter)
+ {
+ result.AppendError ("Internal error #1N: no script attached.\n");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ const char *funct_name = m_options.m_python_function.c_str();
+ if (!funct_name || !funct_name[0])
+ {
+ result.AppendError ("Internal error #2N: no script attached.\n");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ // now I have a valid function name, let's add this as script for every type in the list
+
+ SummaryFormatSP script_format;
+ script_format.reset(new ScriptSummaryFormat(m_options.m_cascade,
+ m_options.m_skip_pointers,
+ m_options.m_skip_references,
+ true,
+ true,
+ false,
+ std::string(funct_name),
+ " " + m_options.m_python_function + "(valobj,dict)"));
+
+ for (int i = 0; i < command.GetArgumentCount(); i++)
+ {
+ const char *type_name = command.GetArgumentAtIndex(i);
+ Debugger::SummaryFormats::Add(ConstString(type_name), script_format);
+ }
+ }
+ else if (m_options.m_python_script.empty()) // use an InputReader to grab Python code from the user
+ {
+ ScriptAddOptions *options = new ScriptAddOptions(m_options.m_skip_pointers,
+ m_options.m_skip_references,
+ m_options.m_cascade);
+
+ for(int i = 0; i < argc; i++) {
+ const char* typeA = command.GetArgumentAtIndex(i);
+ if (typeA && *typeA)
+ options->m_target_types << typeA;
+ else
+ {
+ result.AppendError("empty typenames not allowed");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+
+ CollectPythonScript(options,result);
+ return result.Succeeded();
+ }
+ else // we have a quick 1-line script, just use it
+ {
+ ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
+ if (!interpreter)
+ {
+ result.AppendError ("Internal error #1Q: no script attached.\n");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ StringList funct_sl;
+ funct_sl << m_options.m_python_script.c_str();
+ StringList funct_name_sl;
+ if (!interpreter->GenerateTypeScriptFunction (funct_sl,
+ funct_name_sl))
+ {
+ result.AppendError ("Internal error #2Q: no script attached.\n");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ if (funct_name_sl.GetSize() == 0)
+ {
+ result.AppendError ("Internal error #3Q: no script attached.\n");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ const char *funct_name = funct_name_sl.GetStringAtIndex(0);
+ if (!funct_name || !funct_name[0])
+ {
+ result.AppendError ("Internal error #4Q: no script attached.\n");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ // now I have a valid function name, let's add this as script for every type in the list
+
+ ScriptFormatSP script_format;
+ script_format.reset(new ScriptSummaryFormat(m_options.m_cascade,
+ m_options.m_skip_pointers,
+ m_options.m_skip_references,
+ true,
+ true,
+ false,
+ std::string(funct_name),
+ " " + m_options.m_python_script));
+
+ for (int i = 0; i < command.GetArgumentCount(); i++)
+ {
+ const char *type_name = command.GetArgumentAtIndex(i);
+ Debugger::SummaryFormats::Add(ConstString(type_name), script_format);
+ }
+ }
+
+ return result.Succeeded();
+ }
+
+ bool
+ Execute_StringSummary (Args& command, CommandReturnObject &result)
+ {
const size_t argc = command.GetArgumentCount();
if (argc < 1 && !m_options.m_name)
@@ -624,11 +960,13 @@
Error error;
- SummaryFormat::SharedPointer entry(new SummaryFormat(format_cstr,m_options.m_cascade,
- m_options.m_no_children,m_options.m_no_value,
- m_options.m_one_liner,
- m_options.m_skip_pointers,
- m_options.m_skip_references));
+ SummaryFormat::SharedPointer entry(new StringSummaryFormat(m_options.m_cascade,
+ m_options.m_skip_pointers,
+ m_options.m_skip_references,
+ m_options.m_no_children,
+ m_options.m_no_value,
+ m_options.m_one_liner,
+ format_cstr));
if (error.Fail())
{
@@ -698,6 +1036,9 @@
{ LLDB_OPT_SET_2 , true, "format-string", 'f', required_argument, NULL, 0, eArgTypeSummaryString, "Format string used to display text and object contents."},
{ LLDB_OPT_SET_2, false, "expand", 'e', no_argument, NULL, 0, eArgTypeBoolean, "Expand aggregate data types to show children on separate lines."},
{ LLDB_OPT_SET_2, false, "name", 'n', required_argument, NULL, 0, eArgTypeName, "A name for this summary string."},
+ { LLDB_OPT_SET_3, false, "python-script", 's', required_argument, NULL, 0, eArgTypeName, "Give a one-liner Python script as part of the command."},
+ { LLDB_OPT_SET_3, false, "python-function", 'F', required_argument, NULL, 0, eArgTypeName, "Give the name of a Python function to use for this type."},
+ { LLDB_OPT_SET_3, false, "input-python", 'P', no_argument, NULL, 0, eArgTypeName, "Input Python code to use for this type manually."},
{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
};
@@ -808,8 +1149,8 @@
// CommandObjectTypeSummaryList
//-------------------------------------------------------------------------
-bool CommandObjectTypeSummaryList_LoopCallback(void* pt2self, const char* type, const SummaryFormat::SharedPointer& entry);
-bool CommandObjectTypeRXSummaryList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SummaryFormat::SharedPointer& entry);
+bool CommandObjectTypeSummaryList_LoopCallback(void* pt2self, const char* type, const StringSummaryFormat::SharedPointer& entry);
+bool CommandObjectTypeRXSummaryList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const StringSummaryFormat::SharedPointer& entry);
class CommandObjectTypeSummaryList;
@@ -912,16 +1253,7 @@
CommandReturnObject *result)
{
if (regex == NULL || regex->Execute(type))
- {
- result->GetOutputStream().Printf ("%s: `%s`%s%s%s%s%s%s\n", type,
- entry->m_format.c_str(),
- entry->m_cascades ? "" : " (not cascading)",
- entry->m_dont_show_children ? "" : " (show children)",
- entry->m_dont_show_value ? " (hide value)" : "",
- entry->m_show_members_oneliner ? " (one-line printout)" : "",
- entry->m_skip_pointers ? " (skip pointers)" : "",
- entry->m_skip_references ? " (skip references)" : "");
- }
+ result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str());
return true;
}
@@ -951,8 +1283,6 @@
}
-
-
class CommandObjectTypeFormat : public CommandObjectMultiword
{
public:
@@ -983,10 +1313,10 @@
"A set of commands for editing variable summary display options",
"type summary [] ")
{
- LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeSummaryAdd (interpreter)));
- LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeSummaryClear (interpreter)));
- LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeSummaryDelete (interpreter)));
- LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeSummaryList (interpreter)));
+ LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeSummaryAdd (interpreter)));
+ LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeSummaryClear (interpreter)));
+ LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeSummaryDelete (interpreter)));
+ LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeSummaryList (interpreter)));
}
Modified: lldb/trunk/source/Core/Debugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=135238&r1=135237&r2=135238&view=diff
==============================================================================
--- lldb/trunk/source/Core/Debugger.cpp (original)
+++ lldb/trunk/source/Core/Debugger.cpp Thu Jul 14 21:26:42 2011
@@ -733,6 +733,8 @@
// if this is a V, print the value using the default format
if (*format_name == 'V')
*val_obj_display = ValueObject::eDisplayValue;
+ if (*format_name == 'L')
+ *val_obj_display = ValueObject::eDisplayLocation;
}
// a good custom format tells us to print the value using it
else
Modified: lldb/trunk/source/Core/Error.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Error.cpp?rev=135238&r1=135237&r2=135238&view=diff
==============================================================================
--- lldb/trunk/source/Core/Error.cpp (original)
+++ lldb/trunk/source/Core/Error.cpp Thu Jul 14 21:26:42 2011
@@ -51,6 +51,14 @@
{
}
+Error::Error (const char* err_str):
+ m_code (0),
+ m_type (eErrorTypeInvalid),
+ m_string ()
+{
+ SetErrorString(err_str);
+}
+
//----------------------------------------------------------------------
// Assignment operator
//----------------------------------------------------------------------
Modified: lldb/trunk/source/Core/FormatManager.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/FormatManager.cpp?rev=135238&r1=135237&r2=135238&view=diff
==============================================================================
--- lldb/trunk/source/Core/FormatManager.cpp (original)
+++ lldb/trunk/source/Core/FormatManager.cpp Thu Jul 14 21:26:42 2011
@@ -14,6 +14,8 @@
// Other libraries and framework includes
// Project includes
+#include "lldb/Core/Debugger.h"
+
using namespace lldb;
using namespace lldb_private;
@@ -217,3 +219,54 @@
return lldb::eFormatInvalid;
}
}
+
+std::string
+StringSummaryFormat::FormatObject(lldb::ValueObjectSP object)
+{
+ if (!object.get())
+ return "NULL";
+
+ StreamString s;
+ ExecutionContext exe_ctx;
+ object->GetExecutionContextScope()->CalculateExecutionContext(exe_ctx);
+ SymbolContext sc;
+ if (exe_ctx.frame)
+ sc = exe_ctx.frame->GetSymbolContext(lldb::eSymbolContextEverything);
+
+ if (m_show_members_oneliner)
+ {
+ const uint32_t num_children = object->GetNumChildren();
+ if (num_children)
+ {
+ s.PutChar('(');
+
+ for (uint32_t idx=0; idxGetChildAtIndex(idx, true));
+ if (child_sp.get())
+ {
+ if (idx)
+ s.PutCString(", ");
+ s.PutCString(child_sp.get()->GetName().AsCString());
+ s.PutChar('=');
+ s.PutCString(child_sp.get()->GetPrintableRepresentation());
+ }
+ }
+
+ s.PutChar(')');
+
+ return s.GetString();
+ }
+ else
+ return "";
+
+ }
+ else
+ {
+ if (Debugger::FormatPrompt(m_format.c_str(), &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, NULL, object.get()))
+ return s.GetString();
+ else
+ return "";
+ }
+}
+
Modified: lldb/trunk/source/Core/InputReader.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/InputReader.cpp?rev=135238&r1=135237&r2=135238&view=diff
==============================================================================
--- lldb/trunk/source/Core/InputReader.cpp (original)
+++ lldb/trunk/source/Core/InputReader.cpp Thu Jul 14 21:26:42 2011
@@ -370,3 +370,14 @@
return unknown_state_string;
}
+bool
+InputReader::HandlerData::GetBatchMode()
+{
+ return reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
+}
+
+lldb::StreamSP
+InputReader::HandlerData::GetOutStream()
+{
+ return reader.GetDebugger().GetAsyncOutputStream();
+}
\ No newline at end of file
Added: lldb/trunk/source/Core/InputReaderEZ.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/InputReaderEZ.cpp?rev=135238&view=auto
==============================================================================
--- lldb/trunk/source/Core/InputReaderEZ.cpp (added)
+++ lldb/trunk/source/Core/InputReaderEZ.cpp Thu Jul 14 21:26:42 2011
@@ -0,0 +1,80 @@
+//===-- InputReaderEZ.cpp ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include
+
+#include "lldb/Core/InputReaderEZ.h"
+
+#include "lldb/Core/Debugger.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+size_t
+InputReaderEZ::Callback_Impl(void *baton,
+ InputReader &reader,
+ lldb::InputReaderAction notification,
+ const char *bytes,
+ size_t bytes_len)
+
+{
+ HandlerData hand_data(reader,
+ bytes,
+ bytes_len,
+ baton);
+
+ switch (notification)
+ {
+ case eInputReaderActivate:
+ reader.ActivateHandler(hand_data);
+ break;
+ case eInputReaderDeactivate:
+ reader.DeactivateHandler(hand_data);
+ break;
+ case eInputReaderReactivate:
+ reader.ReactivateHandler(hand_data);
+ break;
+ case eInputReaderAsynchronousOutputWritten:
+ reader.AsynchronousOutputWrittenHandler(hand_data);
+ break;
+ case eInputReaderGotToken:
+ reader.GotTokenHandler(hand_data);
+ break;
+ case eInputReaderInterrupt:
+ reader.InterruptHandler(hand_data);
+ break;
+ case eInputReaderEndOfFile:
+ reader.EOFHandler(hand_data);
+ break;
+ case eInputReaderDone:
+ reader.DoneHandler(hand_data);
+ break;
+ }
+ return bytes_len;
+}
+
+Error
+InputReaderEZ::Initialize(void* baton,
+ lldb::InputReaderGranularity token_size,
+ const char* end_token,
+ const char *prompt,
+ bool echo)
+{
+ return InputReader::Initialize(Callback_Impl,
+ baton,
+ token_size,
+ end_token,
+ prompt,
+ echo);
+}
+
+InputReaderEZ::~InputReaderEZ ()
+{
+}
\ No newline at end of file
Modified: lldb/trunk/source/Core/StringList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/StringList.cpp?rev=135238&r1=135237&r2=135238&view=diff
==============================================================================
--- lldb/trunk/source/Core/StringList.cpp (original)
+++ lldb/trunk/source/Core/StringList.cpp Thu Jul 14 21:26:42 2011
@@ -8,6 +8,8 @@
//===----------------------------------------------------------------------===//
#include "lldb/Core/StringList.h"
+
+#include "lldb/Core/StreamString.h"
#include "lldb/Host/FileSpec.h"
#include
@@ -205,3 +207,33 @@
idx++;
}
}
+
+std::string
+StringList::CopyList(const char* item_preamble,
+ const char* items_sep)
+{
+ StreamString strm;
+ for (int i = 0; i < GetSize(); i++)
+ {
+ if (i && items_sep && items_sep[0])
+ strm << items_sep;
+ if (item_preamble)
+ strm << item_preamble;
+ strm << GetStringAtIndex(i);
+ }
+ return std::string(strm.GetData());
+}
+
+StringList&
+StringList::operator << (const char* str)
+{
+ AppendString(str);
+ return *this;
+}
+
+StringList&
+StringList::operator << (StringList strings)
+{
+ AppendList(strings);
+ return *this;
+}
\ No newline at end of file
Modified: lldb/trunk/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=135238&r1=135237&r2=135238&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObject.cpp (original)
+++ lldb/trunk/source/Core/ValueObject.cpp Thu Jul 14 21:26:42 2011
@@ -29,6 +29,8 @@
#include "lldb/Host/Endian.h"
+#include "lldb/Interpreter/ScriptInterpreterPython.h"
+
#include "lldb/Symbol/ClangASTType.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/Type.h"
@@ -79,8 +81,8 @@
m_is_array_item_for_pointer(false),
m_is_bitfield_for_scalar(false),
m_last_format_mgr_revision(0),
- m_last_summary_format(),
m_last_value_format(),
+ m_last_summary_format(),
m_forced_summary_format(),
m_dump_printable_counter(0)
{
@@ -118,8 +120,8 @@
m_is_array_item_for_pointer(false),
m_is_bitfield_for_scalar(false),
m_last_format_mgr_revision(0),
- m_last_summary_format(),
m_last_value_format(),
+ m_last_summary_format(),
m_forced_summary_format(),
m_dump_printable_counter(0)
{
@@ -164,10 +166,9 @@
m_old_value_str.swap (m_value_str);
m_value_str.clear();
}
- m_location_str.clear();
- m_summary_str.clear();
- m_object_desc_str.clear();
+ ClearUserVisibleData();
+
const bool value_was_valid = GetValueIsValid();
SetValueDidChange (false);
@@ -204,15 +205,15 @@
if (m_last_format_mgr_revision != Debugger::ValueFormats::GetCurrentRevision())
{
if (m_last_summary_format.get())
- m_last_summary_format.reset((SummaryFormat*)NULL);
+ m_last_summary_format.reset((StringSummaryFormat*)NULL);
if (m_last_value_format.get())
m_last_value_format.reset((ValueFormat*)NULL);
Debugger::ValueFormats::Get(*this, m_last_value_format);
if (!Debugger::SummaryFormats::Get(*this, m_last_summary_format))
Debugger::RegexSummaryFormats::Get(*this, m_last_summary_format);
m_last_format_mgr_revision = Debugger::ValueFormats::GetCurrentRevision();
- m_value_str.clear();
- m_summary_str.clear();
+
+ ClearUserVisibleData();
}
}
@@ -507,221 +508,177 @@
{
if (m_summary_str.empty())
{
- SummaryFormat* summary_format = GetSummaryFormat().get();
+ SummaryFormat *summary_format = GetSummaryFormat().get();
if (summary_format)
{
- StreamString s;
- ExecutionContext exe_ctx;
- this->GetExecutionContextScope()->CalculateExecutionContext(exe_ctx);
- SymbolContext sc;
- if (exe_ctx.frame)
- sc = exe_ctx.frame->GetSymbolContext(eSymbolContextEverything);
-
- if (summary_format->m_show_members_oneliner)
- {
- const uint32_t num_children = GetNumChildren();
- if (num_children)
- {
-
- s.PutChar('(');
-
- for (uint32_t idx=0; idxGetName().AsCString());
- s.PutChar('=');
- s.PutCString(child_sp.get()->GetPrintableRepresentation());
- }
- }
-
- s.PutChar(')');
-
- m_summary_str.swap(s.GetString());
- return m_summary_str.c_str();
- }
- else
- return "()";
-
- }
- else
- {
- if (Debugger::FormatPrompt(summary_format->m_format.c_str(), &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, NULL, this))
- {
- m_summary_str.swap(s.GetString());
- return m_summary_str.c_str();
- }
- else
- return NULL;
- }
+ m_summary_str = summary_format->FormatObject(GetSP());
}
-
- clang_type_t clang_type = GetClangType();
-
- // See if this is a pointer to a C string?
- if (clang_type)
+ else
{
- StreamString sstr;
- clang_type_t elem_or_pointee_clang_type;
- const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type,
- GetClangAST(),
- &elem_or_pointee_clang_type));
+ clang_type_t clang_type = GetClangType();
- ExecutionContextScope *exe_scope = GetExecutionContextScope();
- if (exe_scope)
+ // See if this is a pointer to a C string?
+ if (clang_type)
{
- if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
- ClangASTContext::IsCharType (elem_or_pointee_clang_type))
+ StreamString sstr;
+ clang_type_t elem_or_pointee_clang_type;
+ const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type,
+ GetClangAST(),
+ &elem_or_pointee_clang_type));
+
+ ExecutionContextScope *exe_scope = GetExecutionContextScope();
+ if (exe_scope)
{
- Target *target = exe_scope->CalculateTarget();
- if (target != NULL)
+ if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
+ ClangASTContext::IsCharType (elem_or_pointee_clang_type))
{
- lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
- AddressType cstr_address_type = eAddressTypeInvalid;
-
- size_t cstr_len = 0;
- bool capped_data = false;
- if (type_flags.Test (ClangASTContext::eTypeIsArray))
+ Target *target = exe_scope->CalculateTarget();
+ if (target != NULL)
{
- // We have an array
- cstr_len = ClangASTContext::GetArraySize (clang_type);
- if (cstr_len > 512) // TODO: make cap a setting
+ lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
+ AddressType cstr_address_type = eAddressTypeInvalid;
+
+ size_t cstr_len = 0;
+ bool capped_data = false;
+ if (type_flags.Test (ClangASTContext::eTypeIsArray))
{
+ // We have an array
cstr_len = ClangASTContext::GetArraySize (clang_type);
if (cstr_len > 512) // TODO: make cap a setting
{
- capped_data = true;
- cstr_len = 512;
+ cstr_len = ClangASTContext::GetArraySize (clang_type);
+ if (cstr_len > 512) // TODO: make cap a setting
+ {
+ capped_data = true;
+ cstr_len = 512;
+ }
}
+ cstr_address = GetAddressOf (cstr_address_type, true);
}
- cstr_address = GetAddressOf (cstr_address_type, true);
- }
- else
- {
- // We have a pointer
- cstr_address = GetPointerValue (cstr_address_type, true);
- }
- if (cstr_address != LLDB_INVALID_ADDRESS)
- {
- Address cstr_so_addr (NULL, cstr_address);
- DataExtractor data;
- size_t bytes_read = 0;
- std::vector data_buffer;
- Error error;
- bool prefer_file_cache = false;
- if (cstr_len > 0)
+ else
{
- data_buffer.resize(cstr_len);
- data.SetData (&data_buffer.front(), data_buffer.size(), lldb::endian::InlHostByteOrder());
- bytes_read = target->ReadMemory (cstr_so_addr,
- prefer_file_cache,
- &data_buffer.front(),
- cstr_len,
- error);
- if (bytes_read > 0)
- {
- sstr << '"';
- data.Dump (&sstr,
- 0, // Start offset in "data"
- eFormatCharArray, // Print as characters
- 1, // Size of item (1 byte for a char!)
- bytes_read, // How many bytes to print?
- UINT32_MAX, // num per line
- LLDB_INVALID_ADDRESS,// base address
- 0, // bitfield bit size
- 0); // bitfield bit offset
- if (capped_data)
- sstr << "...";
- sstr << '"';
- }
+ // We have a pointer
+ cstr_address = GetPointerValue (cstr_address_type, true);
}
- else
+ if (cstr_address != LLDB_INVALID_ADDRESS)
{
- const size_t k_max_buf_size = 256;
- data_buffer.resize (k_max_buf_size + 1);
- // NULL terminate in case we don't get the entire C string
- data_buffer.back() = '\0';
-
- sstr << '"';
-
- data.SetData (&data_buffer.front(), data_buffer.size(), endian::InlHostByteOrder());
- while ((bytes_read = target->ReadMemory (cstr_so_addr,
- prefer_file_cache,
- &data_buffer.front(),
- k_max_buf_size,
- error)) > 0)
+ Address cstr_so_addr (NULL, cstr_address);
+ DataExtractor data;
+ size_t bytes_read = 0;
+ std::vector data_buffer;
+ Error error;
+ bool prefer_file_cache = false;
+ if (cstr_len > 0)
{
- size_t len = strlen(&data_buffer.front());
- if (len == 0)
- break;
- if (len > bytes_read)
- len = bytes_read;
-
- data.Dump (&sstr,
- 0, // Start offset in "data"
- eFormatCharArray, // Print as characters
- 1, // Size of item (1 byte for a char!)
- len, // How many bytes to print?
- UINT32_MAX, // num per line
- LLDB_INVALID_ADDRESS,// base address
- 0, // bitfield bit size
- 0); // bitfield bit offset
-
- if (len < k_max_buf_size)
- break;
- cstr_so_addr.Slide (k_max_buf_size);
+ data_buffer.resize(cstr_len);
+ data.SetData (&data_buffer.front(), data_buffer.size(), lldb::endian::InlHostByteOrder());
+ bytes_read = target->ReadMemory (cstr_so_addr,
+ prefer_file_cache,
+ &data_buffer.front(),
+ cstr_len,
+ error);
+ if (bytes_read > 0)
+ {
+ sstr << '"';
+ data.Dump (&sstr,
+ 0, // Start offset in "data"
+ eFormatCharArray, // Print as characters
+ 1, // Size of item (1 byte for a char!)
+ bytes_read, // How many bytes to print?
+ UINT32_MAX, // num per line
+ LLDB_INVALID_ADDRESS,// base address
+ 0, // bitfield bit size
+ 0); // bitfield bit offset
+ if (capped_data)
+ sstr << "...";
+ sstr << '"';
+ }
+ }
+ else
+ {
+ const size_t k_max_buf_size = 256;
+ data_buffer.resize (k_max_buf_size + 1);
+ // NULL terminate in case we don't get the entire C string
+ data_buffer.back() = '\0';
+
+ sstr << '"';
+
+ data.SetData (&data_buffer.front(), data_buffer.size(), endian::InlHostByteOrder());
+ while ((bytes_read = target->ReadMemory (cstr_so_addr,
+ prefer_file_cache,
+ &data_buffer.front(),
+ k_max_buf_size,
+ error)) > 0)
+ {
+ size_t len = strlen(&data_buffer.front());
+ if (len == 0)
+ break;
+ if (len > bytes_read)
+ len = bytes_read;
+
+ data.Dump (&sstr,
+ 0, // Start offset in "data"
+ eFormatCharArray, // Print as characters
+ 1, // Size of item (1 byte for a char!)
+ len, // How many bytes to print?
+ UINT32_MAX, // num per line
+ LLDB_INVALID_ADDRESS,// base address
+ 0, // bitfield bit size
+ 0); // bitfield bit offset
+
+ if (len < k_max_buf_size)
+ break;
+ cstr_so_addr.Slide (k_max_buf_size);
+ }
+ sstr << '"';
}
- sstr << '"';
}
}
+
+ if (sstr.GetSize() > 0)
+ m_summary_str.assign (sstr.GetData(), sstr.GetSize());
}
-
- if (sstr.GetSize() > 0)
- m_summary_str.assign (sstr.GetData(), sstr.GetSize());
- }
- else if (ClangASTContext::IsFunctionPointerType (clang_type))
- {
- AddressType func_ptr_address_type = eAddressTypeInvalid;
- lldb::addr_t func_ptr_address = GetPointerValue (func_ptr_address_type, true);
-
- if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS)
+ else if (ClangASTContext::IsFunctionPointerType (clang_type))
{
- switch (func_ptr_address_type)
- {
- case eAddressTypeInvalid:
- case eAddressTypeFile:
- break;
+ AddressType func_ptr_address_type = eAddressTypeInvalid;
+ lldb::addr_t func_ptr_address = GetPointerValue (func_ptr_address_type, true);
- case eAddressTypeLoad:
+ if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS)
+ {
+ switch (func_ptr_address_type)
{
- Address so_addr;
- Target *target = exe_scope->CalculateTarget();
- if (target && target->GetSectionLoadList().IsEmpty() == false)
+ case eAddressTypeInvalid:
+ case eAddressTypeFile:
+ break;
+
+ case eAddressTypeLoad:
{
- if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr))
+ Address so_addr;
+ Target *target = exe_scope->CalculateTarget();
+ if (target && target->GetSectionLoadList().IsEmpty() == false)
{
- so_addr.Dump (&sstr,
- exe_scope,
- Address::DumpStyleResolvedDescription,
- Address::DumpStyleSectionNameOffset);
+ if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr))
+ {
+ so_addr.Dump (&sstr,
+ exe_scope,
+ Address::DumpStyleResolvedDescription,
+ Address::DumpStyleSectionNameOffset);
+ }
}
}
- }
- break;
+ break;
- case eAddressTypeHost:
- break;
+ case eAddressTypeHost:
+ break;
+ }
+ }
+ if (sstr.GetSize() > 0)
+ {
+ m_summary_str.assign (1, '(');
+ m_summary_str.append (sstr.GetData(), sstr.GetSize());
+ m_summary_str.append (1, ')');
}
- }
- if (sstr.GetSize() > 0)
- {
- m_summary_str.assign (1, '(');
- m_summary_str.append (sstr.GetData(), sstr.GetSize());
- m_summary_str.append (1, ')');
}
}
}
@@ -960,34 +917,35 @@
clang_type_t clang_type = GetClangType ();
if (clang_type)
{
- StreamString sstr;
- Format format = GetFormat();
- if (format == eFormatDefault)
+ if (m_last_value_format)
{
- if (m_last_value_format)
- format = m_last_value_format->m_format;
- else
- // force the system into using unsigned integers for bitfields
- format = (m_is_bitfield_for_scalar ? eFormatUnsigned :
- ClangASTType::GetFormat(clang_type));
+ m_value_str = m_last_value_format->FormatObject(GetSP());
}
-
- if (ClangASTType::DumpTypeValue (GetClangAST(), // The clang AST
- clang_type, // The clang type to display
- &sstr,
- format, // Format to display this type with
- m_data, // Data to extract from
- 0, // Byte offset into "m_data"
- GetByteSize(), // Byte size of item in "m_data"
- GetBitfieldBitSize(), // Bitfield bit size
- GetBitfieldBitOffset())) // Bitfield bit offset
- m_value_str.swap(sstr.GetString());
else
{
- m_error.SetErrorStringWithFormat ("unsufficient data for value (only %u of %u bytes available)",
- m_data.GetByteSize(),
- GetByteSize());
- m_value_str.clear();
+ StreamString sstr;
+ Format format = GetFormat();
+ if (format == eFormatDefault)
+ format = (m_is_bitfield_for_scalar ? eFormatUnsigned :
+ ClangASTType::GetFormat(clang_type));
+
+ if (ClangASTType::DumpTypeValue (GetClangAST(), // The clang AST
+ clang_type, // The clang type to display
+ &sstr,
+ format, // Format to display this type with
+ m_data, // Data to extract from
+ 0, // Byte offset into "m_data"
+ GetByteSize(), // Byte size of item in "m_data"
+ GetBitfieldBitSize(), // Bitfield bit size
+ GetBitfieldBitOffset())) // Bitfield bit offset
+ m_value_str.swap(sstr.GetString());
+ else
+ {
+ m_error.SetErrorStringWithFormat ("unsufficient data for value (only %u of %u bytes available)",
+ m_data.GetByteSize(),
+ GetByteSize());
+ m_value_str.clear();
+ }
}
}
}
@@ -1046,6 +1004,9 @@
case eDisplayLanguageSpecific:
return_value = GetObjectDescription();
break;
+ case eDisplayLocation:
+ return_value = GetLocationAsCString();
+ break;
}
// this code snippet might lead to endless recursion, thus we use a RefCounter here to
@@ -3221,3 +3182,12 @@
return needs_update;
}
+
+void
+ValueObject::ClearUserVisibleData()
+{
+ m_location_str.clear();
+ m_value_str.clear();
+ m_summary_str.clear();
+ m_object_desc_str.clear();
+}
\ No newline at end of file
Modified: lldb/trunk/source/Interpreter/ScriptInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreter.cpp?rev=135238&r1=135237&r2=135238&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/ScriptInterpreter.cpp (original)
+++ lldb/trunk/source/Interpreter/ScriptInterpreter.cpp Thu Jul 14 21:26:42 2011
@@ -92,10 +92,12 @@
void
ScriptInterpreter::InitializeInterpreter (SWIGInitCallback python_swig_init_callback,
- SWIGBreakpointCallbackFunction python_swig_breakpoint_callback)
+ SWIGBreakpointCallbackFunction python_swig_breakpoint_callback,
+ SWIGPythonTypeScriptCallbackFunction python_swig_typescript_callback)
{
ScriptInterpreterPython::InitializeInterpreter (python_swig_init_callback,
- python_swig_breakpoint_callback);
+ python_swig_breakpoint_callback,
+ python_swig_typescript_callback);
}
void
Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp?rev=135238&r1=135237&r2=135238&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp (original)
+++ lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Thu Jul 14 21:26:42 2011
@@ -34,6 +34,7 @@
static ScriptInterpreter::SWIGInitCallback g_swig_init_callback = NULL;
static ScriptInterpreter::SWIGBreakpointCallbackFunction g_swig_breakpoint_callback = NULL;
+static ScriptInterpreter::SWIGPythonTypeScriptCallbackFunction g_swig_typescript_callback = NULL;
static int
@@ -1140,6 +1141,117 @@
return ExecuteMultipleLines (function_def_string.c_str());
}
+// TODO move both GenerateTypeScriptFunction and GenerateBreakpointCommandCallbackData to actually
+// use this code to generate their functions
+bool
+ScriptInterpreterPython::GenerateFunction(std::string& signature, StringList &input, StringList &output)
+{
+ int num_lines = input.GetSize ();
+ if (num_lines == 0)
+ return false;
+ StreamString sstr;
+ StringList auto_generated_function;
+ auto_generated_function.AppendString (signature.c_str());
+ auto_generated_function.AppendString (" global_dict = globals()"); // Grab the global dictionary
+ auto_generated_function.AppendString (" new_keys = dict.keys()"); // Make a list of keys in the session dict
+ auto_generated_function.AppendString (" old_keys = global_dict.keys()"); // Save list of keys in global dict
+ auto_generated_function.AppendString (" global_dict.update (dict)"); // Add the session dictionary to the
+ // global dictionary.
+
+ // Wrap everything up inside the function, increasing the indentation.
+
+ for (int i = 0; i < num_lines; ++i)
+ {
+ sstr.Clear ();
+ sstr.Printf (" %s", input.GetStringAtIndex (i));
+ auto_generated_function.AppendString (sstr.GetData());
+ }
+ auto_generated_function.AppendString (" for key in new_keys:"); // Iterate over all the keys from session dict
+ auto_generated_function.AppendString (" dict[key] = global_dict[key]"); // Update session dict values
+ auto_generated_function.AppendString (" if key not in old_keys:"); // If key was not originally in global dict
+ auto_generated_function.AppendString (" del global_dict[key]"); // ...then remove key/value from global dict
+
+ // Verify that the results are valid Python.
+
+ if (!ExportFunctionDefinitionToInterpreter (auto_generated_function))
+ return false;
+
+ return true;
+
+}
+
+// this implementation is identical to GenerateBreakpointCommandCallbackData (apart from the name
+// given to generated functions, of course)
+bool
+ScriptInterpreterPython::GenerateTypeScriptFunction (StringList &user_input, StringList &output)
+{
+ static int num_created_functions = 0;
+ user_input.RemoveBlankLines ();
+ int num_lines = user_input.GetSize ();
+ StreamString sstr;
+
+ // Check to see if we have any data; if not, just return.
+ if (user_input.GetSize() == 0)
+ return false;
+
+ // Take what the user wrote, wrap it all up inside one big auto-generated Python function, passing in the
+ // ValueObject as parameter to the function.
+
+ sstr.Printf ("lldb_autogen_python_type_print_func_%d", num_created_functions);
+ ++num_created_functions;
+ std::string auto_generated_function_name = sstr.GetData();
+
+ sstr.Clear();
+ StringList auto_generated_function;
+
+ // Create the function name & definition string.
+
+ sstr.Printf ("def %s (valobj, dict):", auto_generated_function_name.c_str());
+ auto_generated_function.AppendString (sstr.GetData());
+
+ // Pre-pend code for setting up the session dictionary.
+
+ auto_generated_function.AppendString (" global_dict = globals()"); // Grab the global dictionary
+ auto_generated_function.AppendString (" new_keys = dict.keys()"); // Make a list of keys in the session dict
+ auto_generated_function.AppendString (" old_keys = global_dict.keys()"); // Save list of keys in global dict
+ auto_generated_function.AppendString (" global_dict.update (dict)"); // Add the session dictionary to the
+ // global dictionary.
+
+ // Wrap everything up inside the function, increasing the indentation.
+
+ for (int i = 0; i < num_lines; ++i)
+ {
+ sstr.Clear ();
+ sstr.Printf (" %s", user_input.GetStringAtIndex (i));
+ auto_generated_function.AppendString (sstr.GetData());
+ }
+
+ // Append code to clean up the global dictionary and update the session dictionary (all updates in the function
+ // got written to the values in the global dictionary, not the session dictionary).
+
+ auto_generated_function.AppendString (" for key in new_keys:"); // Iterate over all the keys from session dict
+ auto_generated_function.AppendString (" dict[key] = global_dict[key]"); // Update session dict values
+ auto_generated_function.AppendString (" if key not in old_keys:"); // If key was not originally in global dict
+ auto_generated_function.AppendString (" del global_dict[key]"); // ...then remove key/value from global dict
+
+ // Verify that the results are valid Python.
+
+ if (!ExportFunctionDefinitionToInterpreter (auto_generated_function))
+ return false;
+
+ // Store the name of the auto-generated function to be called.
+
+ output.AppendString (auto_generated_function_name.c_str());
+ return true;
+}
+
+bool
+ScriptInterpreterPython::GenerateTypeScriptFunction (const char* oneliner, StringList &output)
+{
+ StringList input(oneliner);
+ return GenerateTypeScriptFunction(input, output);
+}
+
bool
ScriptInterpreterPython::GenerateBreakpointCommandCallbackData (StringList &user_input, StringList &callback_data)
{
@@ -1206,6 +1318,63 @@
return true;
}
+std::string
+ScriptInterpreterPython::CallPythonScriptFunction (const char *python_function_name,
+ lldb::ValueObjectSP valobj)
+{
+
+ if (!python_function_name || !(*python_function_name))
+ return "";
+
+ if (!valobj.get())
+ return "";
+
+ Target *target = valobj->GetUpdatePoint().GetTarget();
+
+ if (!target)
+ return "";
+
+ Debugger &debugger = target->GetDebugger();
+ ScriptInterpreter *script_interpreter = debugger.GetCommandInterpreter().GetScriptInterpreter();
+ ScriptInterpreterPython *python_interpreter = (ScriptInterpreterPython *) script_interpreter;
+
+ if (!script_interpreter)
+ return "";
+
+ std::string ret_val;
+
+ if (python_function_name
+ && *python_function_name)
+ {
+ FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout);
+ if (CurrentThreadHasPythonLock())
+ {
+ python_interpreter->EnterSession ();
+ ret_val = g_swig_typescript_callback (python_function_name,
+ python_interpreter->m_dictionary_name.c_str(),
+ valobj);
+ python_interpreter->LeaveSession ();
+ }
+ else
+ {
+ while (!GetPythonLock (1))
+ fprintf (tmp_fh,
+ "Python interpreter locked on another thread; waiting to acquire lock...\n");
+ python_interpreter->EnterSession ();
+ ret_val = g_swig_typescript_callback (python_function_name,
+ python_interpreter->m_dictionary_name.c_str(),
+ valobj);
+ python_interpreter->LeaveSession ();
+ ReleasePythonLock ();
+ }
+ }
+ else
+ return "";
+
+ return ret_val;
+
+}
+
bool
ScriptInterpreterPython::BreakpointCallbackFunction
(
@@ -1399,10 +1568,12 @@
void
ScriptInterpreterPython::InitializeInterpreter (SWIGInitCallback python_swig_init_callback,
- SWIGBreakpointCallbackFunction python_swig_breakpoint_callback)
+ SWIGBreakpointCallbackFunction python_swig_breakpoint_callback,
+ SWIGPythonTypeScriptCallbackFunction python_swig_typescript_callback)
{
g_swig_init_callback = python_swig_init_callback;
- g_swig_breakpoint_callback = python_swig_breakpoint_callback;
+ g_swig_breakpoint_callback = python_swig_breakpoint_callback;
+ g_swig_typescript_callback = python_swig_typescript_callback;
}
void
Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp?rev=135238&r1=135237&r2=135238&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp Thu Jul 14 21:26:42 2011
@@ -19,6 +19,7 @@
#include "lldb/Core/Log.h"
#include "lldb/Core/State.h"
#include "lldb/Core/StreamString.h"
+#include "lldb/Host/Endian.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/TimeValue.h"
#include "lldb/Target/Process.h"
Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-script/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-script/Makefile?rev=135238&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-script/Makefile (added)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-script/Makefile Thu Jul 14 21:26:42 2011
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py?rev=135238&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py (added)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py Thu Jul 14 21:26:42 2011
@@ -0,0 +1,110 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+
+class DataFormatterTestCase(TestBase):
+
+ mydir = os.path.join("functionalities", "data-formatter", "data-formatter-script")
+
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ def test_with_dsym_and_run_command(self):
+ """Test data formatter commands."""
+ self.buildDsym()
+ self.data_formatter_commands()
+
+ def test_with_dwarf_and_run_command(self):
+ """Test data formatter commands."""
+ self.buildDwarf()
+ self.data_formatter_commands()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break at.
+ self.line = line_number('main.cpp', '// Set break point at this line.')
+
+ def data_formatter_commands(self):
+ """Test that that file and class static variables display correctly."""
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ self.expect("breakpoint set -f main.cpp -l %d" % self.line,
+ BREAKPOINT_CREATED,
+ startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" %
+ self.line)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # This is the function to remove the custom formats in order to have a
+ # clean slate for the next test case.
+ def cleanup():
+ self.runCmd('type format clear', check=False)
+ self.runCmd('type summary clear', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ # Set the script here to ease the formatting
+ script = 'a = valobj.GetChildMemberWithName(\'integer\'); a_val = a.GetValue(); str = \'Hello from Python, \' + a_val + \' time\'; return str + (\'!\' if a_val == \'1\' else \'s!\');'
+
+ self.runCmd("type summary add add i_am_cool -s \"%s\"" % script)
+
+ self.expect("frame variable one",
+ substrs = ['Hello from Python',
+ '1 time!'])
+
+ self.expect("frame variable two",
+ substrs = ['Hello from Python',
+ '4 times!'])
+
+ self.runCmd("n"); # skip ahead to make values change
+
+ self.expect("frame variable three",
+ substrs = ['Hello from Python, 10 times!',
+ 'Hello from Python, 4 times!'])
+
+ self.runCmd("n"); # skip ahead to make values change
+
+ self.expect("frame variable two",
+ substrs = ['Hello from Python',
+ '1 time!'])
+
+ script = 'a = valobj.GetChildMemberWithName(\'integer\'); a_val = a.GetValue(); str = \'int says \' + a_val; return str;'
+
+ # Check that changes in the script are immediately reflected
+ self.runCmd("type summary add i_am_cool -s \"%s\"" % script)
+
+ self.expect("frame variable two",
+ substrs = ['int says 1'])
+
+ # Change the summary
+ self.runCmd("type summary add -f \"int says ${var.integer}, and float says ${var.floating}\" i_am_cool")
+
+ self.expect("frame variable two",
+ substrs = ['int says 1',
+ 'and float says 2.71'])
+ # Try it for pointers
+ self.expect("frame variable twoptr",
+ substrs = ['int says 1',
+ 'and float says 2.71'])
+
+ # Force a failure for pointers
+ self.runCmd("type summary add i_am_cool -p -s \"%s\"" % script)
+
+ self.expect("frame variable twoptr", matching=False,
+ substrs = ['and float says 2.71'])
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-script/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-script/main.cpp?rev=135238&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-script/main.cpp (added)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-script/main.cpp Thu Jul 14 21:26:42 2011
@@ -0,0 +1,49 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include
+#include
+#include
+
+struct i_am_cool
+{
+ int integer;
+ float floating;
+ char character;
+ i_am_cool(int I, float F, char C) :
+ integer(I), floating(F), character(C) {}
+ i_am_cool() : integer(1), floating(2), character('3') {}
+
+};
+
+struct i_am_cooler
+{
+ i_am_cool first_cool;
+ i_am_cool second_cool;
+ float floating;
+
+ i_am_cooler(int I1, int I2, float F1, float F2, char C1, char C2) :
+ first_cool(I1,F1,C1),
+ second_cool(I2,F2,C2),
+ floating((F1 + F2)/2) {}
+};
+
+int main (int argc, const char * argv[])
+{
+ i_am_cool one(1,3.14,'E');
+ i_am_cool two(4,2.71,'G');
+
+ i_am_cool* twoptr = &two;
+
+ i_am_cooler three(10,4,1985,1/1/2011,'B','E'); // Set break point at this line.
+
+ two.integer = 1;
+
+ return 0;
+}
\ No newline at end of file
Modified: lldb/trunk/www/varformats.html
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/www/varformats.html?rev=135238&r1=135237&r2=135238&view=diff
==============================================================================
--- lldb/trunk/www/varformats.html (original)
+++ lldb/trunk/www/varformats.html Thu Jul 14 21:26:42 2011
@@ -784,6 +784,17 @@
(i_am_cool) one = x=3
+ When defining a named summmary, binding it to one or more types becomes optional.
+ Even if you bind the named summary to a type, and later change the summary string
+ for that type, the named summary will not be changed by that. You can delete
+ named summaries by using the type summary delete command, as if the
+ summary name was the datatype that the summary is applied to
+
+ A summary attached to a variable using the --summary option,
+ has the same semantics that a custom format attached using the -f
+ option has: it stays attached till you attach a new one, or till you let
+ your program run again.
+
From gclayton at apple.com Thu Jul 14 22:27:12 2011
From: gclayton at apple.com (Greg Clayton)
Date: Fri, 15 Jul 2011 03:27:12 -0000
Subject: [Lldb-commits] [lldb] r135240 - in
/lldb/trunk/source/Plugins/Process/MacOSX-Kernel: ./ CommunicationKDP.cpp
CommunicationKDP.h ProcessKDP.cpp ProcessKDP.h ProcessKDPLog.cpp
ProcessKDPLog.h
Message-ID: <20110715032712.84FB72A6C12C@llvm.org>
Author: gclayton
Date: Thu Jul 14 22:27:12 2011
New Revision: 135240
URL: http://llvm.org/viewvc/llvm-project?rev=135240&view=rev
Log:
Hollowed out process plug-in to do KDP darwin kernel debugging.
Added:
lldb/trunk/source/Plugins/Process/MacOSX-Kernel/
lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp
lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h
Added: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp?rev=135240&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp (added)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp Thu Jul 14 22:27:12 2011
@@ -0,0 +1,403 @@
+//===-- CommunicationKDP.cpp ------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#include "CommunicationKDP.h"
+
+// C Includes
+#include
+#include
+
+// C++ Includes
+// Other libraries and framework includes
+#include "lldb/Core/Log.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Host/TimeValue.h"
+#include "lldb/Target/Process.h"
+#include "Utility/StringExtractor.h"
+
+// Project includes
+#include "ProcessKDPLog.h"
+
+#define DEBUGSERVER_BASENAME "debugserver"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// CommunicationKDP constructor
+//----------------------------------------------------------------------
+CommunicationKDP::CommunicationKDP (const char *comm_name) :
+ Communication(comm_name),
+ m_packet_timeout (1),
+ m_sequence_mutex (Mutex::eMutexTypeRecursive),
+ m_public_is_running (false),
+ m_private_is_running (false),
+ m_send_acks (true)
+{
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+CommunicationKDP::~CommunicationKDP()
+{
+ if (IsConnected())
+ {
+ Disconnect();
+ }
+}
+
+char
+CommunicationKDP::CalculcateChecksum (const char *payload, size_t payload_length)
+{
+ int checksum = 0;
+
+ // We only need to compute the checksum if we are sending acks
+ if (GetSendAcks ())
+ {
+ for (size_t i = 0; i < payload_length; ++i)
+ checksum += payload[i];
+ }
+ return checksum & 255;
+}
+
+size_t
+CommunicationKDP::SendAck ()
+{
+ LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
+ if (log)
+ log->Printf ("send packet: +");
+ ConnectionStatus status = eConnectionStatusSuccess;
+ char ack_char = '+';
+ return Write (&ack_char, 1, status, NULL);
+}
+
+size_t
+CommunicationKDP::SendNack ()
+{
+ LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
+ if (log)
+ log->Printf ("send packet: -");
+ ConnectionStatus status = eConnectionStatusSuccess;
+ char nack_char = '-';
+ return Write (&nack_char, 1, status, NULL);
+}
+
+size_t
+CommunicationKDP::SendPacket (lldb_private::StreamString &payload)
+{
+ Mutex::Locker locker(m_sequence_mutex);
+ const std::string &p (payload.GetString());
+ return SendPacketNoLock (p.c_str(), p.size());
+}
+
+size_t
+CommunicationKDP::SendPacket (const char *payload)
+{
+ Mutex::Locker locker(m_sequence_mutex);
+ return SendPacketNoLock (payload, ::strlen (payload));
+}
+
+size_t
+CommunicationKDP::SendPacket (const char *payload, size_t payload_length)
+{
+ Mutex::Locker locker(m_sequence_mutex);
+ return SendPacketNoLock (payload, payload_length);
+}
+
+size_t
+CommunicationKDP::SendPacketNoLock (const char *payload, size_t payload_length)
+{
+ if (IsConnected())
+ {
+ StreamString packet(0, 4, eByteOrderBig);
+
+ packet.PutChar('$');
+ packet.Write (payload, payload_length);
+ packet.PutChar('#');
+ packet.PutHex8(CalculcateChecksum (payload, payload_length));
+
+ LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
+ if (log)
+ log->Printf ("send packet: %.*s", (int)packet.GetSize(), packet.GetData());
+ ConnectionStatus status = eConnectionStatusSuccess;
+ size_t bytes_written = Write (packet.GetData(), packet.GetSize(), status, NULL);
+ if (bytes_written == packet.GetSize())
+ {
+ if (GetSendAcks ())
+ {
+ if (GetAck () != '+')
+ {
+ printf("get ack failed...");
+ return 0;
+ }
+ }
+ }
+ else
+ {
+ LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
+ if (log)
+ log->Printf ("error: failed to send packet: %.*s", (int)packet.GetSize(), packet.GetData());
+ }
+ return bytes_written;
+ }
+ return 0;
+}
+
+char
+CommunicationKDP::GetAck ()
+{
+ StringExtractor packet;
+ if (WaitForPacketWithTimeoutMicroSeconds (packet, GetPacketTimeoutInMicroSeconds ()) == 1)
+ return packet.GetChar();
+ return 0;
+}
+
+bool
+CommunicationKDP::GetSequenceMutex (Mutex::Locker& locker)
+{
+ return locker.TryLock (m_sequence_mutex.GetMutex());
+}
+
+
+bool
+CommunicationKDP::WaitForNotRunningPrivate (const TimeValue *timeout_ptr)
+{
+ return m_private_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
+}
+
+size_t
+CommunicationKDP::WaitForPacketWithTimeoutMicroSeconds (StringExtractor &packet, uint32_t timeout_usec)
+{
+ Mutex::Locker locker(m_sequence_mutex);
+ return WaitForPacketWithTimeoutMicroSecondsNoLock (packet, timeout_usec);
+}
+
+size_t
+CommunicationKDP::WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractor &packet, uint32_t timeout_usec)
+{
+ uint8_t buffer[8192];
+ Error error;
+
+ LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS | KDP_LOG_VERBOSE));
+
+ // Check for a packet from our cache first without trying any reading...
+ if (CheckForPacket (NULL, 0, packet))
+ return packet.GetStringRef().size();
+
+ bool timed_out = false;
+ while (IsConnected() && !timed_out)
+ {
+ lldb::ConnectionStatus status;
+ size_t bytes_read = Read (buffer, sizeof(buffer), timeout_usec, status, &error);
+
+ if (log)
+ log->Printf ("%s: Read (buffer, (sizeof(buffer), timeout_usec = 0x%x, status = %s, error = %s) => bytes_read = %zu",
+ __PRETTY_FUNCTION__,
+ timeout_usec,
+ Communication::ConnectionStatusAsCString (status),
+ error.AsCString(),
+ bytes_read);
+
+ if (bytes_read > 0)
+ {
+ if (CheckForPacket (buffer, bytes_read, packet))
+ return packet.GetStringRef().size();
+ }
+ else
+ {
+ switch (status)
+ {
+ case eConnectionStatusTimedOut:
+ timed_out = true;
+ break;
+ case eConnectionStatusSuccess:
+ //printf ("status = success but error = %s\n", error.AsCString(""));
+ break;
+
+ case eConnectionStatusEndOfFile:
+ case eConnectionStatusNoConnection:
+ case eConnectionStatusLostConnection:
+ case eConnectionStatusError:
+ Disconnect();
+ break;
+ }
+ }
+ }
+ packet.Clear ();
+ return 0;
+}
+
+bool
+CommunicationKDP::CheckForPacket (const uint8_t *src, size_t src_len, StringExtractor &packet)
+{
+ // Put the packet data into the buffer in a thread safe fashion
+ Mutex::Locker locker(m_bytes_mutex);
+
+ LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
+
+ if (src && src_len > 0)
+ {
+ if (log && log->GetVerbose())
+ {
+ StreamString s;
+ log->Printf ("CommunicationKDP::%s adding %u bytes: %.*s",
+ __FUNCTION__,
+ (uint32_t)src_len,
+ (uint32_t)src_len,
+ src);
+ }
+ m_bytes.append ((const char *)src, src_len);
+ }
+
+ // Parse up the packets into gdb remote packets
+ if (!m_bytes.empty())
+ {
+ // end_idx must be one past the last valid packet byte. Start
+ // it off with an invalid value that is the same as the current
+ // index.
+ size_t content_start = 0;
+ size_t content_length = 0;
+ size_t total_length = 0;
+ size_t checksum_idx = std::string::npos;
+
+ switch (m_bytes[0])
+ {
+ case '+': // Look for ack
+ case '-': // Look for cancel
+ case '\x03': // ^C to halt target
+ content_length = total_length = 1; // The command is one byte long...
+ break;
+
+ case '$':
+ // Look for a standard gdb packet?
+ {
+ size_t hash_pos = m_bytes.find('#');
+ if (hash_pos != std::string::npos)
+ {
+ if (hash_pos + 2 < m_bytes.size())
+ {
+ checksum_idx = hash_pos + 1;
+ // Skip the dollar sign
+ content_start = 1;
+ // Don't include the # in the content or the $ in the content length
+ content_length = hash_pos - 1;
+
+ total_length = hash_pos + 3; // Skip the # and the two hex checksum bytes
+ }
+ else
+ {
+ // Checksum bytes aren't all here yet
+ content_length = std::string::npos;
+ }
+ }
+ }
+ break;
+
+ default:
+ {
+ // We have an unexpected byte and we need to flush all bad
+ // data that is in m_bytes, so we need to find the first
+ // byte that is a '+' (ACK), '-' (NACK), \x03 (CTRL+C interrupt),
+ // or '$' character (start of packet header) or of course,
+ // the end of the data in m_bytes...
+ const size_t bytes_len = m_bytes.size();
+ bool done = false;
+ uint32_t idx;
+ for (idx = 1; !done && idx < bytes_len; ++idx)
+ {
+ switch (m_bytes[idx])
+ {
+ case '+':
+ case '-':
+ case '\x03':
+ case '$':
+ done = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+ if (log)
+ log->Printf ("CommunicationKDP::%s tossing %u junk bytes: '%.*s'",
+ __FUNCTION__, idx, idx, m_bytes.c_str());
+ m_bytes.erase(0, idx);
+ }
+ break;
+ }
+
+ if (content_length == std::string::npos)
+ {
+ packet.Clear();
+ return false;
+ }
+ else if (total_length > 0)
+ {
+
+ // We have a valid packet...
+ assert (content_length <= m_bytes.size());
+ assert (total_length <= m_bytes.size());
+ assert (content_length <= total_length);
+
+ bool success = true;
+ std::string &packet_str = packet.GetStringRef();
+ packet_str.assign (m_bytes, content_start, content_length);
+ if (m_bytes[0] == '$')
+ {
+ assert (checksum_idx < m_bytes.size());
+ if (::isxdigit (m_bytes[checksum_idx+0]) ||
+ ::isxdigit (m_bytes[checksum_idx+1]))
+ {
+ if (GetSendAcks ())
+ {
+ const char *packet_checksum_cstr = &m_bytes[checksum_idx];
+ char packet_checksum = strtol (packet_checksum_cstr, NULL, 16);
+ char actual_checksum = CalculcateChecksum (packet_str.c_str(), packet_str.size());
+ success = packet_checksum == actual_checksum;
+ if (!success)
+ {
+ if (log)
+ log->Printf ("error: checksum mismatch: %.*s expected 0x%2.2x, got 0x%2.2x",
+ (int)(total_length),
+ m_bytes.c_str(),
+ (uint8_t)packet_checksum,
+ (uint8_t)actual_checksum);
+ }
+ // Send the ack or nack if needed
+ if (!success)
+ SendNack();
+ else
+ SendAck();
+ }
+ if (success)
+ {
+ if (log)
+ log->Printf ("read packet: %.*s", (int)(total_length), m_bytes.c_str());
+ }
+ }
+ else
+ {
+ success = false;
+ if (log)
+ log->Printf ("error: invalid checksum in packet: '%s'\n", (int)(total_length), m_bytes.c_str());
+ }
+ }
+ m_bytes.erase(0, total_length);
+ packet.SetFilePos(0);
+ return success;
+ }
+ }
+ packet.Clear();
+ return false;
+}
+
Added: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h?rev=135240&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h (added)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h Thu Jul 14 22:27:12 2011
@@ -0,0 +1,152 @@
+//===-- CommunicationKDP.h --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_CommunicationKDP_h_
+#define liblldb_CommunicationKDP_h_
+
+// C Includes
+// C++ Includes
+#include
+#include
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Core/Communication.h"
+#include "lldb/Core/Listener.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Host/Predicate.h"
+#include "lldb/Host/TimeValue.h"
+
+class StringExtractor;
+
+class CommunicationKDP : public lldb_private::Communication
+{
+public:
+ enum
+ {
+ eBroadcastBitRunPacketSent = kLoUserBroadcastBit
+ };
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ CommunicationKDP (const char *comm_name);
+
+ virtual
+ ~CommunicationKDP();
+
+ size_t
+ SendPacket (const char *payload);
+
+ size_t
+ SendPacket (const char *payload,
+ size_t payload_length);
+
+ size_t
+ SendPacket (lldb_private::StreamString &response);
+
+ // Wait for a packet within 'nsec' seconds
+ size_t
+ WaitForPacketWithTimeoutMicroSeconds (StringExtractor &response,
+ uint32_t usec);
+
+ char
+ GetAck ();
+
+ size_t
+ SendAck ();
+
+ size_t
+ SendNack ();
+
+ char
+ CalculcateChecksum (const char *payload,
+ size_t payload_length);
+
+ bool
+ GetSequenceMutex(lldb_private::Mutex::Locker& locker);
+
+ bool
+ CheckForPacket (const uint8_t *src,
+ size_t src_len,
+ StringExtractor &packet);
+ bool
+ IsRunning() const
+ {
+ return m_public_is_running.GetValue();
+ }
+
+ bool
+ GetSendAcks ()
+ {
+ return m_send_acks;
+ }
+
+ //------------------------------------------------------------------
+ // Set the global packet timeout.
+ //
+ // For clients, this is the timeout that gets used when sending
+ // packets and waiting for responses. For servers, this might not
+ // get used, and if it doesn't this should be moved to the
+ // CommunicationKDPClient.
+ //------------------------------------------------------------------
+ uint32_t
+ SetPacketTimeout (uint32_t packet_timeout)
+ {
+ const uint32_t old_packet_timeout = m_packet_timeout;
+ m_packet_timeout = packet_timeout;
+ return old_packet_timeout;
+ }
+
+ uint32_t
+ GetPacketTimeoutInMicroSeconds () const
+ {
+ return m_packet_timeout * lldb_private::TimeValue::MicroSecPerSec;
+ }
+ //------------------------------------------------------------------
+ // Start a debugserver instance on the current host using the
+ // supplied connection URL.
+ //------------------------------------------------------------------
+ lldb_private::Error
+ StartDebugserverProcess (const char *connect_url,
+ const char *unix_socket_name,
+ lldb_private::ProcessLaunchInfo &launch_info);
+
+
+protected:
+ typedef std::list packet_collection;
+
+ size_t
+ SendPacketNoLock (const char *payload,
+ size_t payload_length);
+
+ size_t
+ WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractor &response,
+ uint32_t timeout_usec);
+
+ bool
+ WaitForNotRunningPrivate (const lldb_private::TimeValue *timeout_ptr);
+
+ //------------------------------------------------------------------
+ // Classes that inherit from CommunicationKDP can see and modify these
+ //------------------------------------------------------------------
+ uint32_t m_packet_timeout;
+ lldb_private::Mutex m_sequence_mutex; // Restrict access to sending/receiving packets to a single thread at a time
+ lldb_private::Predicate m_public_is_running;
+ lldb_private::Predicate m_private_is_running;
+ bool m_send_acks;
+
+private:
+ //------------------------------------------------------------------
+ // For CommunicationKDP only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (CommunicationKDP);
+};
+
+#endif // liblldb_CommunicationKDP_h_
Added: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp?rev=135240&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp (added)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp Thu Jul 14 22:27:12 2011
@@ -0,0 +1,725 @@
+//===-- ProcessKDP.cpp ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// C Includes
+#include
+#include
+
+// C++ Includes
+// Other libraries and framework includes
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/State.h"
+#include "lldb/Host/Host.h"
+
+// Project includes
+#include "ProcessKDP.h"
+#include "ProcessKDPLog.h"
+//#include "ThreadKDP.h"
+#include "StopInfoMachException.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+const char *
+ProcessKDP::GetPluginNameStatic()
+{
+ return "kdp-remote";
+}
+
+const char *
+ProcessKDP::GetPluginDescriptionStatic()
+{
+ return "KDP Remote protocol based debugging plug-in for darwin kernel debugging.";
+}
+
+void
+ProcessKDP::Terminate()
+{
+ PluginManager::UnregisterPlugin (ProcessKDP::CreateInstance);
+}
+
+
+Process*
+ProcessKDP::CreateInstance (Target &target, Listener &listener)
+{
+ return new ProcessKDP (target, listener);
+}
+
+bool
+ProcessKDP::CanDebug(Target &target)
+{
+ // For now we are just making sure the file exists for a given module
+ ModuleSP exe_module_sp(target.GetExecutableModule());
+ if (exe_module_sp.get())
+ {
+ const llvm::Triple &triple_ref = target.GetArchitecture().GetTriple();
+ if (triple_ref.getOS() == llvm::Triple::Darwin &&
+ triple_ref.getVendor() == llvm::Triple::Apple)
+ {
+
+ ObjectFile *exe_objfile = exe_module_sp->GetObjectFile();
+ if (exe_objfile->GetType() == ObjectFile::eTypeExecutable &&
+ exe_objfile->GetStrata() == ObjectFile::eStrataKernel)
+ return true;
+ }
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------
+// ProcessKDP constructor
+//----------------------------------------------------------------------
+ProcessKDP::ProcessKDP(Target& target, Listener &listener) :
+ Process (target, listener),
+ m_comm("lldb.process.kdp-remote.communication"),
+ m_async_broadcaster ("lldb.process.kdp-remote.async-broadcaster"),
+ m_async_thread (LLDB_INVALID_HOST_THREAD)
+{
+// m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit, "async thread should exit");
+// m_async_broadcaster.SetEventName (eBroadcastBitAsyncContinue, "async thread continue");
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+ProcessKDP::~ProcessKDP()
+{
+ Clear();
+}
+
+//----------------------------------------------------------------------
+// PluginInterface
+//----------------------------------------------------------------------
+const char *
+ProcessKDP::GetPluginName()
+{
+ return "Process debugging plug-in that uses the Darwin KDP remote protocol";
+}
+
+const char *
+ProcessKDP::GetShortPluginName()
+{
+ return GetPluginNameStatic();
+}
+
+uint32_t
+ProcessKDP::GetPluginVersion()
+{
+ return 1;
+}
+
+Error
+ProcessKDP::WillLaunch (Module* module)
+{
+ Error error;
+ error.SetErrorString ("launching not supported in kdp-remote plug-in");
+ return error;
+}
+
+Error
+ProcessKDP::WillAttachToProcessWithID (lldb::pid_t pid)
+{
+ Error error;
+ error.SetErrorString ("attaching to a by process ID not supported in kdp-remote plug-in");
+ return error;
+}
+
+Error
+ProcessKDP::WillAttachToProcessWithName (const char *process_name, bool wait_for_launch)
+{
+ Error error;
+ error.SetErrorString ("attaching to a by process name not supported in kdp-remote plug-in");
+ return error;
+}
+
+Error
+ProcessKDP::DoConnectRemote (const char *remote_url)
+{
+ // TODO: fill in the remote connection to the remote KDP here!
+ Error error;
+ error.SetErrorString ("attaching to a by process name not supported in kdp-remote plug-in");
+ return error;
+}
+
+//----------------------------------------------------------------------
+// Process Control
+//----------------------------------------------------------------------
+Error
+ProcessKDP::DoLaunch (Module* module,
+ char const *argv[],
+ char const *envp[],
+ uint32_t launch_flags,
+ const char *stdin_path,
+ const char *stdout_path,
+ const char *stderr_path,
+ const char *working_dir)
+{
+ Error error;
+ error.SetErrorString ("launching not supported in kdp-remote plug-in");
+ return error;
+}
+
+
+Error
+ProcessKDP::DoAttachToProcessWithID (lldb::pid_t attach_pid)
+{
+ Error error;
+ error.SetErrorString ("attach to process by ID is not suppported in kdp remote debugging");
+ return error;
+}
+
+size_t
+ProcessKDP::AttachInputReaderCallback (void *baton,
+ InputReader *reader,
+ lldb::InputReaderAction notification,
+ const char *bytes,
+ size_t bytes_len)
+{
+ if (notification == eInputReaderGotToken)
+ {
+// ProcessKDP *process = (ProcessKDP *)baton;
+// if (process->m_waiting_for_attach)
+// process->m_waiting_for_attach = false;
+ reader->SetIsDone(true);
+ return 1;
+ }
+ return 0;
+}
+
+Error
+ProcessKDP::DoAttachToProcessWithName (const char *process_name, bool wait_for_launch)
+{
+ Error error;
+ error.SetErrorString ("attach to process by name is not suppported in kdp remote debugging");
+ return error;
+}
+
+
+void
+ProcessKDP::DidAttach ()
+{
+ LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS));
+ if (log)
+ log->Printf ("ProcessKDP::DidLaunch()");
+ if (GetID() != LLDB_INVALID_PROCESS_ID)
+ {
+ // TODO: figure out the register context that we will use
+ }
+}
+
+Error
+ProcessKDP::WillResume ()
+{
+ return Error();
+}
+
+Error
+ProcessKDP::DoResume ()
+{
+ Error error;
+ error.SetErrorString ("ProcessKDP::DoResume () is not implemented yet");
+ return error;
+}
+
+uint32_t
+ProcessKDP::UpdateThreadListIfNeeded ()
+{
+ // locker will keep a mutex locked until it goes out of scope
+ LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_THREAD));
+ if (log && log->GetMask().Test(KDP_LOG_VERBOSE))
+ log->Printf ("ProcessKDP::%s (pid = %i)", __FUNCTION__, GetID());
+
+ Mutex::Locker locker (m_thread_list.GetMutex ());
+ // TODO: get the thread list here!
+ const uint32_t stop_id = GetStopID();
+ if (m_thread_list.GetSize(false) == 0 || stop_id != m_thread_list.GetStopID())
+ {
+ // Update the thread list's stop id immediately so we don't recurse into this function.
+// ThreadList curr_thread_list (this);
+// curr_thread_list.SetStopID(stop_id);
+//
+// std::vector thread_ids;
+// bool sequence_mutex_unavailable = false;
+// const size_t num_thread_ids = m_comm.GetCurrentThreadIDs (thread_ids, sequence_mutex_unavailable);
+// if (num_thread_ids > 0)
+// {
+// for (size_t i=0; iPrintf ("ProcessKDP::InterruptIfRunning(discard_thread_plans=%i, catch_stop_event=%i) is_running=%i",
+ discard_thread_plans,
+ catch_stop_event,
+ is_running);
+
+ if (discard_thread_plans)
+ {
+ if (log)
+ log->Printf ("ProcessKDP::InterruptIfRunning() discarding all thread plans");
+ m_thread_list.DiscardThreadPlans();
+ }
+ if (is_running)
+ {
+ if (catch_stop_event)
+ {
+ if (log)
+ log->Printf ("ProcessKDP::InterruptIfRunning() pausing private state thread");
+ PausePrivateStateThread();
+ paused_private_state_thread = true;
+ }
+
+ bool timed_out = false;
+// bool sent_interrupt = false;
+ Mutex::Locker locker;
+
+ // TODO: implement halt in CommunicationKDP
+// if (!m_comm.SendInterrupt (locker, 1, sent_interrupt, timed_out))
+// {
+// if (timed_out)
+// error.SetErrorString("timed out sending interrupt packet");
+// else
+// error.SetErrorString("unknown error sending interrupt packet");
+// if (paused_private_state_thread)
+// ResumePrivateStateThread();
+// return error;
+// }
+
+ if (catch_stop_event)
+ {
+ // LISTEN HERE
+ TimeValue timeout_time;
+ timeout_time = TimeValue::Now();
+ timeout_time.OffsetWithSeconds(5);
+ StateType state = WaitForStateChangedEventsPrivate (&timeout_time, stop_event_sp);
+
+ timed_out = state == eStateInvalid;
+ if (log)
+ log->Printf ("ProcessKDP::InterruptIfRunning() catch stop event: state = %s, timed-out=%i", StateAsCString(state), timed_out);
+
+ if (timed_out)
+ error.SetErrorString("unable to verify target stopped");
+ }
+
+ if (paused_private_state_thread)
+ {
+ if (log)
+ log->Printf ("ProcessKDP::InterruptIfRunning() resuming private state thread");
+ ResumePrivateStateThread();
+ }
+ }
+ return error;
+}
+
+Error
+ProcessKDP::WillDetach ()
+{
+ LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
+ if (log)
+ log->Printf ("ProcessKDP::WillDetach()");
+
+ bool discard_thread_plans = true;
+ bool catch_stop_event = true;
+ EventSP event_sp;
+ return InterruptIfRunning (discard_thread_plans, catch_stop_event, event_sp);
+}
+
+Error
+ProcessKDP::DoDetach()
+{
+ Error error;
+ LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
+ if (log)
+ log->Printf ("ProcessKDP::DoDetach()");
+
+ DisableAllBreakpointSites ();
+
+ m_thread_list.DiscardThreadPlans();
+
+ size_t response_size = m_comm.SendPacket ("D", 1);
+ if (log)
+ {
+ if (response_size)
+ log->PutCString ("ProcessKDP::DoDetach() detach packet sent successfully");
+ else
+ log->PutCString ("ProcessKDP::DoDetach() detach packet send failed");
+ }
+ // Sleep for one second to let the process get all detached...
+ StopAsyncThread ();
+
+ m_comm.StopReadThread();
+ m_comm.Disconnect(); // Disconnect from the debug server.
+
+ SetPrivateState (eStateDetached);
+ ResumePrivateStateThread();
+
+ //KillDebugserverProcess ();
+ return error;
+}
+
+Error
+ProcessKDP::DoDestroy ()
+{
+ Error error;
+ LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
+ if (log)
+ log->Printf ("ProcessKDP::DoDestroy()");
+
+ // Interrupt if our inferior is running...
+ if (m_comm.IsConnected())
+ {
+ if (m_public_state.GetValue() == eStateAttaching)
+ {
+ // We are being asked to halt during an attach. We need to just close
+ // our file handle and debugserver will go away, and we can be done...
+ m_comm.Disconnect();
+ }
+ else
+ {
+
+ StringExtractor response;
+ // TODO: Send kill packet?
+ SetExitStatus(SIGABRT, NULL);
+ }
+ }
+ StopAsyncThread ();
+ m_comm.StopReadThread();
+ m_comm.Disconnect(); // Disconnect from the debug server.
+ return error;
+}
+
+//------------------------------------------------------------------
+// Process Queries
+//------------------------------------------------------------------
+
+bool
+ProcessKDP::IsAlive ()
+{
+ return m_comm.IsConnected() && m_private_state.GetValue() != eStateExited;
+}
+
+//------------------------------------------------------------------
+// Process Memory
+//------------------------------------------------------------------
+size_t
+ProcessKDP::DoReadMemory (addr_t addr, void *buf, size_t size, Error &error)
+{
+ error.SetErrorString ("ProcessKDP::DoReadMemory not implemented");
+ return 0;
+}
+
+size_t
+ProcessKDP::DoWriteMemory (addr_t addr, const void *buf, size_t size, Error &error)
+{
+ error.SetErrorString ("ProcessKDP::DoReadMemory not implemented");
+ return 0;
+}
+
+lldb::addr_t
+ProcessKDP::DoAllocateMemory (size_t size, uint32_t permissions, Error &error)
+{
+ error.SetErrorString ("memory allocation not suppported in kdp remote debugging");
+ return LLDB_INVALID_ADDRESS;
+}
+
+Error
+ProcessKDP::DoDeallocateMemory (lldb::addr_t addr)
+{
+ Error error;
+ error.SetErrorString ("memory deallocation not suppported in kdp remote debugging");
+ return error;
+}
+
+Error
+ProcessKDP::EnableBreakpoint (BreakpointSite *bp_site)
+{
+ return EnableSoftwareBreakpoint (bp_site);
+}
+
+Error
+ProcessKDP::DisableBreakpoint (BreakpointSite *bp_site)
+{
+ return DisableSoftwareBreakpoint (bp_site);
+}
+
+Error
+ProcessKDP::EnableWatchpoint (WatchpointLocation *wp)
+{
+ Error error;
+ error.SetErrorString ("watchpoints are not suppported in kdp remote debugging");
+ return error;
+}
+
+Error
+ProcessKDP::DisableWatchpoint (WatchpointLocation *wp)
+{
+ Error error;
+ error.SetErrorString ("watchpoints are not suppported in kdp remote debugging");
+ return error;
+}
+
+void
+ProcessKDP::Clear()
+{
+ Mutex::Locker locker (m_thread_list.GetMutex ());
+ m_thread_list.Clear();
+}
+
+Error
+ProcessKDP::DoSignal (int signo)
+{
+ Error error;
+ error.SetErrorString ("sending signals is not suppported in kdp remote debugging");
+ return error;
+}
+
+void
+ProcessKDP::Initialize()
+{
+ static bool g_initialized = false;
+
+ if (g_initialized == false)
+ {
+ g_initialized = true;
+ PluginManager::RegisterPlugin (GetPluginNameStatic(),
+ GetPluginDescriptionStatic(),
+ CreateInstance);
+
+ Log::Callbacks log_callbacks = {
+ ProcessKDPLog::DisableLog,
+ ProcessKDPLog::EnableLog,
+ ProcessKDPLog::ListLogCategories
+ };
+
+ Log::RegisterLogChannel (ProcessKDP::GetPluginNameStatic(), log_callbacks);
+ }
+}
+
+bool
+ProcessKDP::StartAsyncThread ()
+{
+ LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
+
+ if (log)
+ log->Printf ("ProcessKDP::%s ()", __FUNCTION__);
+
+ // Create a thread that watches our internal state and controls which
+ // events make it to clients (into the DCProcess event queue).
+ m_async_thread = Host::ThreadCreate ("", ProcessKDP::AsyncThread, this, NULL);
+ return IS_VALID_LLDB_HOST_THREAD(m_async_thread);
+}
+
+void
+ProcessKDP::StopAsyncThread ()
+{
+ LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
+
+ if (log)
+ log->Printf ("ProcessKDP::%s ()", __FUNCTION__);
+
+ m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncThreadShouldExit);
+
+ // Stop the stdio thread
+ if (IS_VALID_LLDB_HOST_THREAD(m_async_thread))
+ {
+ Host::ThreadJoin (m_async_thread, NULL, NULL);
+ }
+}
+
+
+void *
+ProcessKDP::AsyncThread (void *arg)
+{
+ ProcessKDP *process = (ProcessKDP*) arg;
+
+ LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS));
+ if (log)
+ log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) thread starting...", __FUNCTION__, arg, process->GetID());
+
+ Listener listener ("ProcessKDP::AsyncThread");
+ EventSP event_sp;
+ const uint32_t desired_event_mask = eBroadcastBitAsyncContinue |
+ eBroadcastBitAsyncThreadShouldExit;
+
+ if (listener.StartListeningForEvents (&process->m_async_broadcaster, desired_event_mask) == desired_event_mask)
+ {
+ listener.StartListeningForEvents (&process->m_comm, Communication::eBroadcastBitReadThreadDidExit);
+
+ bool done = false;
+ while (!done)
+ {
+ if (log)
+ log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) listener.WaitForEvent (NULL, event_sp)...", __FUNCTION__, arg, process->GetID());
+ if (listener.WaitForEvent (NULL, event_sp))
+ {
+ const uint32_t event_type = event_sp->GetType();
+ if (event_sp->BroadcasterIs (&process->m_async_broadcaster))
+ {
+ if (log)
+ log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) Got an event of type: %d...", __FUNCTION__, arg, process->GetID(), event_type);
+
+ switch (event_type)
+ {
+ case eBroadcastBitAsyncContinue:
+ {
+ const EventDataBytes *continue_packet = EventDataBytes::GetEventDataFromEvent(event_sp.get());
+
+ if (continue_packet)
+ {
+ // TODO: do continue support here
+
+// const char *continue_cstr = (const char *)continue_packet->GetBytes ();
+// const size_t continue_cstr_len = continue_packet->GetByteSize ();
+// if (log)
+// log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) got eBroadcastBitAsyncContinue: %s", __FUNCTION__, arg, process->GetID(), continue_cstr);
+//
+// if (::strstr (continue_cstr, "vAttach") == NULL)
+// process->SetPrivateState(eStateRunning);
+// StringExtractor response;
+// StateType stop_state = process->GetCommunication().SendContinuePacketAndWaitForResponse (process, continue_cstr, continue_cstr_len, response);
+//
+// switch (stop_state)
+// {
+// case eStateStopped:
+// case eStateCrashed:
+// case eStateSuspended:
+// process->m_last_stop_packet = response;
+// process->SetPrivateState (stop_state);
+// break;
+//
+// case eStateExited:
+// process->m_last_stop_packet = response;
+// response.SetFilePos(1);
+// process->SetExitStatus(response.GetHexU8(), NULL);
+// done = true;
+// break;
+//
+// case eStateInvalid:
+// process->SetExitStatus(-1, "lost connection");
+// break;
+//
+// default:
+// process->SetPrivateState (stop_state);
+// break;
+// }
+ }
+ }
+ break;
+
+ case eBroadcastBitAsyncThreadShouldExit:
+ if (log)
+ log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) got eBroadcastBitAsyncThreadShouldExit...", __FUNCTION__, arg, process->GetID());
+ done = true;
+ break;
+
+ default:
+ if (log)
+ log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) got unknown event 0x%8.8x", __FUNCTION__, arg, process->GetID(), event_type);
+ done = true;
+ break;
+ }
+ }
+ else if (event_sp->BroadcasterIs (&process->m_comm))
+ {
+ if (event_type & Communication::eBroadcastBitReadThreadDidExit)
+ {
+ process->SetExitStatus (-1, "lost connection");
+ done = true;
+ }
+ }
+ }
+ else
+ {
+ if (log)
+ log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) listener.WaitForEvent (NULL, event_sp) => false", __FUNCTION__, arg, process->GetID());
+ done = true;
+ }
+ }
+ }
+
+ if (log)
+ log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) thread exiting...", __FUNCTION__, arg, process->GetID());
+
+ process->m_async_thread = LLDB_INVALID_HOST_THREAD;
+ return NULL;
+}
+
+
Added: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h?rev=135240&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h (added)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h Thu Jul 14 22:27:12 2011
@@ -0,0 +1,283 @@
+//===-- ProcessKDP.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ProcessKDP_h_
+#define liblldb_ProcessKDP_h_
+
+// C Includes
+
+// C++ Includes
+#include
+#include
+
+// Other libraries and framework includes
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/Broadcaster.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/InputReader.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Core/StringList.h"
+#include "lldb/Core/ThreadSafeValue.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Thread.h"
+
+#include "CommunicationKDP.h"
+#include "Utility/StringExtractor.h"
+
+class ThreadKDP;
+
+class ProcessKDP : public lldb_private::Process
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ static Process*
+ CreateInstance (lldb_private::Target& target, lldb_private::Listener &listener);
+
+ static void
+ Initialize();
+
+ static void
+ Terminate();
+
+ static const char *
+ GetPluginNameStatic();
+
+ static const char *
+ GetPluginDescriptionStatic();
+
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ ProcessKDP(lldb_private::Target& target, lldb_private::Listener &listener);
+
+ virtual
+ ~ProcessKDP();
+
+ //------------------------------------------------------------------
+ // Check if a given Process
+ //------------------------------------------------------------------
+ virtual bool
+ CanDebug (lldb_private::Target &target);
+
+ // virtual uint32_t
+ // ListProcessesMatchingName (const char *name, lldb_private::StringList &matches, std::vector &pids);
+
+ //------------------------------------------------------------------
+ // Creating a new process, or attaching to an existing one
+ //------------------------------------------------------------------
+ virtual lldb_private::Error
+ WillLaunch (lldb_private::Module* module);
+
+ virtual lldb_private::Error
+ DoLaunch (lldb_private::Module* module,
+ char const *argv[], // Can be NULL
+ char const *envp[], // Can be NULL
+ uint32_t flags,
+ const char *stdin_path, // Can be NULL
+ const char *stdout_path, // Can be NULL
+ const char *stderr_path, // Can be NULL
+ const char *working_dir); // Can be NULL
+
+ virtual lldb_private::Error
+ WillAttachToProcessWithID (lldb::pid_t pid);
+
+ virtual lldb_private::Error
+ WillAttachToProcessWithName (const char *process_name, bool wait_for_launch);
+
+ virtual lldb_private::Error
+ DoConnectRemote (const char *remote_url);
+
+ virtual lldb_private::Error
+ DoAttachToProcessWithID (lldb::pid_t pid);
+
+ virtual lldb_private::Error
+ DoAttachToProcessWithName (const char *process_name, bool wait_for_launch);
+
+ virtual void
+ DidAttach ();
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ virtual const char *
+ GetPluginName();
+
+ virtual const char *
+ GetShortPluginName();
+
+ virtual uint32_t
+ GetPluginVersion();
+
+ //------------------------------------------------------------------
+ // Process Control
+ //------------------------------------------------------------------
+ virtual lldb_private::Error
+ WillResume ();
+
+ virtual lldb_private::Error
+ DoResume ();
+
+ virtual lldb_private::Error
+ DoHalt (bool &caused_stop);
+
+ virtual lldb_private::Error
+ WillDetach ();
+
+ virtual lldb_private::Error
+ DoDetach ();
+
+ virtual lldb_private::Error
+ DoSignal (int signal);
+
+ virtual lldb_private::Error
+ DoDestroy ();
+
+ virtual void
+ RefreshStateAfterStop();
+
+ //------------------------------------------------------------------
+ // Process Queries
+ //------------------------------------------------------------------
+ virtual bool
+ IsAlive ();
+
+ //------------------------------------------------------------------
+ // Process Memory
+ //------------------------------------------------------------------
+ virtual size_t
+ DoReadMemory (lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error);
+
+ virtual size_t
+ DoWriteMemory (lldb::addr_t addr, const void *buf, size_t size, lldb_private::Error &error);
+
+ virtual lldb::addr_t
+ DoAllocateMemory (size_t size, uint32_t permissions, lldb_private::Error &error);
+
+ virtual lldb_private::Error
+ DoDeallocateMemory (lldb::addr_t ptr);
+
+ //----------------------------------------------------------------------
+ // Process Breakpoints
+ //----------------------------------------------------------------------
+ virtual lldb_private::Error
+ EnableBreakpoint (lldb_private::BreakpointSite *bp_site);
+
+ virtual lldb_private::Error
+ DisableBreakpoint (lldb_private::BreakpointSite *bp_site);
+
+ //----------------------------------------------------------------------
+ // Process Watchpoints
+ //----------------------------------------------------------------------
+ virtual lldb_private::Error
+ EnableWatchpoint (lldb_private::WatchpointLocation *wp_loc);
+
+ virtual lldb_private::Error
+ DisableWatchpoint (lldb_private::WatchpointLocation *wp_loc);
+
+protected:
+ friend class ThreadKDP;
+ friend class CommunicationKDP;
+
+ //----------------------------------------------------------------------
+ // Accessors
+ //----------------------------------------------------------------------
+ bool
+ IsRunning ( lldb::StateType state )
+ {
+ return state == lldb::eStateRunning || IsStepping(state);
+ }
+
+ bool
+ IsStepping ( lldb::StateType state)
+ {
+ return state == lldb::eStateStepping;
+ }
+
+ bool
+ CanResume ( lldb::StateType state)
+ {
+ return state == lldb::eStateStopped;
+ }
+
+ bool
+ HasExited (lldb::StateType state)
+ {
+ return state == lldb::eStateExited;
+ }
+
+ bool
+ ProcessIDIsValid ( ) const;
+
+ // static void
+ // STDIOReadThreadBytesReceived (void *baton, const void *src, size_t src_len);
+
+ // void
+ // AppendSTDOUT (const char* s, size_t len);
+
+ void
+ Clear ( );
+
+ uint32_t
+ UpdateThreadListIfNeeded ();
+
+ CommunicationKDP &
+ GetCommunication()
+ {
+ return m_comm;
+ }
+
+ enum
+ {
+ eBroadcastBitAsyncContinue = (1 << 0),
+ eBroadcastBitAsyncThreadShouldExit = (1 << 1)
+ };
+
+ lldb_private::Error
+ InterruptIfRunning (bool discard_thread_plans,
+ bool catch_stop_event,
+ lldb::EventSP &stop_event_sp);
+
+ //------------------------------------------------------------------
+ /// Broadcaster event bits definitions.
+ //------------------------------------------------------------------
+ CommunicationKDP m_comm;
+ lldb_private::Broadcaster m_async_broadcaster;
+ lldb::thread_t m_async_thread;
+
+ bool
+ StartAsyncThread ();
+
+ void
+ StopAsyncThread ();
+
+ static void *
+ AsyncThread (void *arg);
+
+ lldb::StateType
+ SetThreadStopInfo (StringExtractor& stop_packet);
+
+ static size_t
+ AttachInputReaderCallback (void *baton,
+ lldb_private::InputReader *reader,
+ lldb::InputReaderAction notification,
+ const char *bytes,
+ size_t bytes_len);
+
+private:
+ //------------------------------------------------------------------
+ // For ProcessKDP only
+ //------------------------------------------------------------------
+
+ DISALLOW_COPY_AND_ASSIGN (ProcessKDP);
+
+};
+
+#endif // liblldb_ProcessKDP_h_
Added: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp?rev=135240&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp (added)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp Thu Jul 14 22:27:12 2011
@@ -0,0 +1,183 @@
+//===-- ProcessKDPLog.cpp ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ProcessKDPLog.h"
+
+#include "lldb/Interpreter/Args.h"
+#include "lldb/Core/StreamFile.h"
+
+#include "ProcessKDP.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+
+// We want to avoid global constructors where code needs to be run so here we
+// control access to our static g_log_sp by hiding it in a singleton function
+// that will construct the static g_lob_sp the first time this function is
+// called.
+static LogSP &
+GetLog ()
+{
+ static LogSP g_log_sp;
+ return g_log_sp;
+}
+
+LogSP
+ProcessKDPLog::GetLogIfAllCategoriesSet (uint32_t mask)
+{
+ LogSP log(GetLog ());
+ if (log && mask)
+ {
+ uint32_t log_mask = log->GetMask().Get();
+ if ((log_mask & mask) != mask)
+ return LogSP();
+ }
+ return log;
+}
+
+void
+ProcessKDPLog::DisableLog (Args &args, Stream *feedback_strm)
+{
+ LogSP log (GetLog ());
+ if (log)
+ {
+ uint32_t flag_bits = 0;
+
+ const size_t argc = args.GetArgumentCount ();
+ if (argc > 0)
+ {
+ flag_bits = log->GetMask().Get();
+ for (size_t i = 0; i < argc; ++i)
+ {
+ const char *arg = args.GetArgumentAtIndex (i);
+
+
+ if (::strcasecmp (arg, "all") == 0 ) flag_bits &= ~KDP_LOG_ALL;
+ else if (::strcasecmp (arg, "async") == 0 ) flag_bits &= ~KDP_LOG_ASYNC;
+ else if (::strncasecmp (arg, "break", 5) == 0 ) flag_bits &= ~KDP_LOG_BREAKPOINTS;
+ else if (::strncasecmp (arg, "comm", 4) == 0 ) flag_bits &= ~KDP_LOG_COMM;
+ else if (::strcasecmp (arg, "default") == 0 ) flag_bits &= ~KDP_LOG_DEFAULT;
+ else if (::strcasecmp (arg, "packets") == 0 ) flag_bits &= ~KDP_LOG_PACKETS;
+ else if (::strcasecmp (arg, "memory") == 0 ) flag_bits &= ~KDP_LOG_MEMORY;
+ else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits &= ~KDP_LOG_MEMORY_DATA_SHORT;
+ else if (::strcasecmp (arg, "data-long") == 0 ) flag_bits &= ~KDP_LOG_MEMORY_DATA_LONG;
+ else if (::strcasecmp (arg, "process") == 0 ) flag_bits &= ~KDP_LOG_PROCESS;
+ else if (::strcasecmp (arg, "step") == 0 ) flag_bits &= ~KDP_LOG_STEP;
+ else if (::strcasecmp (arg, "thread") == 0 ) flag_bits &= ~KDP_LOG_THREAD;
+ else if (::strcasecmp (arg, "verbose") == 0 ) flag_bits &= ~KDP_LOG_VERBOSE;
+ else if (::strncasecmp (arg, "watch", 5) == 0 ) flag_bits &= ~KDP_LOG_WATCHPOINTS;
+ else
+ {
+ feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
+ ListLogCategories (feedback_strm);
+ }
+
+ }
+ }
+
+ if (flag_bits == 0)
+ GetLog ().reset();
+ else
+ log->GetMask().Reset (flag_bits);
+ }
+
+ return;
+}
+
+LogSP
+ProcessKDPLog::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, Args &args, Stream *feedback_strm)
+{
+ // Try see if there already is a log - that way we can reuse its settings.
+ // We could reuse the log in toto, but we don't know that the stream is the same.
+ uint32_t flag_bits = 0;
+ LogSP log(GetLog ());
+ if (log)
+ flag_bits = log->GetMask().Get();
+
+ // Now make a new log with this stream if one was provided
+ if (log_stream_sp)
+ {
+ log = make_shared(log_stream_sp);
+ GetLog () = log;
+ }
+
+ if (log)
+ {
+ bool got_unknown_category = false;
+ const size_t argc = args.GetArgumentCount();
+ for (size_t i=0; iPrintf("error: unrecognized log category '%s'\n", arg);
+ if (got_unknown_category == false)
+ {
+ got_unknown_category = true;
+ ListLogCategories (feedback_strm);
+ }
+ }
+ }
+ if (flag_bits == 0)
+ flag_bits = KDP_LOG_DEFAULT;
+ log->GetMask().Reset(flag_bits);
+ log->GetOptions().Reset(log_options);
+ }
+ return log;
+}
+
+void
+ProcessKDPLog::ListLogCategories (Stream *strm)
+{
+ strm->Printf("Logging categories for '%s':\n"
+ "\tall - turn on all available logging categories\n"
+ "\tasync - log asynchronous activity\n"
+ "\tbreak - log breakpoints\n"
+ "\tcommunication - log communication activity\n"
+ "\tdefault - enable the default set of logging categories for liblldb\n"
+ "\tpackets - log gdb remote packets\n"
+ "\tmemory - log memory reads and writes\n"
+ "\tdata-short - log memory bytes for memory reads and writes for short transactions only\n"
+ "\tdata-long - log memory bytes for memory reads and writes for all transactions\n"
+ "\tprocess - log process events and activities\n"
+ "\tthread - log thread events and activities\n"
+ "\tstep - log step related activities\n"
+ "\tverbose - enable verbose logging\n"
+ "\twatch - log watchpoint related activities\n", ProcessKDP::GetPluginNameStatic());
+}
+
+
+void
+ProcessKDPLog::LogIf (uint32_t mask, const char *format, ...)
+{
+ LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (mask));
+ if (log)
+ {
+ va_list args;
+ va_start (args, format);
+ log->VAPrintf (format, args);
+ va_end (args);
+ }
+}
Added: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h?rev=135240&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h (added)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h Thu Jul 14 22:27:12 2011
@@ -0,0 +1,54 @@
+//===-- ProcessKDPLog.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ProcessKDPLog_h_
+#define liblldb_ProcessKDPLog_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+
+// Project includes
+#include "lldb/Core/Log.h"
+
+#define KDP_LOG_VERBOSE (1u << 0)
+#define KDP_LOG_PROCESS (1u << 1)
+#define KDP_LOG_THREAD (1u << 2)
+#define KDP_LOG_PACKETS (1u << 3)
+#define KDP_LOG_MEMORY (1u << 4) // Log memory reads/writes calls
+#define KDP_LOG_MEMORY_DATA_SHORT (1u << 5) // Log short memory reads/writes bytes
+#define KDP_LOG_MEMORY_DATA_LONG (1u << 6) // Log all memory reads/writes bytes
+#define KDP_LOG_BREAKPOINTS (1u << 7)
+#define KDP_LOG_WATCHPOINTS (1u << 8)
+#define KDP_LOG_STEP (1u << 9)
+#define KDP_LOG_COMM (1u << 10)
+#define KDP_LOG_ASYNC (1u << 11)
+#define KDP_LOG_ALL (UINT32_MAX)
+#define KDP_LOG_DEFAULT KDP_LOG_PACKETS
+
+class ProcessKDPLog
+{
+public:
+ static lldb::LogSP
+ GetLogIfAllCategoriesSet(uint32_t mask = 0);
+
+ static void
+ DisableLog (lldb_private::Args &args, lldb_private::Stream *feedback_strm);
+
+ static lldb::LogSP
+ EnableLog (lldb::StreamSP &log_stream_sp, uint32_t log_options, lldb_private::Args &args, lldb_private::Stream *feedback_strm);
+
+ static void
+ ListLogCategories (lldb_private::Stream *strm);
+
+ static void
+ LogIf (uint32_t mask, const char *format, ...);
+};
+
+#endif // liblldb_ProcessKDPLog_h_
From gclayton at apple.com Fri Jul 15 11:31:38 2011
From: gclayton at apple.com (Greg Clayton)
Date: Fri, 15 Jul 2011 16:31:38 -0000
Subject: [Lldb-commits] [lldb] r135277 - in /lldb/trunk:
include/lldb/Core/ConnectionFileDescriptor.h lldb.xcodeproj/project.pbxproj
source/Core/ConnectionFileDescriptor.cpp
source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
Message-ID: <20110715163139.122902A6C12C@llvm.org>
Author: gclayton
Date: Fri Jul 15 11:31:38 2011
New Revision: 135277
URL: http://llvm.org/viewvc/llvm-project?rev=135277&view=rev
Log:
Added the ability to connect using "tcp://:" which is the
same as the old "connect://:". Also added the ability to
connect using "udp://:" which will open a connected
datagram socket. I need to find a way to specify a non connected
datagram socket as well.
We might need to start setting some settings in the URL itself,
maybe something like:
udp://:?connected=yes
udp://:?connected=no
I am open to suggestions for URL settings.
Also did more work on the KDP darwin kernel plug-in.
Modified:
lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h
lldb/trunk/lldb.xcodeproj/project.pbxproj
lldb/trunk/source/Core/ConnectionFileDescriptor.cpp
lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
Modified: lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h?rev=135277&r1=135276&r2=135277&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h (original)
+++ lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h Fri Jul 15 11:31:38 2011
@@ -61,8 +61,11 @@
SocketListen (uint16_t listen_port_num, Error *error_ptr);
lldb::ConnectionStatus
- SocketConnect (const char *host_and_port, Error *error_ptr);
-
+ ConnectTCP (const char *host_and_port, Error *error_ptr);
+
+ lldb::ConnectionStatus
+ ConnectUDP (const char *host_and_port, Error *error_ptr);
+
lldb::ConnectionStatus
NamedSocketAccept (const char *socket_name, Error *error_ptr);
Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=135277&r1=135276&r2=135277&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Fri Jul 15 11:31:38 2011
@@ -16,6 +16,12 @@
26368A3C126B697600E8659F /* darwin-debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26368A3B126B697600E8659F /* darwin-debug.cpp */; };
26368AF7126B960500E8659F /* darwin-debug in Resources */ = {isa = PBXBuildFile; fileRef = 26579F68126A25920007C5CB /* darwin-debug */; };
263E949F13661AEA00E7D1CE /* UnwindAssembly-x86.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 263E949D13661AE400E7D1CE /* UnwindAssembly-x86.cpp */; };
+ 2642FBAE13D003B400ED6808 /* CommunicationKDP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2642FBA813D003B400ED6808 /* CommunicationKDP.cpp */; };
+ 2642FBAF13D003B400ED6808 /* CommunicationKDP.h in Headers */ = {isa = PBXBuildFile; fileRef = 2642FBA913D003B400ED6808 /* CommunicationKDP.h */; };
+ 2642FBB013D003B400ED6808 /* ProcessKDP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2642FBAA13D003B400ED6808 /* ProcessKDP.cpp */; };
+ 2642FBB113D003B400ED6808 /* ProcessKDP.h in Headers */ = {isa = PBXBuildFile; fileRef = 2642FBAB13D003B400ED6808 /* ProcessKDP.h */; };
+ 2642FBB213D003B400ED6808 /* ProcessKDPLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2642FBAC13D003B400ED6808 /* ProcessKDPLog.cpp */; };
+ 2642FBB313D003B400ED6808 /* ProcessKDPLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 2642FBAD13D003B400ED6808 /* ProcessKDPLog.h */; };
264A97BF133918BC0017F0BE /* PlatformRemoteGDBServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 264A97BD133918BC0017F0BE /* PlatformRemoteGDBServer.cpp */; };
264D8D5013661BD7003A368F /* UnwindAssembly.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 264D8D4F13661BD7003A368F /* UnwindAssembly.cpp */; };
265ABF6310F42EE900531910 /* DebugSymbols.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 265ABF6210F42EE900531910 /* DebugSymbols.framework */; };
@@ -640,6 +646,12 @@
263FEDA5112CC1DA00E4C208 /* ThreadSafeSTLMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadSafeSTLMap.h; path = include/lldb/Core/ThreadSafeSTLMap.h; sourceTree = ""; };
26424E3C125986CB0016D82C /* ValueObjectConstResult.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectConstResult.cpp; path = source/Core/ValueObjectConstResult.cpp; sourceTree = ""; };
26424E3E125986D30016D82C /* ValueObjectConstResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ValueObjectConstResult.h; path = include/lldb/Core/ValueObjectConstResult.h; sourceTree = ""; };
+ 2642FBA813D003B400ED6808 /* CommunicationKDP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CommunicationKDP.cpp; sourceTree = ""; };
+ 2642FBA913D003B400ED6808 /* CommunicationKDP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommunicationKDP.h; sourceTree = ""; };
+ 2642FBAA13D003B400ED6808 /* ProcessKDP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProcessKDP.cpp; sourceTree = ""; };
+ 2642FBAB13D003B400ED6808 /* ProcessKDP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProcessKDP.h; sourceTree = ""; };
+ 2642FBAC13D003B400ED6808 /* ProcessKDPLog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProcessKDPLog.cpp; sourceTree = ""; };
+ 2642FBAD13D003B400ED6808 /* ProcessKDPLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProcessKDPLog.h; sourceTree = ""; };
264334381110F63100CDB6C6 /* ValueObjectRegister.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectRegister.cpp; path = source/Core/ValueObjectRegister.cpp; sourceTree = ""; };
2643343A1110F63C00CDB6C6 /* ValueObjectRegister.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ValueObjectRegister.h; path = include/lldb/Core/ValueObjectRegister.h; sourceTree = ""; };
264723A511FA076E00DE380C /* CleanUp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CleanUp.h; path = include/lldb/Utility/CleanUp.h; sourceTree = ""; };
@@ -1483,6 +1495,7 @@
isa = PBXGroup;
children = (
4CEE62F71145F1C70064CF93 /* GDB Remote */,
+ 2642FBA713D003B400ED6808 /* MacOSX-Kernel */,
260C898B10F57C5600BB2B04 /* MacOSX-User */,
26B4666E11A2080F00CF6220 /* Utility */,
);
@@ -1723,6 +1736,19 @@
name = API;
sourceTree = "";
};
+ 2642FBA713D003B400ED6808 /* MacOSX-Kernel */ = {
+ isa = PBXGroup;
+ children = (
+ 2642FBA813D003B400ED6808 /* CommunicationKDP.cpp */,
+ 2642FBA913D003B400ED6808 /* CommunicationKDP.h */,
+ 2642FBAA13D003B400ED6808 /* ProcessKDP.cpp */,
+ 2642FBAB13D003B400ED6808 /* ProcessKDP.h */,
+ 2642FBAC13D003B400ED6808 /* ProcessKDPLog.cpp */,
+ 2642FBAD13D003B400ED6808 /* ProcessKDPLog.h */,
+ );
+ path = "MacOSX-Kernel";
+ sourceTree = "";
+ };
264A97BC133918A30017F0BE /* GDB Server */ = {
isa = PBXGroup;
children = (
@@ -2686,6 +2712,9 @@
buildActionMask = 2147483647;
files = (
9A9E1F0113980943005AC039 /* InputReaderStack.h in Headers */,
+ 2642FBAF13D003B400ED6808 /* CommunicationKDP.h in Headers */,
+ 2642FBB113D003B400ED6808 /* ProcessKDP.h in Headers */,
+ 2642FBB313D003B400ED6808 /* ProcessKDPLog.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -3279,6 +3308,9 @@
26F4214413C6515B00E04E5E /* DynamicLoaderMacOSXKernel.cpp in Sources */,
94611EB213CCA4A4003A22AF /* RefCounter.cpp in Sources */,
94031A9E13CF486700DCFF3C /* InputReaderEZ.cpp in Sources */,
+ 2642FBAE13D003B400ED6808 /* CommunicationKDP.cpp in Sources */,
+ 2642FBB013D003B400ED6808 /* ProcessKDP.cpp in Sources */,
+ 2642FBB213D003B400ED6808 /* ProcessKDPLog.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Modified: lldb/trunk/source/Core/ConnectionFileDescriptor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ConnectionFileDescriptor.cpp?rev=135277&r1=135276&r2=135277&view=diff
==============================================================================
--- lldb/trunk/source/Core/ConnectionFileDescriptor.cpp (original)
+++ lldb/trunk/source/Core/ConnectionFileDescriptor.cpp Fri Jul 15 11:31:38 2011
@@ -97,7 +97,15 @@
}
else if (strstr(s, "connect://"))
{
- return SocketConnect (s + strlen("connect://"), error_ptr);
+ return ConnectTCP (s + strlen("connect://"), error_ptr);
+ }
+ else if (strstr(s, "tcp://"))
+ {
+ return ConnectTCP (s + strlen("tcp://"), error_ptr);
+ }
+ else if (strstr(s, "udp://"))
+ {
+ return ConnectUDP (s + strlen("udp://"), error_ptr);
}
else if (strstr(s, "fd://"))
{
@@ -626,10 +634,10 @@
}
ConnectionStatus
-ConnectionFileDescriptor::SocketConnect (const char *host_and_port, Error *error_ptr)
+ConnectionFileDescriptor::ConnectTCP (const char *host_and_port, Error *error_ptr)
{
lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION,
- "%p ConnectionFileDescriptor::SocketConnect (host/port = %s)",
+ "%p ConnectionFileDescriptor::ConnectTCP (host/port = %s)",
this, host_and_port);
Close (m_fd, NULL);
m_is_socket = true;
@@ -715,6 +723,96 @@
return eConnectionStatusSuccess;
}
+ConnectionStatus
+ConnectionFileDescriptor::ConnectUDP (const char *host_and_port, Error *error_ptr)
+{
+ lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION,
+ "%p ConnectionFileDescriptor::ConnectUDP (host/port = %s)",
+ this, host_and_port);
+ Close (m_fd, NULL);
+ m_is_socket = true;
+
+ RegularExpression regex ("([^:]+):([0-9]+)");
+ if (regex.Execute (host_and_port, 2) == false)
+ {
+ if (error_ptr)
+ error_ptr->SetErrorStringWithFormat("invalid host:port specification: '%s'", host_and_port);
+ return eConnectionStatusError;
+ }
+ std::string host_str;
+ std::string port_str;
+ if (regex.GetMatchAtIndex (host_and_port, 1, host_str) == false ||
+ regex.GetMatchAtIndex (host_and_port, 2, port_str) == false)
+ {
+ if (error_ptr)
+ error_ptr->SetErrorStringWithFormat("invalid host:port specification '%s'", host_and_port);
+ return eConnectionStatusError;
+ }
+
+ int32_t port = Args::StringToSInt32 (port_str.c_str(), INT32_MIN);
+ if (port == INT32_MIN)
+ {
+ if (error_ptr)
+ error_ptr->SetErrorStringWithFormat("invalid port '%s'", port_str.c_str());
+ return eConnectionStatusError;
+ }
+ // Create the socket
+ m_fd = ::socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (m_fd == -1)
+ {
+ if (error_ptr)
+ error_ptr->SetErrorToErrno();
+ return eConnectionStatusError;
+ }
+
+ m_should_close_fd = true;
+
+ // Enable local address reuse
+ SetSocketOption (m_fd, SOL_SOCKET, SO_REUSEADDR, 1);
+
+ struct sockaddr_in sa;
+ ::memset (&sa, 0, sizeof (sa));
+ sa.sin_family = AF_INET;
+ sa.sin_port = htons (port);
+
+ int inet_pton_result = ::inet_pton (AF_INET, host_str.c_str(), &sa.sin_addr);
+
+ if (inet_pton_result <= 0)
+ {
+ struct hostent *host_entry = gethostbyname (host_str.c_str());
+ if (host_entry)
+ host_str = ::inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list);
+ inet_pton_result = ::inet_pton (AF_INET, host_str.c_str(), &sa.sin_addr);
+ if (inet_pton_result <= 0)
+ {
+
+ if (error_ptr)
+ {
+ if (inet_pton_result == -1)
+ error_ptr->SetErrorToErrno();
+ else
+ error_ptr->SetErrorStringWithFormat("invalid host string: '%s'", host_str.c_str());
+ }
+ Close (m_fd, NULL);
+ return eConnectionStatusError;
+ }
+ }
+
+ if (-1 == ::connect (m_fd, (const struct sockaddr *)&sa, sizeof(sa)))
+ {
+ if (error_ptr)
+ error_ptr->SetErrorToErrno();
+ Close (m_fd, NULL);
+ return eConnectionStatusError;
+ }
+
+ // Keep our TCP packets coming without any delays.
+ SetSocketOption (m_fd, IPPROTO_TCP, TCP_NODELAY, 1);
+ if (error_ptr)
+ error_ptr->Clear();
+ return eConnectionStatusSuccess;
+}
+
#if defined(__MINGW32__) || defined(__MINGW64__)
typedef const char * set_socket_option_arg_type;
typedef char * get_socket_option_arg_type;
Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp?rev=135277&r1=135276&r2=135277&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp Fri Jul 15 11:31:38 2011
@@ -16,6 +16,7 @@
// C++ Includes
// Other libraries and framework includes
+#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Host/FileSpec.h"
@@ -41,7 +42,9 @@
m_sequence_mutex (Mutex::eMutexTypeRecursive),
m_public_is_running (false),
m_private_is_running (false),
- m_send_acks (true)
+ m_session_key (0),
+ m_request_sequence_id (0),
+ m_exception_sequence_id (0)
{
}
@@ -56,110 +59,68 @@
}
}
-char
-CommunicationKDP::CalculcateChecksum (const char *payload, size_t payload_length)
-{
- int checksum = 0;
-
- // We only need to compute the checksum if we are sending acks
- if (GetSendAcks ())
- {
- for (size_t i = 0; i < payload_length; ++i)
- checksum += payload[i];
- }
- return checksum & 255;
-}
-
-size_t
-CommunicationKDP::SendAck ()
-{
- LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
- if (log)
- log->Printf ("send packet: +");
- ConnectionStatus status = eConnectionStatusSuccess;
- char ack_char = '+';
- return Write (&ack_char, 1, status, NULL);
-}
-
-size_t
-CommunicationKDP::SendNack ()
-{
- LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
- if (log)
- log->Printf ("send packet: -");
- ConnectionStatus status = eConnectionStatusSuccess;
- char nack_char = '-';
- return Write (&nack_char, 1, status, NULL);
-}
-
-size_t
-CommunicationKDP::SendPacket (lldb_private::StreamString &payload)
+bool
+CommunicationKDP::SendRequestPacket (const StreamString &request_packet)
{
Mutex::Locker locker(m_sequence_mutex);
- const std::string &p (payload.GetString());
- return SendPacketNoLock (p.c_str(), p.size());
+ return SendRequestPacketNoLock (request_packet);
}
-size_t
-CommunicationKDP::SendPacket (const char *payload)
-{
- Mutex::Locker locker(m_sequence_mutex);
- return SendPacketNoLock (payload, ::strlen (payload));
+void
+CommunicationKDP::MakeRequestPacketHeader (RequestType request_type,
+ StreamString &request_packet)
+{
+ request_packet.Clear();
+ request_packet.PutHex32 (request_type); // Set the request type
+ request_packet.PutHex8 (ePacketTypeRequest); // Set the packet type
+ request_packet.PutHex8 (++m_request_sequence_id); // Sequence number
+ request_packet.PutHex16 (0); // Pad1 and Pad2 bytes
+ request_packet.PutHex32 (m_session_key); // Session key
}
-size_t
-CommunicationKDP::SendPacket (const char *payload, size_t payload_length)
-{
- Mutex::Locker locker(m_sequence_mutex);
- return SendPacketNoLock (payload, payload_length);
-}
-size_t
-CommunicationKDP::SendPacketNoLock (const char *payload, size_t payload_length)
+bool
+CommunicationKDP::SendRequestPacketNoLock (const StreamString &request_packet)
{
if (IsConnected())
{
- StreamString packet(0, 4, eByteOrderBig);
-
- packet.PutChar('$');
- packet.Write (payload, payload_length);
- packet.PutChar('#');
- packet.PutHex8(CalculcateChecksum (payload, payload_length));
+ const char *packet_data = request_packet.GetData();
+ const size_t packet_size = request_packet.GetSize();
LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
if (log)
- log->Printf ("send packet: %.*s", (int)packet.GetSize(), packet.GetData());
- ConnectionStatus status = eConnectionStatusSuccess;
- size_t bytes_written = Write (packet.GetData(), packet.GetSize(), status, NULL);
- if (bytes_written == packet.GetSize())
- {
- if (GetSendAcks ())
- {
- if (GetAck () != '+')
- {
- printf("get ack failed...");
- return 0;
- }
- }
- }
- else
{
- LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
- if (log)
- log->Printf ("error: failed to send packet: %.*s", (int)packet.GetSize(), packet.GetData());
+ StreamString log_strm;
+ DataExtractor data (packet_data,
+ packet_size,
+ request_packet.GetByteOrder(),
+ request_packet.GetAddressByteSize());
+ data.Dump (&log_strm,
+ 0,
+ eFormatBytes,
+ 1,
+ packet_size,
+ 32, // Num bytes per line
+ 0, // Base address
+ 0,
+ 0);
+
+ log->Printf("request packet: <%u>\n%s", packet_size, log_strm.GetString().c_str());
}
- return bytes_written;
- }
- return 0;
-}
+ ConnectionStatus status = eConnectionStatusSuccess;
-char
-CommunicationKDP::GetAck ()
-{
- StringExtractor packet;
- if (WaitForPacketWithTimeoutMicroSeconds (packet, GetPacketTimeoutInMicroSeconds ()) == 1)
- return packet.GetChar();
- return 0;
+ size_t bytes_written = Write (packet_data,
+ packet_size,
+ status,
+ NULL);
+
+ if (bytes_written == packet_size)
+ return true;
+
+ if (log)
+ log->Printf ("error: failed to send packet entire packet %zu of %zu bytes sent", bytes_written, packet_size);
+ }
+ return false;
}
bool
@@ -262,142 +223,30 @@
// Parse up the packets into gdb remote packets
if (!m_bytes.empty())
{
- // end_idx must be one past the last valid packet byte. Start
- // it off with an invalid value that is the same as the current
- // index.
- size_t content_start = 0;
- size_t content_length = 0;
- size_t total_length = 0;
- size_t checksum_idx = std::string::npos;
-
- switch (m_bytes[0])
- {
- case '+': // Look for ack
- case '-': // Look for cancel
- case '\x03': // ^C to halt target
- content_length = total_length = 1; // The command is one byte long...
- break;
-
- case '$':
- // Look for a standard gdb packet?
- {
- size_t hash_pos = m_bytes.find('#');
- if (hash_pos != std::string::npos)
- {
- if (hash_pos + 2 < m_bytes.size())
- {
- checksum_idx = hash_pos + 1;
- // Skip the dollar sign
- content_start = 1;
- // Don't include the # in the content or the $ in the content length
- content_length = hash_pos - 1;
-
- total_length = hash_pos + 3; // Skip the # and the two hex checksum bytes
- }
- else
- {
- // Checksum bytes aren't all here yet
- content_length = std::string::npos;
- }
- }
- }
- break;
-
- default:
- {
- // We have an unexpected byte and we need to flush all bad
- // data that is in m_bytes, so we need to find the first
- // byte that is a '+' (ACK), '-' (NACK), \x03 (CTRL+C interrupt),
- // or '$' character (start of packet header) or of course,
- // the end of the data in m_bytes...
- const size_t bytes_len = m_bytes.size();
- bool done = false;
- uint32_t idx;
- for (idx = 1; !done && idx < bytes_len; ++idx)
- {
- switch (m_bytes[idx])
- {
- case '+':
- case '-':
- case '\x03':
- case '$':
- done = true;
- break;
-
- default:
- break;
- }
- }
- if (log)
- log->Printf ("CommunicationKDP::%s tossing %u junk bytes: '%.*s'",
- __FUNCTION__, idx, idx, m_bytes.c_str());
- m_bytes.erase(0, idx);
- }
- break;
- }
-
- if (content_length == std::string::npos)
- {
- packet.Clear();
- return false;
- }
- else if (total_length > 0)
- {
-
- // We have a valid packet...
- assert (content_length <= m_bytes.size());
- assert (total_length <= m_bytes.size());
- assert (content_length <= total_length);
-
- bool success = true;
- std::string &packet_str = packet.GetStringRef();
- packet_str.assign (m_bytes, content_start, content_length);
- if (m_bytes[0] == '$')
- {
- assert (checksum_idx < m_bytes.size());
- if (::isxdigit (m_bytes[checksum_idx+0]) ||
- ::isxdigit (m_bytes[checksum_idx+1]))
- {
- if (GetSendAcks ())
- {
- const char *packet_checksum_cstr = &m_bytes[checksum_idx];
- char packet_checksum = strtol (packet_checksum_cstr, NULL, 16);
- char actual_checksum = CalculcateChecksum (packet_str.c_str(), packet_str.size());
- success = packet_checksum == actual_checksum;
- if (!success)
- {
- if (log)
- log->Printf ("error: checksum mismatch: %.*s expected 0x%2.2x, got 0x%2.2x",
- (int)(total_length),
- m_bytes.c_str(),
- (uint8_t)packet_checksum,
- (uint8_t)actual_checksum);
- }
- // Send the ack or nack if needed
- if (!success)
- SendNack();
- else
- SendAck();
- }
- if (success)
- {
- if (log)
- log->Printf ("read packet: %.*s", (int)(total_length), m_bytes.c_str());
- }
- }
- else
- {
- success = false;
- if (log)
- log->Printf ("error: invalid checksum in packet: '%s'\n", (int)(total_length), m_bytes.c_str());
- }
- }
- m_bytes.erase(0, total_length);
- packet.SetFilePos(0);
- return success;
- }
+ // TODO: Figure out if we have a full packet reply
}
packet.Clear();
return false;
}
+
+CommunicationKDP::ErrorType
+CommunicationKDP::Connect (uint16_t reply_port,
+ uint16_t exc_port,
+ const char *greeting)
+{
+ StreamString request_packet (Stream::eBinary, 4, eByteOrderLittle);
+ MakeRequestPacketHeader (eRequestTypeConnect, request_packet);
+ request_packet.PutHex16(reply_port);
+ request_packet.PutHex16(exc_port);
+ request_packet.PutCString(greeting);
+
+ return eErrorUnimplemented;
+}
+
+CommunicationKDP::ErrorType
+CommunicationKDP::Disconnect ()
+{
+ return eErrorUnimplemented;
+}
+
Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h?rev=135277&r1=135276&r2=135277&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h Fri Jul 15 11:31:38 2011
@@ -33,6 +33,53 @@
{
eBroadcastBitRunPacketSent = kLoUserBroadcastBit
};
+
+ const static uint32_t kMaxPacketSize = 1200;
+ const static uint32_t kMaxDataSize = 1024;
+
+ typedef enum
+ {
+ eRequestTypeConnect = 0u,
+ eRequestTypeDisconnect,
+ eRequestTypeHostInfo,
+ eRequestTypeVersion,
+ eRequestTypeMaxBytes,
+ eRequestTypeReadMemory,
+ eRequestTypeWriteMemory,
+ eRequestTypeReadRegisters,
+ eRequestTypeWriteRegisters,
+ eRequestTypeLoad,
+ eRequestTypeImagePath,
+ eRequestTypeSuspend,
+ eRequestTypeResume,
+ eRequestTypeException,
+ eRequestTypeTermination,
+ eRequestTypeBreakpointSet,
+ eRequestTypeBreakpointRemove,
+ eRequestTypeRegions,
+ eRequestTypeReattach,
+ eRequestTypeHostReboot,
+ eRequestTypeReadMemory64,
+ eRequestTypeWriteMemory64,
+ eRequestTypeBreakpointSet64,
+ eRequestTypeBreakpointRemove64,
+ eRequestTypeKernelVersion
+ } RequestType;
+
+ typedef enum
+ {
+ eErrorSuccess = 0,
+ eErrorAlreadyConnected,
+ eErrorPacketToBig,
+ eErrorInvalidRegisterFlavor,
+ eErrorUnimplemented
+ } ErrorType;
+
+ typedef enum
+ {
+ ePacketTypeRequest = 0u,
+ ePacketTypeReply = 1u
+ } PacketType;
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
@@ -41,34 +88,14 @@
virtual
~CommunicationKDP();
- size_t
- SendPacket (const char *payload);
-
- size_t
- SendPacket (const char *payload,
- size_t payload_length);
-
- size_t
- SendPacket (lldb_private::StreamString &response);
+ bool
+ SendRequestPacket (const lldb_private::StreamString &request_packet);
// Wait for a packet within 'nsec' seconds
size_t
WaitForPacketWithTimeoutMicroSeconds (StringExtractor &response,
uint32_t usec);
- char
- GetAck ();
-
- size_t
- SendAck ();
-
- size_t
- SendNack ();
-
- char
- CalculcateChecksum (const char *payload,
- size_t payload_length);
-
bool
GetSequenceMutex(lldb_private::Mutex::Locker& locker);
@@ -82,12 +109,6 @@
return m_public_is_running.GetValue();
}
- bool
- GetSendAcks ()
- {
- return m_send_acks;
- }
-
//------------------------------------------------------------------
// Set the global packet timeout.
//
@@ -119,12 +140,19 @@
lldb_private::ProcessLaunchInfo &launch_info);
+ ErrorType
+ Connect (uint16_t reply_port,
+ uint16_t exc_port,
+ const char *greeting);
+
+ ErrorType
+ Disconnect ();
+
protected:
typedef std::list packet_collection;
- size_t
- SendPacketNoLock (const char *payload,
- size_t payload_length);
+ bool
+ SendRequestPacketNoLock (const lldb_private::StreamString &request_packet);
size_t
WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractor &response,
@@ -133,6 +161,10 @@
bool
WaitForNotRunningPrivate (const lldb_private::TimeValue *timeout_ptr);
+ void
+ MakeRequestPacketHeader (RequestType request_type,
+ lldb_private::StreamString &request_packet);
+
//------------------------------------------------------------------
// Classes that inherit from CommunicationKDP can see and modify these
//------------------------------------------------------------------
@@ -140,8 +172,9 @@
lldb_private::Mutex m_sequence_mutex; // Restrict access to sending/receiving packets to a single thread at a time
lldb_private::Predicate m_public_is_running;
lldb_private::Predicate m_private_is_running;
- bool m_send_acks;
-
+ uint32_t m_session_key;
+ uint8_t m_request_sequence_id;
+ uint8_t m_exception_sequence_id;
private:
//------------------------------------------------------------------
// For CommunicationKDP only
Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp?rev=135277&r1=135276&r2=135277&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp Fri Jul 15 11:31:38 2011
@@ -16,6 +16,7 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/State.h"
#include "lldb/Host/Host.h"
+#include "lldb/Target/Target.h"
// Project includes
#include "ProcessKDP.h"
@@ -414,7 +415,7 @@
m_thread_list.DiscardThreadPlans();
- size_t response_size = m_comm.SendPacket ("D", 1);
+ size_t response_size = m_comm.Disconnect ();
if (log)
{
if (response_size)
From gclayton at apple.com Fri Jul 15 13:02:58 2011
From: gclayton at apple.com (Greg Clayton)
Date: Fri, 15 Jul 2011 18:02:58 -0000
Subject: [Lldb-commits] [lldb] r135284 - in
/lldb/trunk/source/Plugins/Process/MacOSX-Kernel: CommunicationKDP.cpp
CommunicationKDP.h ProcessKDP.cpp ProcessKDP.h ProcessKDPLog.cpp
ProcessKDPLog.h
Message-ID: <20110715180258.D5E782A6C12C@llvm.org>
Author: gclayton
Date: Fri Jul 15 13:02:58 2011
New Revision: 135284
URL: http://llvm.org/viewvc/llvm-project?rev=135284&view=rev
Log:
Fixed the comment lines in the file comment headers.
Modified:
lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp
lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h
Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp?rev=135284&r1=135283&r2=135284&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp Fri Jul 15 13:02:58 2011
@@ -1,4 +1,4 @@
-//===-- CommunicationKDP.cpp ------------------------------*- C++ -*-===//
+//===-- CommunicationKDP.cpp ------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h?rev=135284&r1=135283&r2=135284&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h Fri Jul 15 13:02:58 2011
@@ -1,4 +1,4 @@
-//===-- CommunicationKDP.h --------------------------------*- C++ -*-===//
+//===-- CommunicationKDP.h --------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp?rev=135284&r1=135283&r2=135284&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp Fri Jul 15 13:02:58 2011
@@ -1,4 +1,4 @@
-//===-- ProcessKDP.cpp ------------------------------------*- C++ -*-===//
+//===-- ProcessKDP.cpp ------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h?rev=135284&r1=135283&r2=135284&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h Fri Jul 15 13:02:58 2011
@@ -1,4 +1,4 @@
-//===-- ProcessKDP.h --------------------------------------*- C++ -*-===//
+//===-- ProcessKDP.h --------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp?rev=135284&r1=135283&r2=135284&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp Fri Jul 15 13:02:58 2011
@@ -1,4 +1,4 @@
-//===-- ProcessKDPLog.cpp ---------------------------------*- C++ -*-===//
+//===-- ProcessKDPLog.cpp ---------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h?rev=135284&r1=135283&r2=135284&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h Fri Jul 15 13:02:58 2011
@@ -1,4 +1,4 @@
-//===-- ProcessKDPLog.h -----------------------------------*- C++ -*-===//
+//===-- ProcessKDPLog.h -----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
From gclayton at apple.com Fri Jul 15 14:31:49 2011
From: gclayton at apple.com (Greg Clayton)
Date: Fri, 15 Jul 2011 19:31:49 -0000
Subject: [Lldb-commits] [lldb] r135292 - in /lldb/trunk:
include/lldb/API/SBValue.h source/API/SBValue.cpp
test/python_api/default-constructor/sb_value.py
Message-ID: <20110715193149.4D1212A6C12C@llvm.org>
Author: gclayton
Date: Fri Jul 15 14:31:49 2011
New Revision: 135292
URL: http://llvm.org/viewvc/llvm-project?rev=135292&view=rev
Log:
Added the ability to get synthetic child values from SBValue objects that
represent pointers and arrays by adding an extra parameter to the
SBValue
SBValue::GetChildAtIndex (uint32_t idx,
DynamicValueType use_dynamic,
bool can_create_synthetic);
The new "can_create_synthetic" will allow you to create child values that
aren't actually a part of the original type. So if you code like:
int *foo_ptr = ...
And you have a SBValue that contains the value for "foo_ptr":
SBValue foo_value = ...
You can now get the "foo_ptr[12]" item by doing this:
v = foo_value.GetChiltAtIndex (12, lldb.eNoDynamicValues, True);
Normall the "foo_value" would only have one child value (an integer), but
we can create "synthetic" child values by treating the pointer as an array.
Likewise if you have code like:
int array[2];
array_value = ....
v = array_value.GetChiltAtIndex (0); // Success, v will be valid
v = array_value.GetChiltAtIndex (1); // Success, v will be valid
v = array_value.GetChiltAtIndex (2); // Fail, v won't be valid, "2" is not a valid zero based index in "array"
But if you use the ability to create synthetic children:
v = array_value.GetChiltAtIndex (0, lldb.eNoDynamicValues, True); // Success, v will be valid
v = array_value.GetChiltAtIndex (1, lldb.eNoDynamicValues, True); // Success, v will be valid
v = array_value.GetChiltAtIndex (2, lldb.eNoDynamicValues, True); // Success, v will be valid
Modified:
lldb/trunk/include/lldb/API/SBValue.h
lldb/trunk/source/API/SBValue.cpp
lldb/trunk/test/python_api/default-constructor/sb_value.py
Modified: lldb/trunk/include/lldb/API/SBValue.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBValue.h?rev=135292&r1=135291&r2=135292&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBValue.h (original)
+++ lldb/trunk/include/lldb/API/SBValue.h Fri Jul 15 14:31:49 2011
@@ -150,8 +150,60 @@
lldb::SBValue
GetChildAtIndex (uint32_t idx);
- lldb::SBValue
- GetChildAtIndex (uint32_t idx, lldb::DynamicValueType use_dynamic);
+ //------------------------------------------------------------------
+ /// Get a child value by index from a value.
+ ///
+ /// Structs, unions, classes, arrays and and pointers have child
+ /// values that can be access by index.
+ ///
+ /// Structs and unions access child members using a zero based index
+ /// for each child member. For
+ ///
+ /// Classes reserve the first indexes for base classes that have
+ /// members (empty base classes are omitted), and all members of the
+ /// current class will then follow the base classes.
+ ///
+ /// Pointers differ depending on what they point to. If the pointer
+ /// points to a simple type, the child at index zero
+ /// is the only child value available, unless \a synthetic_allowed
+ /// is \b true, in which case the pointer will be used as an array
+ /// and can create "synthetic" child values using positive or
+ /// negative indexes. If the pointer points to an aggregate type
+ /// (an array, class, union, struct), then the pointee is
+ /// transparently skipped and any children are going to be the indexes
+ /// of the child values within the aggregate type. For example if
+ /// we have a "Point" type and we have a SBValue that contains a
+ /// pointer to a "Point" type, then the child at index zero will be
+ /// the "x" member, and the child at index 1 will be the "y" member
+ /// (the child at index zero won't be a "Point" instance).
+ ///
+ /// Arrays have a preset number of children that can be accessed by
+ /// index and will returns invalid child values for indexes that are
+ /// out of bounds unless the \a synthetic_allowed is \b true. In this
+ /// case the array can create "synthetic" child values for indexes
+ /// that aren't in the array bounds using positive or negative
+ /// indexes.
+ ///
+ /// @param[in] idx
+ /// The index of the child value to get
+ ///
+ /// @param[in] use_dynamic
+ /// An enumeration that specifies wether to get dynamic values,
+ /// and also if the target can be run to figure out the dynamic
+ /// type of the child value.
+ ///
+ /// @param[in] synthetic_allowed
+ /// If \b true, then allow child values to be created by index
+ /// for pointers and arrays for indexes that normally wouldn't
+ /// be allowed.
+ ///
+ /// @return
+ /// A new SBValue object that represents the child member value.
+ //------------------------------------------------------------------
+ lldb::SBValue
+ GetChildAtIndex (uint32_t idx,
+ lldb::DynamicValueType use_dynamic,
+ bool can_create_synthetic);
// Matches children of this object only and will match base classes and
// member names if this is a clang typed object.
Modified: lldb/trunk/source/API/SBValue.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBValue.cpp?rev=135292&r1=135291&r2=135292&view=diff
==============================================================================
--- lldb/trunk/source/API/SBValue.cpp (original)
+++ lldb/trunk/source/API/SBValue.cpp Fri Jul 15 14:31:49 2011
@@ -361,17 +361,15 @@
SBValue
SBValue::GetChildAtIndex (uint32_t idx)
{
+ const bool can_create_synthetic = false;
+ lldb::DynamicValueType use_dynamic = eNoDynamicValues;
if (m_opaque_sp)
- {
- lldb::DynamicValueType use_dynamic_value = m_opaque_sp->GetUpdatePoint().GetTarget()->GetPreferDynamicValue();
- return GetChildAtIndex (idx, use_dynamic_value);
- }
- else
- return GetChildAtIndex (idx, eNoDynamicValues);
+ use_dynamic = m_opaque_sp->GetUpdatePoint().GetTarget()->GetPreferDynamicValue();
+ return GetChildAtIndex (idx, use_dynamic, can_create_synthetic);
}
SBValue
-SBValue::GetChildAtIndex (uint32_t idx, lldb::DynamicValueType use_dynamic)
+SBValue::GetChildAtIndex (uint32_t idx, lldb::DynamicValueType use_dynamic, bool can_create_synthetic)
{
lldb::ValueObjectSP child_sp;
@@ -380,13 +378,25 @@
if (m_opaque_sp->GetUpdatePoint().GetTarget())
{
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
-
- child_sp = m_opaque_sp->GetChildAtIndex (idx, true);
- if (use_dynamic != lldb::eNoDynamicValues)
+ const bool can_create = true;
+ child_sp = m_opaque_sp->GetChildAtIndex (idx, can_create);
+ if (can_create_synthetic && !child_sp)
{
- if (child_sp)
+ if (m_opaque_sp->IsPointerType())
+ {
+ child_sp = m_opaque_sp->GetSyntheticArrayMemberFromPointer(idx, can_create);
+ }
+ else if (m_opaque_sp->IsArrayType())
+ {
+ child_sp = m_opaque_sp->GetSyntheticArrayMemberFromArray(idx, can_create);
+ }
+ }
+
+ if (child_sp)
+ {
+ if (use_dynamic != lldb::eNoDynamicValues)
{
- lldb::ValueObjectSP dynamic_sp = child_sp->GetDynamicValue (use_dynamic);
+ lldb::ValueObjectSP dynamic_sp(child_sp->GetDynamicValue (use_dynamic));
if (dynamic_sp)
child_sp = dynamic_sp;
}
Modified: lldb/trunk/test/python_api/default-constructor/sb_value.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/default-constructor/sb_value.py?rev=135292&r1=135291&r2=135292&view=diff
==============================================================================
--- lldb/trunk/test/python_api/default-constructor/sb_value.py (original)
+++ lldb/trunk/test/python_api/default-constructor/sb_value.py Fri Jul 15 14:31:49 2011
@@ -21,7 +21,7 @@
obj.GetLocation()
obj.SetValueFromCString("my_new_value")
obj.GetChildAtIndex(1)
- obj.GetChildAtIndex(2, lldb.eNoDynamicValues)
+ obj.GetChildAtIndex(2, lldb.eNoDynamicValues, False)
obj.GetIndexOfChildWithName("my_first_child")
obj.GetChildMemberWithName("my_first_child")
obj.GetChildMemberWithName("my_first_child", lldb.eNoDynamicValues)
From johnso87 at crhc.illinois.edu Fri Jul 15 15:12:05 2011
From: johnso87 at crhc.illinois.edu (Matt Johnson)
Date: Fri, 15 Jul 2011 15:12:05 -0500
Subject: [Lldb-commits] [PATCH] Make LLDB compile with Clang r135279
Message-ID: <4E209F15.1020300@crhc.illinois.edu>
Hi all,
This patch cleans up LLDB's usage of Clang and LLVM APIs that have
changed recently, due to the type system rewrite that landed last
weekend and some other StringRef and ArrayRef-related changes. LLDB,
with this patch, compiles under G++ 4.5.2 on Ubuntu 11.04. Comments
welcome.
Best,
Matt
-------------- next part --------------
A non-text attachment was scrubbed...
Name: typesystem.diff
Type: text/x-diff
Size: 9788 bytes
Desc: not available
Url : http://lists.cs.uiuc.edu/pipermail/lldb-commits/attachments/20110715/15ef88eb/attachment-0001.bin
From johnso87 at crhc.illinois.edu Fri Jul 15 15:26:52 2011
From: johnso87 at crhc.illinois.edu (Matt Johnson)
Date: Fri, 15 Jul 2011 15:26:52 -0500
Subject: [Lldb-commits] [PATCH] Begin cleanup to silence G++ warnings
Message-ID: <4E20A28C.9070402@crhc.illinois.edu>
Hi all,
This is the beginning of a cleanup effort to reduce the (vast) number of
(mostly benign) warnings when compiling LLDB HEAD under G++ 4.5.2 on
Ubuntu 11.04. Getting these warnings out of the way makes it much easier
to spot more important warnings, if nothing else. The fixes here can be
categorized as follows:
* Use of a signed type as a for loop induction variable, when the loop
bound is an unsigned type
* Assigning NULL (a pointer constant) to non-pointer types (e.g.,
uint32_t, addr_t)
* Declaring class members in one order, and including them in
constructor initializer lists in a different order
There are many more of the above warnings that I haven't gotten to yet,
as well as things like the following:
* Python docstrings in e.g. SBTarget.h use a nonstandard gcc
preprocessor extension that allows multi-line string literals.
- This causes *tons* of warnings (one per line of the literal, per
inclusion of the relevant header). e.g.:
/media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:23:1:
warning: missing terminating " character
/media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:48:1:
warning: missing terminating " character
/media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:91:27:
warning: missing terminating " character
/media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:164:5:
warning: missing terminating " character
/media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:180:27:
warning: missing terminating " character
/media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:216:5:
warning: missing terminating " character
/media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:224:27:
warning: missing terminating " character
/media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:245:5:
warning: missing terminating " character
/media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:253:27:
warning: missing terminating " character
/media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:277:5:
warning: missing terminating " character
/media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:286:27:
warning: missing terminating " character
/media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:310:5:
warning: missing terminating " character
/media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:334:27:
warning: missing terminating " character
/media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:361:5:
warning: missing terminating " character
/media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:370:27:
warning: missing terminating " character
/media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:386:5:
warning: missing terminating " character
- These literals should be formed like:
#ifdef SWIG
%feature("docstring",
"Represents the target program running under the debugger.\n"
"\n"
"SBTarget supports module and breakpoint iterations. For example,\n"
...
- instead of:
%feature("docstring",
"Represents the target program running under the debugger.
SBTarget supports module and breakpoint iterations. For example,
...
* Use of (deprecated) instead of
* Not handling some enum values in a switch statement. e.g.,
"ClangASTType.cpp:283:12: warning: enumeration value ?UnaryTransform?
not handled in switch"
* Defining static helper functions that are never used. e.g.,
"RegisterContextLinux_x86_64.cpp:408:17: warning: ?unsigned int
GetRegSize(unsigned int)? defined but not used"
Comments welcome.
Best,
Matt
-------------- next part --------------
A non-text attachment was scrubbed...
Name: cleanup.diff
Type: text/x-diff
Size: 20274 bytes
Desc: not available
Url : http://lists.cs.uiuc.edu/pipermail/lldb-commits/attachments/20110715/bab889a4/attachment.bin
From johnso87 at crhc.illinois.edu Fri Jul 15 15:31:18 2011
From: johnso87 at crhc.illinois.edu (Matt Johnson)
Date: Fri, 15 Jul 2011 15:31:18 -0500
Subject: [Lldb-commits] [PATCH] Begin cleanup to silence G++ warnings
In-Reply-To: <4E20A28C.9070402@crhc.illinois.edu>
References: <4E20A28C.9070402@crhc.illinois.edu>
Message-ID: <4E20A396.9070205@crhc.illinois.edu>
Note,
The line numbering in this patch depends on the previous patch I sent
to the list regarding updating LLDB's usage of Clang/LLVM APIs. See
http://lists.cs.uiuc.edu/pipermail/lldb-commits/Week-of-Mon-20110711/003313.html.
Sorry about that.
-Matt
On 07/15/2011 03:26 PM, Matt Johnson wrote:
> Hi all,
> This is the beginning of a cleanup effort to reduce the (vast) number
> of (mostly benign) warnings when compiling LLDB HEAD under G++ 4.5.2
> on Ubuntu 11.04. Getting these warnings out of the way makes it much
> easier to spot more important warnings, if nothing else. The fixes
> here can be categorized as follows:
>
> * Use of a signed type as a for loop induction variable, when the loop
> bound is an unsigned type
> * Assigning NULL (a pointer constant) to non-pointer types (e.g.,
> uint32_t, addr_t)
> * Declaring class members in one order, and including them in
> constructor initializer lists in a different order
>
> There are many more of the above warnings that I haven't gotten to
> yet, as well as things like the following:
> * Python docstrings in e.g. SBTarget.h use a nonstandard gcc
> preprocessor extension that allows multi-line string literals.
> - This causes *tons* of warnings (one per line of the literal, per
> inclusion of the relevant header). e.g.:
>
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:23:1:
> warning: missing terminating " character
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:48:1:
> warning: missing terminating " character
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:91:27:
> warning: missing terminating " character
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:164:5:
> warning: missing terminating " character
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:180:27:
> warning: missing terminating " character
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:216:5:
> warning: missing terminating " character
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:224:27:
> warning: missing terminating " character
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:245:5:
> warning: missing terminating " character
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:253:27:
> warning: missing terminating " character
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:277:5:
> warning: missing terminating " character
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:286:27:
> warning: missing terminating " character
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:310:5:
> warning: missing terminating " character
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:334:27:
> warning: missing terminating " character
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:361:5:
> warning: missing terminating " character
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:370:27:
> warning: missing terminating " character
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:386:5:
> warning: missing terminating " character
>
> - These literals should be formed like:
>
> #ifdef SWIG
> %feature("docstring",
> "Represents the target program running under the debugger.\n"
> "\n"
> "SBTarget supports module and breakpoint iterations. For example,\n"
> ...
>
> - instead of:
>
> %feature("docstring",
> "Represents the target program running under the debugger.
>
> SBTarget supports module and breakpoint iterations. For example,
> ...
>
>
> * Use of (deprecated) instead of
> * Not handling some enum values in a switch statement. e.g.,
> "ClangASTType.cpp:283:12: warning: enumeration value ?UnaryTransform?
> not handled in switch"
> * Defining static helper functions that are never used. e.g.,
> "RegisterContextLinux_x86_64.cpp:408:17: warning: ?unsigned int
> GetRegSize(unsigned int)? defined but not used"
>
> Comments welcome.
> Best,
> Matt
>
>
> _______________________________________________
> lldb-commits mailing list
> lldb-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.cs.uiuc.edu/pipermail/lldb-commits/attachments/20110715/2e4575e6/attachment-0001.html
From johnny.chen at apple.com Fri Jul 15 15:46:19 2011
From: johnny.chen at apple.com (Johnny Chen)
Date: Fri, 15 Jul 2011 20:46:19 -0000
Subject: [Lldb-commits] [lldb] r135295 - in /lldb/trunk:
include/lldb/API/SBBreakpoint.h include/lldb/API/SBCompileUnit.h
include/lldb/API/SBValue.h scripts/Python/modify-python-lldb.py
Message-ID: <20110715204619.7C3B33128018@llvm.org>
Author: johnny
Date: Fri Jul 15 15:46:19 2011
New Revision: 135295
URL: http://llvm.org/viewvc/llvm-project?rev=135295&view=rev
Log:
Add some more docstrings for SBCompileUnit and SBBreakpoint, plus incorporate the doxgen doc block of
SBValue::GetChildAtIndex(uint32_t idx,
lldb::DynamicValueType use_dynamic,
bool can_create_synthetic);
into the SBValue docstrings.
Modified:
lldb/trunk/include/lldb/API/SBBreakpoint.h
lldb/trunk/include/lldb/API/SBCompileUnit.h
lldb/trunk/include/lldb/API/SBValue.h
lldb/trunk/scripts/Python/modify-python-lldb.py
Modified: lldb/trunk/include/lldb/API/SBBreakpoint.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBBreakpoint.h?rev=135295&r1=135294&r2=135295&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBBreakpoint.h (original)
+++ lldb/trunk/include/lldb/API/SBBreakpoint.h Fri Jul 15 15:46:19 2011
@@ -71,6 +71,12 @@
process.Continue()
+SBBreakpoint supports breakpoint location iteration. For example,
+
+ for bl in breakpoint:
+ print 'breakpoint location load addr: %s' % hex(bl.GetLoadAddress())
+ print 'breakpoint location condition: %s' % hex(bl.GetCondition())
+
"
) SBBreakpoint;
#endif
Modified: lldb/trunk/include/lldb/API/SBCompileUnit.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBCompileUnit.h?rev=135295&r1=135294&r2=135295&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBCompileUnit.h (original)
+++ lldb/trunk/include/lldb/API/SBCompileUnit.h Fri Jul 15 15:46:19 2011
@@ -17,7 +17,32 @@
#ifdef SWIG
%feature("docstring",
- "Represents a compilation unit, or compiled source file."
+"Represents a compilation unit, or compiled source file.
+
+SBCompileUnit supports line entry iteration. For example,
+
+ for lineEntry in compileUnit:
+ print 'line entry: %s:%d' % (str(lineEntry.GetFileSpec()),
+ lineEntry.GetLine())
+ print 'start addr: %s' % str(lineEntry.GetStartAddress())
+ print 'end addr: %s' % str(lineEntry.GetEndAddress())
+
+produces:
+
+line entry: /Volumes/data/lldb/svn/trunk/test/python_api/symbol-context/main.c:20
+start addr: a.out[0x100000d98]
+end addr: a.out[0x100000da3]
+line entry: /Volumes/data/lldb/svn/trunk/test/python_api/symbol-context/main.c:21
+start addr: a.out[0x100000da3]
+end addr: a.out[0x100000da9]
+line entry: /Volumes/data/lldb/svn/trunk/test/python_api/symbol-context/main.c:22
+start addr: a.out[0x100000da9]
+end addr: a.out[0x100000db6]
+line entry: /Volumes/data/lldb/svn/trunk/test/python_api/symbol-context/main.c:23
+start addr: a.out[0x100000db6]
+end addr: a.out[0x100000dbc]
+...
+"
) SBCompileUnit;
#endif
class SBCompileUnit
Modified: lldb/trunk/include/lldb/API/SBValue.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBValue.h?rev=135295&r1=135294&r2=135295&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBValue.h (original)
+++ lldb/trunk/include/lldb/API/SBValue.h Fri Jul 15 15:46:19 2011
@@ -150,6 +150,9 @@
lldb::SBValue
GetChildAtIndex (uint32_t idx);
+#ifdef SWIG
+ %feature("docstring", "
+#endif
//------------------------------------------------------------------
/// Get a child value by index from a value.
///
@@ -167,20 +170,20 @@
/// points to a simple type, the child at index zero
/// is the only child value available, unless \a synthetic_allowed
/// is \b true, in which case the pointer will be used as an array
- /// and can create "synthetic" child values using positive or
+ /// and can create 'synthetic' child values using positive or
/// negative indexes. If the pointer points to an aggregate type
/// (an array, class, union, struct), then the pointee is
/// transparently skipped and any children are going to be the indexes
/// of the child values within the aggregate type. For example if
- /// we have a "Point" type and we have a SBValue that contains a
- /// pointer to a "Point" type, then the child at index zero will be
- /// the "x" member, and the child at index 1 will be the "y" member
- /// (the child at index zero won't be a "Point" instance).
+ /// we have a 'Point' type and we have a SBValue that contains a
+ /// pointer to a 'Point' type, then the child at index zero will be
+ /// the 'x' member, and the child at index 1 will be the 'y' member
+ /// (the child at index zero won't be a 'Point' instance).
///
/// Arrays have a preset number of children that can be accessed by
/// index and will returns invalid child values for indexes that are
/// out of bounds unless the \a synthetic_allowed is \b true. In this
- /// case the array can create "synthetic" child values for indexes
+ /// case the array can create 'synthetic' child values for indexes
/// that aren't in the array bounds using positive or negative
/// indexes.
///
@@ -200,6 +203,9 @@
/// @return
/// A new SBValue object that represents the child member value.
//------------------------------------------------------------------
+#ifdef SWIG
+ ") GetChildAtIndex;
+#endif
lldb::SBValue
GetChildAtIndex (uint32_t idx,
lldb::DynamicValueType use_dynamic,
Modified: lldb/trunk/scripts/Python/modify-python-lldb.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/modify-python-lldb.py?rev=135295&r1=135294&r2=135295&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/modify-python-lldb.py (original)
+++ lldb/trunk/scripts/Python/modify-python-lldb.py Fri Jul 15 15:46:19 2011
@@ -223,7 +223,7 @@
# Adding support for eq and ne for the matched SB class.
state |= DEFINING_EQUALITY
- elif (state & DEFINING_ITERATOR) or (state & DEFINING_EQUALITY):
+ if (state & DEFINING_ITERATOR) or (state & DEFINING_EQUALITY):
match = init_pattern.search(line)
if match:
# We found the beginning of the __init__ method definition.
@@ -244,15 +244,16 @@
# Next state will be NORMAL.
state = NORMAL
- elif (state & CLEANUP_DOCSTRING):
+ if (state & CLEANUP_DOCSTRING):
# Cleanse the lldb.py of the autodoc'ed residues.
if c_ifdef_swig in line or c_endif_swig in line:
continue
# As well as the comment marker line and trailing blank line.
if c_comment_marker in line or line == trailing_blank_line:
continue
- # Also remove the '\a ' substrings.
+ # Also remove the '\a ' and '\b 'substrings.
line = line.replace('\a ', '')
+ line = line.replace('\b ', '')
# And the leading '///' substring.
doxygen_comment_match = doxygen_comment_start.match(line)
if doxygen_comment_match:
From j.e.aten at gmail.com Fri Jul 15 15:26:09 2011
From: j.e.aten at gmail.com (Jason E. Aten)
Date: Fri, 15 Jul 2011 15:26:09 -0500
Subject: [Lldb-commits] [PATCH] Make LLDB compile with Clang r135279
In-Reply-To: <4E209F15.1020300@crhc.illinois.edu>
References: <4E209F15.1020300@crhc.illinois.edu>
Message-ID:
Nice! Thank you, Matt. I'll check it out.
On Fri, Jul 15, 2011 at 3:12 PM, Matt Johnson wrote:
> Hi all,
> This patch cleans up LLDB's usage of Clang and LLVM APIs that have
> changed recently, due to the type system rewrite that landed last weekend
> and some other StringRef and ArrayRef-related changes. LLDB, with this
> patch, compiles under G++ 4.5.2 on Ubuntu 11.04. Comments welcome.
> Best,
> Matt
>
> _______________________________________________
> lldb-commits mailing list
> lldb-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.cs.uiuc.edu/pipermail/lldb-commits/attachments/20110715/9bf1e7b8/attachment.html
From johnny.chen at apple.com Fri Jul 15 17:28:11 2011
From: johnny.chen at apple.com (Johnny Chen)
Date: Fri, 15 Jul 2011 22:28:11 -0000
Subject: [Lldb-commits] [lldb] r135315 - in /lldb/trunk/test: lldbtest.py
python_api/value/ python_api/value/Makefile
python_api/value/TestValueAPI.py python_api/value/main.c
Message-ID: <20110715222811.11DE6312800A@llvm.org>
Author: johnny
Date: Fri Jul 15 17:28:10 2011
New Revision: 135315
URL: http://llvm.org/viewvc/llvm-project?rev=135315&view=rev
Log:
Add TestValueAPI.py to exercise the newly added/modified SBValue APIs:
o GetChildAtIndex, and
o GetValueForExpressionPath
Added:
lldb/trunk/test/python_api/value/
lldb/trunk/test/python_api/value/Makefile
lldb/trunk/test/python_api/value/TestValueAPI.py
lldb/trunk/test/python_api/value/main.c
Modified:
lldb/trunk/test/lldbtest.py
Modified: lldb/trunk/test/lldbtest.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=135315&r1=135314&r2=135315&view=diff
==============================================================================
--- lldb/trunk/test/lldbtest.py (original)
+++ lldb/trunk/test/lldbtest.py Fri Jul 15 17:28:10 2011
@@ -194,6 +194,8 @@
VALID_TARGET = "Got a valid target"
+VALID_VARIABLE = "Got a valid variable"
+
VARIABLES_DISPLAYED_CORRECTLY = "Variable(s) displayed correctly"
Added: lldb/trunk/test/python_api/value/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/value/Makefile?rev=135315&view=auto
==============================================================================
--- lldb/trunk/test/python_api/value/Makefile (added)
+++ lldb/trunk/test/python_api/value/Makefile Fri Jul 15 17:28:10 2011
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
Added: lldb/trunk/test/python_api/value/TestValueAPI.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/value/TestValueAPI.py?rev=135315&view=auto
==============================================================================
--- lldb/trunk/test/python_api/value/TestValueAPI.py (added)
+++ lldb/trunk/test/python_api/value/TestValueAPI.py Fri Jul 15 17:28:10 2011
@@ -0,0 +1,87 @@
+"""
+Test some SBValue APIs.
+"""
+
+import os, time
+import re
+import unittest2
+import lldb, lldbutil
+from lldbtest import *
+
+class ValueAPITestCase(TestBase):
+
+ mydir = os.path.join("python_api", "value")
+
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ @python_api_test
+ def test_with_dsym(self):
+ """Exercise some SBValue APIs."""
+ d = {'EXE': self.exe_name}
+ self.buildDsym(dictionary=d)
+ self.setTearDownCleanup(dictionary=d)
+ self.value_api(self.exe_name)
+
+ @python_api_test
+ def test_with_dwarf(self):
+ """Exercise some SBValue APIs."""
+ d = {'EXE': self.exe_name}
+ self.buildDwarf(dictionary=d)
+ self.setTearDownCleanup(dictionary=d)
+ self.value_api(self.exe_name)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # We'll use the test method name as the exe_name.
+ self.exe_name = self.testMethodName
+ # Find the line number to of function 'c'.
+ self.line = line_number('main.c', '// Break at this line')
+
+ def value_api(self, exe_name):
+ """Exercise some SBValue APIs."""
+ exe = os.path.join(os.getcwd(), exe_name)
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # Create the breakpoint inside function 'main'.
+ breakpoint = target.BreakpointCreateByLocation('main.c', self.line)
+ self.assertTrue(breakpoint, VALID_BREAKPOINT)
+
+ # Now launch the process, and do not stop at entry point.
+ process = target.LaunchSimple(None, None, os.getcwd())
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ # Get Frame #0.
+ self.assertTrue(process.GetState() == lldb.eStateStopped)
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+ self.assertTrue(thread != None, "There should be a thread stopped due to breakpoint condition")
+ frame0 = thread.GetFrameAtIndex(0)
+
+ # Get variable 'str_ptr'.
+ value = frame0.FindVariable('str_ptr')
+ self.assertTrue(value, VALID_VARIABLE)
+ self.DebugSBValue(value)
+
+ # Get child at index 5 => 'Friday'.
+ child = value.GetChildAtIndex(5, lldb.eNoDynamicValues, True)
+ self.assertTrue(child, VALID_VARIABLE)
+ self.DebugSBValue(child)
+
+ self.expect(child.GetSummary(), exe=False,
+ substrs = ['Friday'])
+
+ # Now try to get at the same variable using GetValueForExpressionPath().
+ # These two SBValue objects should have the same value.
+ val2 = value.GetValueForExpressionPath('[5]')
+ self.assertTrue(val2, VALID_VARIABLE)
+ self.DebugSBValue(val2)
+ self.assertTrue(child.GetValue() == val2.GetValue() and
+ child.GetSummary() == val2.GetSummary())
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
Added: lldb/trunk/test/python_api/value/main.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/value/main.c?rev=135315&view=auto
==============================================================================
--- lldb/trunk/test/python_api/value/main.c (added)
+++ lldb/trunk/test/python_api/value/main.c Fri Jul 15 17:28:10 2011
@@ -0,0 +1,30 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include
+
+// This simple program is to test the lldb Python API SBValue.GetChildAtIndex().
+
+const char *days_of_week[7] = { "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday" };
+
+int main (int argc, char const *argv[])
+{
+ int i;
+ const char **str_ptr = days_of_week;
+ for (i = 0; i < 7; ++i)
+ printf("%s\n", str_ptr[i]); // Break at this line
+ // and do str_ptr_val.GetChildAtIndex(5, lldb.eNoDynamicValues, True).
+
+ return 0;
+}
From peter at pcc.me.uk Fri Jul 15 18:22:49 2011
From: peter at pcc.me.uk (Peter Collingbourne)
Date: Fri, 15 Jul 2011 23:22:49 -0000
Subject: [Lldb-commits] [lldb] r135325 -
/lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
Message-ID: <20110715232249.CEB0A2A6C12D@llvm.org>
Author: pcc
Date: Fri Jul 15 18:22:49 2011
New Revision: 135325
URL: http://llvm.org/viewvc/llvm-project?rev=135325&view=rev
Log:
Fix gcc build error
Modified:
lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h?rev=135325&r1=135324&r2=135325&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h (original)
+++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h Fri Jul 15 18:22:49 2011
@@ -27,8 +27,6 @@
const lldb::StackFrameSP& frame_sp,
const lldb::BreakpointLocationSP &bp_loc_sp);
- typedef
-
typedef std::string (*SWIGPythonTypeScriptCallbackFunction) (const char *python_function_name,
const char *session_dictionary_name,
const lldb::ValueObjectSP& valobj_sp);
From granata.enrico at gmail.com Fri Jul 15 18:30:15 2011
From: granata.enrico at gmail.com (Enrico Granata)
Date: Fri, 15 Jul 2011 23:30:15 -0000
Subject: [Lldb-commits] [lldb] r135326 - in /lldb/trunk: include/lldb/Core/
source/Commands/ source/Core/ source/Symbol/
test/functionalities/data-formatter/data-formatter-script/
Message-ID: <20110715233015.927A52A6C12C@llvm.org>
Author: enrico
Date: Fri Jul 15 18:30:15 2011
New Revision: 135326
URL: http://llvm.org/viewvc/llvm-project?rev=135326&view=rev
Log:
System-wide summaries:
- Summaries for char*, const char* and char[] are loaded at startup as
system-wide summaries. This means you cannot delete them unless you use
the -a option to type summary delete/clear
- You can add your own system-wide summaries by using the -w option to type
summary add
Several code improvements for the Python summaries feature
Modified:
lldb/trunk/include/lldb/Core/Debugger.h
lldb/trunk/include/lldb/Core/FormatManager.h
lldb/trunk/include/lldb/Core/InputReader.h
lldb/trunk/include/lldb/Core/InputReaderEZ.h
lldb/trunk/source/Commands/CommandObjectType.cpp
lldb/trunk/source/Commands/CommandObjectType.h
lldb/trunk/source/Core/Debugger.cpp
lldb/trunk/source/Core/InputReaderEZ.cpp
lldb/trunk/source/Core/ValueObject.cpp
lldb/trunk/source/Symbol/ClangASTContext.cpp
lldb/trunk/source/Symbol/TypeHierarchyNavigator.cpp
lldb/trunk/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py
lldb/trunk/test/functionalities/data-formatter/data-formatter-script/main.cpp
Modified: lldb/trunk/include/lldb/Core/Debugger.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Debugger.h?rev=135326&r1=135325&r2=135326&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Debugger.h (original)
+++ lldb/trunk/include/lldb/Core/Debugger.h Fri Jul 15 18:30:15 2011
@@ -525,6 +525,32 @@
GetCount();
};
+ class SystemSummaryFormats
+ {
+ public:
+
+ static bool
+ Get(ValueObject& vobj, SummaryFormat::SharedPointer &entry);
+
+ static void
+ Add(const ConstString &type, const SummaryFormat::SharedPointer &entry);
+
+ static bool
+ Delete(const ConstString &type);
+
+ static void
+ Clear();
+
+ static void
+ LoopThrough(SummaryFormat::SummaryCallback callback, void* callback_baton);
+
+ static uint32_t
+ GetCurrentRevision();
+
+ static uint32_t
+ GetCount();
+ };
+
class RegexSummaryFormats
{
public:
@@ -551,6 +577,32 @@
GetCount();
};
+ class SystemRegexSummaryFormats
+ {
+ public:
+
+ static bool
+ Get(ValueObject& vobj, SummaryFormat::SharedPointer &entry);
+
+ static void
+ Add(const lldb::RegularExpressionSP &type, const SummaryFormat::SharedPointer &entry);
+
+ static bool
+ Delete(const ConstString &type);
+
+ static void
+ Clear();
+
+ static void
+ LoopThrough(SummaryFormat::RegexSummaryCallback callback, void* callback_baton);
+
+ static uint32_t
+ GetCurrentRevision();
+
+ static uint32_t
+ GetCount();
+ };
+
class NamedSummaryFormats
{
public:
Modified: lldb/trunk/include/lldb/Core/FormatManager.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/FormatManager.h?rev=135326&r1=135325&r2=135326&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/FormatManager.h (original)
+++ lldb/trunk/include/lldb/Core/FormatManager.h Fri Jul 15 18:30:15 2011
@@ -150,19 +150,22 @@
bool m_dont_show_children;
bool m_dont_show_value;
bool m_show_members_oneliner;
+ bool m_is_system;
SummaryFormat(bool casc = false,
bool skipptr = false,
bool skipref = false,
bool nochildren = true,
bool novalue = true,
- bool oneliner = false) :
+ bool oneliner = false,
+ bool system = false) :
m_cascades(casc),
m_skip_pointers(skipptr),
m_skip_references(skipref),
m_dont_show_children(nochildren),
m_dont_show_value(novalue),
- m_show_members_oneliner(oneliner)
+ m_show_members_oneliner(oneliner),
+ m_is_system(system)
{
}
@@ -200,6 +203,12 @@
return m_show_members_oneliner;
}
+ bool
+ IsSystem() const
+ {
+ return m_is_system;
+ }
+
virtual
~SummaryFormat()
{
@@ -228,8 +237,9 @@
bool nochildren = true,
bool novalue = true,
bool oneliner = false,
+ bool system = false,
std::string f = "") :
- SummaryFormat(casc,skipptr,skipref,nochildren,novalue,oneliner),
+ SummaryFormat(casc,skipptr,skipref,nochildren,novalue,oneliner,system),
m_format(f)
{
}
@@ -252,13 +262,14 @@
GetDescription()
{
StreamString sstr;
- sstr.Printf ("`%s`%s%s%s%s%s%s\n", m_format.c_str(),
+ sstr.Printf ("`%s`%s%s%s%s%s%s%s", m_format.c_str(),
m_cascades ? "" : " (not cascading)",
m_dont_show_children ? "" : " (show children)",
m_dont_show_value ? " (hide value)" : "",
m_show_members_oneliner ? " (one-line printout)" : "",
m_skip_pointers ? " (skip pointers)" : "",
- m_skip_references ? " (skip references)" : "");
+ m_skip_references ? " (skip references)" : "",
+ m_is_system ? " (system)" : "");
return sstr.GetString();
}
@@ -276,9 +287,10 @@
bool nochildren = true,
bool novalue = true,
bool oneliner = false,
+ bool system = false,
std::string fname = "",
std::string pscri = "") :
- SummaryFormat(casc,skipptr,skipref,nochildren,novalue,oneliner),
+ SummaryFormat(casc,skipptr,skipref,nochildren,novalue,oneliner,system),
m_function_name(fname),
m_python_script(pscri)
{
@@ -312,10 +324,14 @@
GetDescription()
{
StreamString sstr;
- sstr.Printf ("%s%s%s\n%s\n", m_cascades ? "" : " (not cascading)",
- m_skip_pointers ? " (skip pointers)" : "",
- m_skip_references ? " (skip references)" : "",
- m_python_script.c_str());
+ sstr.Printf ("%s%s%s%s%s%s%s\n%s", m_cascades ? "" : " (not cascading)",
+ m_dont_show_children ? "" : " (show children)",
+ m_dont_show_value ? " (hide value)" : "",
+ m_show_members_oneliner ? " (one-line printout)" : "",
+ m_skip_pointers ? " (skip pointers)" : "",
+ m_skip_references ? " (skip references)" : "",
+ m_is_system ? " (system)" : "",
+ m_python_script.c_str());
return sstr.GetString();
}
@@ -727,12 +743,12 @@
ValueNavigator m_value_nav;
SummaryNavigator m_summary_nav;
+ SummaryNavigator m_system_summary_nav;
RegexSummaryNavigator m_regex_summary_nav;
-
+ RegexSummaryNavigator m_system_regex_summary_nav;
+
NamedSummariesMap m_named_summaries_map;
-
- ScriptNavigator m_script_nav;
-
+
uint32_t m_last_revision;
public:
@@ -740,19 +756,48 @@
FormatManager() :
m_value_nav(this),
m_summary_nav(this),
+ m_system_summary_nav(this),
m_regex_summary_nav(this),
+ m_system_regex_summary_nav(this),
m_named_summaries_map(this),
- m_script_nav(this),
m_last_revision(0)
{
+ // add some default stuff
+ // most formats, summaries, ... actually belong to the users' lldbinit file rather than here
+ SummaryFormat::SharedPointer string_format(new StringSummaryFormat(false,
+ true,
+ false,
+ true,
+ false,
+ false,
+ true,
+ "${var%s}"));
+
+
+ SummaryFormat::SharedPointer string_array_format(new StringSummaryFormat(false,
+ true,
+ false,
+ false,
+ false,
+ false,
+ true,
+ "${var%s}"));
+
+ lldb::RegularExpressionSP any_size_char_arr(new RegularExpression("char \\[[0-9]+\\]"));
+
+
+ SystemSummary().Add(ConstString("char *").GetCString(), string_format);
+ SystemSummary().Add(ConstString("const char *").GetCString(), string_format);
+ SystemRegexSummary().Add(any_size_char_arr, string_array_format);
}
ValueNavigator& Value() { return m_value_nav; }
SummaryNavigator& Summary() { return m_summary_nav; }
+ SummaryNavigator& SystemSummary() { return m_system_summary_nav; }
RegexSummaryNavigator& RegexSummary() { return m_regex_summary_nav; }
+ RegexSummaryNavigator& SystemRegexSummary() { return m_system_regex_summary_nav; }
NamedSummariesMap& NamedSummary() { return m_named_summaries_map; }
- ScriptNavigator& Script() { return m_script_nav; }
static bool
GetFormatFromCString (const char *format_cstr,
Modified: lldb/trunk/include/lldb/Core/InputReader.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/InputReader.h?rev=135326&r1=135325&r2=135326&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/InputReader.h (original)
+++ lldb/trunk/include/lldb/Core/InputReader.h Fri Jul 15 18:30:15 2011
@@ -52,6 +52,65 @@
bool
GetBatchMode();
};
+
+ struct InitializationParameters
+ {
+ private:
+ void* m_baton;
+ lldb::InputReaderGranularity m_token_size;
+ char* m_end_token;
+ char* m_prompt;
+ bool m_echo;
+ public:
+ InitializationParameters() :
+ m_baton(NULL),
+ m_token_size(lldb::eInputReaderGranularityLine),
+ m_echo(true)
+ {
+ SetEndToken("DONE");
+ SetPrompt("> ");
+ }
+
+ InitializationParameters&
+ SetEcho(bool e)
+ {
+ m_echo = e;
+ return *this;
+ }
+
+ InitializationParameters&
+ SetBaton(void* b)
+ {
+ m_baton = b;
+ return *this;
+ }
+
+ InitializationParameters&
+ SetGranularity(lldb::InputReaderGranularity g)
+ {
+ m_token_size = g;
+ return *this;
+ }
+
+ InitializationParameters&
+ SetEndToken(const char* e)
+ {
+ m_end_token = new char[strlen(e)+1];
+ ::strcpy(m_end_token,e);
+ return *this;
+ }
+
+ InitializationParameters&
+ SetPrompt(const char* p)
+ {
+ m_prompt = new char[strlen(p)+1];
+ ::strcpy(m_prompt,p);
+ return *this;
+ }
+
+ friend class InputReaderEZ;
+
+ };
InputReader (Debugger &debugger);
@@ -75,6 +134,12 @@
return Error("unimplemented");
}
+ virtual Error
+ Initialize(InitializationParameters& params)
+ {
+ return Error("unimplemented");
+ }
+
// to use these handlers instead of the Callback function, you must subclass
// InputReaderEZ, and redefine the handlers for the events you care about
virtual void
Modified: lldb/trunk/include/lldb/Core/InputReaderEZ.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/InputReaderEZ.h?rev=135326&r1=135325&r2=135326&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/InputReaderEZ.h (original)
+++ lldb/trunk/include/lldb/Core/InputReaderEZ.h Fri Jul 15 18:30:15 2011
@@ -10,6 +10,8 @@
#ifndef liblldb_InputReaderEZ_h_
#define liblldb_InputReaderEZ_h_
+#include
+
#include "lldb/lldb-public.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/Core/Debugger.h"
@@ -30,7 +32,7 @@
const char *bytes,
size_t bytes_len);
public:
-
+
InputReaderEZ (Debugger &debugger) :
InputReader(debugger)
{}
@@ -38,11 +40,15 @@
virtual
~InputReaderEZ ();
- virtual Error Initialize(void* baton,
- lldb::InputReaderGranularity token_size = lldb::eInputReaderGranularityLine,
- const char* end_token = "DONE",
- const char *prompt = "> ",
- bool echo = true);
+ virtual Error
+ Initialize(void* baton,
+ lldb::InputReaderGranularity token_size = lldb::eInputReaderGranularityLine,
+ const char* end_token = "DONE",
+ const char *prompt = "> ",
+ bool echo = true);
+
+ virtual Error
+ Initialize(InitializationParameters& params);
virtual void
ActivateHandler(HandlerData&) {}
Modified: lldb/trunk/source/Commands/CommandObjectType.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectType.cpp?rev=135326&r1=135325&r2=135326&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectType.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectType.cpp Fri Jul 15 18:30:15 2011
@@ -176,7 +176,7 @@
return false;
}
- if(m_options.m_format == eFormatInvalid)
+ if (m_options.m_format == eFormatInvalid)
{
result.AppendErrorWithFormat ("%s needs a valid format.\n", m_cmd_name.c_str());
result.SetStatus(eReturnStatusFailed);
@@ -265,7 +265,7 @@
const char* typeA = command.GetArgumentAtIndex(0);
ConstString typeCS(typeA);
- if(!typeCS)
+ if (!typeCS)
{
result.AppendError("empty typenames not allowed");
result.SetStatus(eReturnStatusFailed);
@@ -418,34 +418,8 @@
// CommandObjectTypeSummaryAdd
//-------------------------------------------------------------------------
-class ScriptAddOptions
-{
-
-public:
-
- bool m_skip_pointers;
- bool m_skip_references;
- bool m_cascade;
- bool m_callback_is_synchronous;
- StringList m_target_types;
- StringList m_user_source;
-
- ScriptAddOptions(bool p,
- bool r,
- bool c) :
- m_skip_pointers(p),
- m_skip_references(r),
- m_cascade(c),
- m_target_types(),
- m_user_source()
- {
- }
-
- typedef lldb::SharedPtr::Type SharedPointer;
-
-};
-
-static const char *g_reader_instructions = "Enter your Python command(s). Type 'DONE' to end.";
+static const char *g_reader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
+ "def function (valobj,dict):";
class TypeScriptAddInputReader : public InputReaderEZ
{
@@ -560,473 +534,542 @@
script_format.reset(new ScriptSummaryFormat(options->m_cascade,
options->m_skip_pointers,
options->m_skip_references,
- true,
- true,
- false,
+ options->m_no_children,
+ options->m_no_value,
+ options->m_one_liner,
+ options->m_is_system,
std::string(funct_name),
options->m_user_source.CopyList(" ")));
+ Error error;
+
for (int i = 0; i < options->m_target_types.GetSize(); i++)
{
const char *type_name = options->m_target_types.GetStringAtIndex(i);
- Debugger::SummaryFormats::Add(ConstString(type_name), script_format);
+ CommandObjectTypeSummaryAdd::AddSummary(ConstString(type_name),
+ script_format,
+ (options->m_regex ? CommandObjectTypeSummaryAdd::eRegexSummary : CommandObjectTypeSummaryAdd::eRegularSummary),
+ options->m_is_system,
+ &error);
+ if (error.Fail())
+ {
+ out_stream->Printf (error.AsCString());
+ out_stream->Flush();
+ return;
+ }
+ }
+
+ if (options->m_name)
+ {
+ if ( (bool)(*(options->m_name)) )
+ {
+ CommandObjectTypeSummaryAdd::AddSummary(*(options->m_name),
+ script_format,
+ CommandObjectTypeSummaryAdd::eNamedSummary,
+ options->m_is_system,
+ &error);
+ if (error.Fail())
+ {
+ out_stream->Printf (error.AsCString());
+ out_stream->Flush();
+ return;
+ }
+ }
+ else
+ {
+ out_stream->Printf (error.AsCString());
+ out_stream->Flush();
+ return;
+ }
}
}
};
-class CommandObjectTypeSummaryAdd : public CommandObject
+Error
+CommandObjectTypeSummaryAdd::CommandOptions::SetOptionValue (uint32_t option_idx, const char *option_arg)
{
+ Error error;
+ char short_option = (char) m_getopt_table[option_idx].val;
+ bool success;
+
+ switch (short_option)
+ {
+ case 'C':
+ m_cascade = Args::StringToBoolean(option_arg, true, &success);
+ if (!success)
+ error.SetErrorStringWithFormat("Invalid value for cascade: %s.\n", option_arg);
+ break;
+ case 'e':
+ m_no_children = false;
+ break;
+ case 'v':
+ m_no_value = true;
+ break;
+ case 'c':
+ m_one_liner = true;
+ break;
+ case 'f':
+ m_format_string = std::string(option_arg);
+ break;
+ case 'p':
+ m_skip_pointers = true;
+ break;
+ case 'r':
+ m_skip_references = true;
+ break;
+ case 'x':
+ m_regex = true;
+ break;
+ case 'n':
+ m_name = new ConstString(option_arg);
+ break;
+ case 's':
+ m_python_script = std::string(option_arg);
+ m_is_add_script = true;
+ break;
+ case 'F':
+ m_python_function = std::string(option_arg);
+ m_is_add_script = true;
+ break;
+ case 'P':
+ m_is_add_script = true;
+ break;
+ case 'w':
+ m_is_system = true;
+ break;
+ default:
+ error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
+ break;
+ }
-private:
-
- class CommandOptions : public Options
+ return error;
+}
+
+void
+CommandObjectTypeSummaryAdd::CommandOptions::OptionParsingStarting ()
+{
+ m_cascade = true;
+ m_no_children = true;
+ m_no_value = false;
+ m_one_liner = false;
+ m_skip_references = false;
+ m_skip_pointers = false;
+ m_regex = false;
+ m_name = NULL;
+ m_python_script = "";
+ m_python_function = "";
+ m_is_add_script = false;
+ m_is_system = false;
+}
+
+void
+CommandObjectTypeSummaryAdd::CollectPythonScript (ScriptAddOptions *options,
+ CommandReturnObject &result)
+{
+ InputReaderSP reader_sp (new TypeScriptAddInputReader(m_interpreter.GetDebugger()));
+ if (reader_sp && options)
{
- public:
- CommandOptions (CommandInterpreter &interpreter) :
- Options (interpreter)
- {
- }
-
- virtual
- ~CommandOptions (){}
-
- virtual Error
- SetOptionValue (uint32_t option_idx, const char *option_arg)
- {
- Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
- bool success;
-
- switch (short_option)
- {
- case 'C':
- m_cascade = Args::StringToBoolean(option_arg, true, &success);
- if (!success)
- error.SetErrorStringWithFormat("Invalid value for cascade: %s.\n", option_arg);
- break;
- case 'e':
- m_no_children = false;
- break;
- case 'v':
- m_no_value = true;
- break;
- case 'c':
- m_one_liner = true;
- break;
- case 'f':
- m_format_string = std::string(option_arg);
- break;
- case 'p':
- m_skip_pointers = true;
- break;
- case 'r':
- m_skip_references = true;
- break;
- case 'x':
- m_regex = true;
- break;
- case 'n':
- m_name = new ConstString(option_arg);
- break;
- case 's':
- m_python_script = std::string(option_arg);
- m_is_add_script = true;
- break;
- case 'F':
- m_python_function = std::string(option_arg);
- m_is_add_script = true;
- break;
- case 'P':
- m_is_add_script = true;
- break;
- default:
- error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
- break;
- }
-
- return error;
- }
+ InputReaderEZ::InitializationParameters ipr;
- void
- OptionParsingStarting ()
+ Error err (reader_sp->Initialize (ipr.SetBaton(options).SetPrompt(" ")));
+ if (err.Success())
{
- m_cascade = true;
- m_no_children = true;
- m_no_value = false;
- m_one_liner = false;
- m_skip_references = false;
- m_skip_pointers = false;
- m_regex = false;
- m_name = NULL;
- m_python_script = "";
- m_python_function = "";
- m_is_add_script = false;
+ m_interpreter.GetDebugger().PushInputReader (reader_sp);
+ result.SetStatus (eReturnStatusSuccessFinishNoResult);
}
-
- const OptionDefinition*
- GetDefinitions ()
+ else
{
- return g_option_table;
+ result.AppendError (err.AsCString());
+ result.SetStatus (eReturnStatusFailed);
}
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
-
- bool m_cascade;
- bool m_no_children;
- bool m_no_value;
- bool m_one_liner;
- bool m_skip_references;
- bool m_skip_pointers;
- bool m_regex;
- std::string m_format_string;
- ConstString* m_name;
- std::string m_python_script;
- std::string m_python_function;
- bool m_is_add_script;
- };
+ }
+ else
+ {
+ result.AppendError("out of memory");
+ result.SetStatus (eReturnStatusFailed);
+ }
- CommandOptions m_options;
+}
+
+bool
+CommandObjectTypeSummaryAdd::Execute_ScriptSummary (Args& command, CommandReturnObject &result)
+{
+ const size_t argc = command.GetArgumentCount();
- virtual Options *
- GetOptions ()
+ if (argc < 1 && !m_options.m_name)
{
- return &m_options;
+ result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
-public:
- CommandObjectTypeSummaryAdd (CommandInterpreter &interpreter) :
- CommandObject (interpreter,
- "type summary add",
- "Add a new summary style for a type.",
- NULL), m_options (interpreter)
- {
- CommandArgumentEntry type_arg;
- CommandArgumentData type_style_arg;
-
- type_style_arg.arg_type = eArgTypeName;
- type_style_arg.arg_repetition = eArgRepeatPlus;
-
- type_arg.push_back (type_style_arg);
-
- m_arguments.push_back (type_arg);
-
- SetHelpLong(
- "Some examples of using this command.\n"
- "We use as reference the following snippet of code:\n"
- "struct JustADemo\n"
- "{\n"
- "int* ptr;\n"
- "float value;\n"
- "JustADemo(int p = 1, float v = 0.1) : ptr(new int(p)), value(v) {}\n"
- "};\n"
- "JustADemo object(42,3.14);\n"
- "struct AnotherDemo : public JustADemo\n"
- "{\n"
- "uint8_t byte;\n"
- "AnotherDemo(uint8_t b = 'E', int p = 1, float v = 0.1) : JustADemo(p,v), byte(b) {}\n"
- "};\n"
- "AnotherDemo *another_object = new AnotherDemo('E',42,3.14);\n"
- "\n"
- "type summary add -f \"the answer is ${*var.ptr}\" JustADemo\n"
- "when typing frame variable object you will get \"the answer is 42\"\n"
- "type summary add -f \"the answer is ${*var.ptr}, and the question is ${var.value}\" JustADemo\n"
- "when typing frame variable object you will get \"the answer is 42 and the question is 3.14\"\n"
- "\n"
- "Alternatively, you could also say\n"
- "type summary add -f \"${var%V} -> ${*var}\" \"int *\"\n"
- "and replace the above summary string with\n"
- "type summary add -f \"the answer is ${var.ptr}, and the question is ${var.value}\" JustADemo\n"
- "to obtain a similar result\n"
- "\n"
- "To add a summary valid for both JustADemo and AnotherDemo you can use the scoping operator, as in:\n"
- "type summary add -f \"${var.ptr}, ${var.value},{${var.byte}}\" JustADemo -C yes\n"
- "\n"
- "This will be used for both variables of type JustADemo and AnotherDemo. To prevent this, change the -C to read -C no\n"
- "If you do not want pointers to be shown using that summary, you can use the -p option, as in:\n"
- "type summary add -f \"${var.ptr}, ${var.value},{${var.byte}}\" JustADemo -C yes -p\n"
- "A similar option -r exists for references.\n"
- "\n"
- "If you simply want a one-line summary of the content of your variable, without typing an explicit string to that effect\n"
- "you can use the -c option, without giving any summary string:\n"
- "type summary add -c JustADemo\n"
- "frame variable object\n"
- "the output being similar to (ptr=0xsomeaddress, value=3.14)\n"
- "\n"
- "If you want to display some summary text, but also expand the structure of your object, you can add the -e option, as in:\n"
- "type summary add -e -f \"*ptr = ${*var.ptr}\" JustADemo\n"
- "Here the value of the int* is displayed, followed by the standard LLDB sequence of children objects, one per line.\n"
- "to get an output like:\n"
- "\n"
- "*ptr = 42 {\n"
- " ptr = 0xsomeaddress\n"
- " value = 3.14\n"
- "}\n"
- "\n"
- "A command you may definitely want to try if you're doing C++ debugging is:\n"
- "type summary add -f \"${var._M_dataplus._M_p}\" std::string\n"
- );
- }
-
- ~CommandObjectTypeSummaryAdd ()
- {
- }
-
- void
- CollectPythonScript
- (
- ScriptAddOptions *options,
- CommandReturnObject &result
- )
+ SummaryFormatSP script_format;
+
+ if (!m_options.m_python_function.empty()) // we have a Python function ready to use
{
- InputReaderSP reader_sp (new TypeScriptAddInputReader(m_interpreter.GetDebugger()));
- if (reader_sp && options)
+ ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
+ if (!interpreter)
{
-
- Error err (reader_sp->Initialize (options));
- if (err.Success())
- {
- m_interpreter.GetDebugger().PushInputReader (reader_sp);
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- result.AppendError (err.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
+ result.AppendError ("Internal error #1N: no script attached.\n");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
}
- else
+ const char *funct_name = m_options.m_python_function.c_str();
+ if (!funct_name || !funct_name[0])
{
- result.AppendError("out of memory");
+ result.AppendError ("Internal error #2N: no script attached.\n");
result.SetStatus (eReturnStatusFailed);
+ return false;
}
+ script_format.reset(new ScriptSummaryFormat(m_options.m_cascade,
+ m_options.m_skip_pointers,
+ m_options.m_skip_references,
+ m_options.m_no_children,
+ m_options.m_no_value,
+ m_options.m_one_liner,
+ m_options.m_is_system,
+ std::string(funct_name),
+ " " + m_options.m_python_function + "(valobj,dict)"));
}
-
- bool
- Execute (Args& command, CommandReturnObject &result)
- {
- if (m_options.m_is_add_script)
- return Execute_ScriptSummary(command, result);
- else
- return Execute_StringSummary(command, result);
- }
-
- bool
- Execute_ScriptSummary (Args& command, CommandReturnObject &result)
+ else if (!m_options.m_python_script.empty()) // we have a quick 1-line script, just use it
{
- const size_t argc = command.GetArgumentCount();
-
- if (argc < 1)
+ ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
+ if (!interpreter)
{
- result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
+ result.AppendError ("Internal error #1Q: no script attached.\n");
+ result.SetStatus (eReturnStatusFailed);
return false;
}
-
- if (!m_options.m_python_function.empty()) // we have a Python function ready to use
+ StringList funct_sl;
+ funct_sl << m_options.m_python_script.c_str();
+ StringList funct_name_sl;
+ if (!interpreter->GenerateTypeScriptFunction (funct_sl,
+ funct_name_sl))
{
- ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
- if (!interpreter)
- {
- result.AppendError ("Internal error #1N: no script attached.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- const char *funct_name = m_options.m_python_function.c_str();
- if (!funct_name || !funct_name[0])
- {
- result.AppendError ("Internal error #2N: no script attached.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- // now I have a valid function name, let's add this as script for every type in the list
-
- SummaryFormatSP script_format;
- script_format.reset(new ScriptSummaryFormat(m_options.m_cascade,
- m_options.m_skip_pointers,
- m_options.m_skip_references,
- true,
- true,
- false,
- std::string(funct_name),
- " " + m_options.m_python_function + "(valobj,dict)"));
-
- for (int i = 0; i < command.GetArgumentCount(); i++)
- {
- const char *type_name = command.GetArgumentAtIndex(i);
- Debugger::SummaryFormats::Add(ConstString(type_name), script_format);
- }
+ result.AppendError ("Internal error #2Q: no script attached.\n");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
}
- else if (m_options.m_python_script.empty()) // use an InputReader to grab Python code from the user
- {
- ScriptAddOptions *options = new ScriptAddOptions(m_options.m_skip_pointers,
- m_options.m_skip_references,
- m_options.m_cascade);
-
- for(int i = 0; i < argc; i++) {
- const char* typeA = command.GetArgumentAtIndex(i);
- if (typeA && *typeA)
- options->m_target_types << typeA;
- else
- {
- result.AppendError("empty typenames not allowed");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- }
-
- CollectPythonScript(options,result);
- return result.Succeeded();
+ if (funct_name_sl.GetSize() == 0)
+ {
+ result.AppendError ("Internal error #3Q: no script attached.\n");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
}
- else // we have a quick 1-line script, just use it
+ const char *funct_name = funct_name_sl.GetStringAtIndex(0);
+ if (!funct_name || !funct_name[0])
{
- ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
- if (!interpreter)
- {
- result.AppendError ("Internal error #1Q: no script attached.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- StringList funct_sl;
- funct_sl << m_options.m_python_script.c_str();
- StringList funct_name_sl;
- if (!interpreter->GenerateTypeScriptFunction (funct_sl,
- funct_name_sl))
- {
- result.AppendError ("Internal error #2Q: no script attached.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- if (funct_name_sl.GetSize() == 0)
- {
- result.AppendError ("Internal error #3Q: no script attached.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- const char *funct_name = funct_name_sl.GetStringAtIndex(0);
- if (!funct_name || !funct_name[0])
+ result.AppendError ("Internal error #4Q: no script attached.\n");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ script_format.reset(new ScriptSummaryFormat(m_options.m_cascade,
+ m_options.m_skip_pointers,
+ m_options.m_skip_references,
+ m_options.m_no_children,
+ m_options.m_no_value,
+ m_options.m_one_liner,
+ m_options.m_is_system,
+ std::string(funct_name),
+ " " + m_options.m_python_script));
+ }
+ else // use an InputReader to grab Python code from the user
+ {
+ ScriptAddOptions *options = new ScriptAddOptions(m_options.m_skip_pointers,
+ m_options.m_skip_references,
+ m_options.m_cascade,
+ m_options.m_no_children,
+ m_options.m_no_value,
+ m_options.m_one_liner,
+ m_options.m_regex,
+ m_options.m_is_system,
+ m_options.m_name);
+
+ for(int i = 0; i < argc; i++) {
+ const char* typeA = command.GetArgumentAtIndex(i);
+ if (typeA && *typeA)
+ options->m_target_types << typeA;
+ else
{
- result.AppendError ("Internal error #4Q: no script attached.\n");
- result.SetStatus (eReturnStatusFailed);
+ result.AppendError("empty typenames not allowed");
+ result.SetStatus(eReturnStatusFailed);
return false;
}
- // now I have a valid function name, let's add this as script for every type in the list
-
- ScriptFormatSP script_format;
- script_format.reset(new ScriptSummaryFormat(m_options.m_cascade,
- m_options.m_skip_pointers,
- m_options.m_skip_references,
- true,
- true,
- false,
- std::string(funct_name),
- " " + m_options.m_python_script));
-
- for (int i = 0; i < command.GetArgumentCount(); i++)
- {
- const char *type_name = command.GetArgumentAtIndex(i);
- Debugger::SummaryFormats::Add(ConstString(type_name), script_format);
- }
}
+ CollectPythonScript(options,result);
return result.Succeeded();
}
-
- bool
- Execute_StringSummary (Args& command, CommandReturnObject &result)
+
+ // if I am here, script_format must point to something good, so I can add that
+ // as a script summary to all interested parties
+
+ Error error;
+
+ for (int i = 0; i < command.GetArgumentCount(); i++)
{
- const size_t argc = command.GetArgumentCount();
-
- if (argc < 1 && !m_options.m_name)
+ const char *type_name = command.GetArgumentAtIndex(i);
+ CommandObjectTypeSummaryAdd::AddSummary(ConstString(type_name),
+ script_format,
+ (m_options.m_regex ? eRegexSummary : eRegularSummary),
+ m_options.m_is_system,
+ &error);
+ if (error.Fail())
{
- result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
+ result.AppendError(error.AsCString());
result.SetStatus(eReturnStatusFailed);
return false;
}
-
- if(!m_options.m_one_liner && m_options.m_format_string.empty())
+ }
+
+ if (m_options.m_name)
+ {
+ if ( (bool)(*(m_options.m_name)) )
{
- result.AppendError("empty summary strings not allowed");
+ AddSummary(*(m_options.m_name), script_format, eNamedSummary, m_options.m_is_system, &error);
+ if (error.Fail())
+ {
+ result.AppendError(error.AsCString());
+ result.AppendError("added to types, but not given a name");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+ else
+ {
+ result.AppendError("added to types, but not given a name");
result.SetStatus(eReturnStatusFailed);
return false;
}
-
- const char* format_cstr = (m_options.m_one_liner ? "" : m_options.m_format_string.c_str());
-
- Error error;
-
- SummaryFormat::SharedPointer entry(new StringSummaryFormat(m_options.m_cascade,
- m_options.m_skip_pointers,
- m_options.m_skip_references,
- m_options.m_no_children,
- m_options.m_no_value,
- m_options.m_one_liner,
- format_cstr));
-
- if (error.Fail())
+ }
+
+ return result.Succeeded();
+}
+
+bool
+CommandObjectTypeSummaryAdd::Execute_StringSummary (Args& command, CommandReturnObject &result)
+{
+ const size_t argc = command.GetArgumentCount();
+
+ if (argc < 1 && !m_options.m_name)
+ {
+ result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ if (!m_options.m_one_liner && m_options.m_format_string.empty())
+ {
+ result.AppendError("empty summary strings not allowed");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ const char* format_cstr = (m_options.m_one_liner ? "" : m_options.m_format_string.c_str());
+
+ Error error;
+
+ SummaryFormat::SharedPointer entry(new StringSummaryFormat(m_options.m_cascade,
+ m_options.m_skip_pointers,
+ m_options.m_skip_references,
+ m_options.m_no_children,
+ m_options.m_no_value,
+ m_options.m_one_liner,
+ m_options.m_is_system,
+ format_cstr));
+
+ if (error.Fail())
+ {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+
+ // now I have a valid format, let's add it to every type
+
+ for(int i = 0; i < argc; i++) {
+ const char* typeA = command.GetArgumentAtIndex(i);
+ if (!typeA || typeA[0] == '\0')
{
- result.AppendError(error.AsCString());
+ result.AppendError("empty typenames not allowed");
result.SetStatus(eReturnStatusFailed);
return false;
}
+ ConstString typeCS(typeA);
- // now I have a valid format, let's add it to every type
+ AddSummary(typeCS,
+ entry,
+ (m_options.m_regex ? eRegexSummary : eRegularSummary),
+ m_options.m_is_system,
+ &error);
- for(int i = 0; i < argc; i++) {
- const char* typeA = command.GetArgumentAtIndex(i);
- if (!typeA || typeA[0] == '\0')
- {
- result.AppendError("empty typenames not allowed");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- ConstString typeCS(typeA);
- if (!m_options.m_regex)
- {
- Debugger::SummaryFormats::Add(typeCS, entry);
- }
- else
- {
- RegularExpressionSP typeRX(new RegularExpression());
- if(!typeRX->Compile(typeA))
- {
- result.AppendError("regex format error (maybe this is not really a regex?)");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- Debugger::RegexSummaryFormats::Delete(typeCS);
- Debugger::RegexSummaryFormats::Add(typeRX, entry);
- }
+ if (error.Fail())
+ {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
-
- if (m_options.m_name)
+ }
+
+ if (m_options.m_name)
+ {
+ if ( (bool)(*(m_options.m_name)) )
{
- if( (bool)(*(m_options.m_name)) )
- {
- Debugger::NamedSummaryFormats::Add(*(m_options.m_name), entry);
- }
- else
+ AddSummary(*(m_options.m_name), entry, eNamedSummary, m_options.m_is_system, &error);
+ if (error.Fail())
{
+ result.AppendError(error.AsCString());
result.AppendError("added to types, but not given a name");
result.SetStatus(eReturnStatusFailed);
return false;
}
}
-
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- return result.Succeeded();
+ else
+ {
+ result.AppendError("added to types, but not given a name");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
}
-};
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return result.Succeeded();
+}
+
+CommandObjectTypeSummaryAdd::CommandObjectTypeSummaryAdd (CommandInterpreter &interpreter) :
+CommandObject (interpreter,
+ "type summary add",
+ "Add a new summary style for a type.",
+ NULL), m_options (interpreter)
+{
+ CommandArgumentEntry type_arg;
+ CommandArgumentData type_style_arg;
+
+ type_style_arg.arg_type = eArgTypeName;
+ type_style_arg.arg_repetition = eArgRepeatPlus;
+
+ type_arg.push_back (type_style_arg);
+
+ m_arguments.push_back (type_arg);
+
+ SetHelpLong(
+ "Some examples of using this command.\n"
+ "We use as reference the following snippet of code:\n"
+ "struct JustADemo\n"
+ "{\n"
+ "int* ptr;\n"
+ "float value;\n"
+ "JustADemo(int p = 1, float v = 0.1) : ptr(new int(p)), value(v) {}\n"
+ "};\n"
+ "JustADemo object(42,3.14);\n"
+ "struct AnotherDemo : public JustADemo\n"
+ "{\n"
+ "uint8_t byte;\n"
+ "AnotherDemo(uint8_t b = 'E', int p = 1, float v = 0.1) : JustADemo(p,v), byte(b) {}\n"
+ "};\n"
+ "AnotherDemo *another_object = new AnotherDemo('E',42,3.14);\n"
+ "\n"
+ "type summary add -f \"the answer is ${*var.ptr}\" JustADemo\n"
+ "when typing frame variable object you will get \"the answer is 42\"\n"
+ "type summary add -f \"the answer is ${*var.ptr}, and the question is ${var.value}\" JustADemo\n"
+ "when typing frame variable object you will get \"the answer is 42 and the question is 3.14\"\n"
+ "\n"
+ "Alternatively, you could also say\n"
+ "type summary add -f \"${var%V} -> ${*var}\" \"int *\"\n"
+ "and replace the above summary string with\n"
+ "type summary add -f \"the answer is ${var.ptr}, and the question is ${var.value}\" JustADemo\n"
+ "to obtain a similar result\n"
+ "\n"
+ "To add a summary valid for both JustADemo and AnotherDemo you can use the scoping operator, as in:\n"
+ "type summary add -f \"${var.ptr}, ${var.value},{${var.byte}}\" JustADemo -C yes\n"
+ "\n"
+ "This will be used for both variables of type JustADemo and AnotherDemo. To prevent this, change the -C to read -C no\n"
+ "If you do not want pointers to be shown using that summary, you can use the -p option, as in:\n"
+ "type summary add -f \"${var.ptr}, ${var.value},{${var.byte}}\" JustADemo -C yes -p\n"
+ "A similar option -r exists for references.\n"
+ "\n"
+ "If you simply want a one-line summary of the content of your variable, without typing an explicit string to that effect\n"
+ "you can use the -c option, without giving any summary string:\n"
+ "type summary add -c JustADemo\n"
+ "frame variable object\n"
+ "the output being similar to (ptr=0xsomeaddress, value=3.14)\n"
+ "\n"
+ "If you want to display some summary text, but also expand the structure of your object, you can add the -e option, as in:\n"
+ "type summary add -e -f \"*ptr = ${*var.ptr}\" JustADemo\n"
+ "Here the value of the int* is displayed, followed by the standard LLDB sequence of children objects, one per line.\n"
+ "to get an output like:\n"
+ "\n"
+ "*ptr = 42 {\n"
+ " ptr = 0xsomeaddress\n"
+ " value = 3.14\n"
+ "}\n"
+ "\n"
+ "A command you may definitely want to try if you're doing C++ debugging is:\n"
+ "type summary add -f \"${var._M_dataplus._M_p}\" std::string\n"
+ );
+}
+
+bool
+CommandObjectTypeSummaryAdd::Execute (Args& command, CommandReturnObject &result)
+{
+ if (m_options.m_is_add_script)
+ return Execute_ScriptSummary(command, result);
+ else
+ return Execute_StringSummary(command, result);
+}
+
+bool
+CommandObjectTypeSummaryAdd::AddSummary(const ConstString& type_name,
+ SummaryFormatSP entry,
+ SummaryFormatType type,
+ bool is_system,
+ Error* error)
+{
+ if (type == eRegexSummary)
+ {
+ RegularExpressionSP typeRX(new RegularExpression());
+ if (!typeRX->Compile(type_name.GetCString()))
+ {
+ if (error)
+ error->SetErrorString("regex format error (maybe this is not really a regex?)");
+ return false;
+ }
+
+ if (!is_system)
+ {
+ Debugger::RegexSummaryFormats::Delete(type_name);
+ Debugger::RegexSummaryFormats::Add(typeRX, entry);
+ }
+ else
+ {
+ Debugger::SystemRegexSummaryFormats::Delete(type_name);
+ Debugger::SystemRegexSummaryFormats::Add(typeRX, entry);
+ }
+ return true;
+ }
+ else if (type == eNamedSummary)
+ {
+ // system named summaries do not exist (yet?)
+ Debugger::NamedSummaryFormats::Add(type_name,entry);
+ return true;
+ }
+ else
+ {
+ if (!is_system)
+ Debugger::SummaryFormats::Add(type_name,entry);
+ else
+ Debugger::SystemSummaryFormats::Add(type_name,entry);
+ return true;
+ }
+}
OptionDefinition
CommandObjectTypeSummaryAdd::CommandOptions::g_option_table[] =
{
+ { LLDB_OPT_SET_ALL, false, "system", 'w', no_argument, NULL, 0, eArgTypeBoolean, "This is a system summary (makes it harder to delete it by accident)."},
{ LLDB_OPT_SET_ALL, false, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean, "If true, cascade to derived typedefs."},
{ LLDB_OPT_SET_ALL, false, "no-value", 'v', no_argument, NULL, 0, eArgTypeBoolean, "Don't show the value, just show the summary, for this type."},
{ LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeBoolean, "Don't use this format for pointers-to-type objects."},
@@ -1034,11 +1077,11 @@
{ LLDB_OPT_SET_ALL, false, "regex", 'x', no_argument, NULL, 0, eArgTypeBoolean, "Type names are actually regular expressions."},
{ LLDB_OPT_SET_1 , true, "inline-children", 'c', no_argument, NULL, 0, eArgTypeBoolean, "If true, inline all child values into summary string."},
{ LLDB_OPT_SET_2 , true, "format-string", 'f', required_argument, NULL, 0, eArgTypeSummaryString, "Format string used to display text and object contents."},
- { LLDB_OPT_SET_2, false, "expand", 'e', no_argument, NULL, 0, eArgTypeBoolean, "Expand aggregate data types to show children on separate lines."},
- { LLDB_OPT_SET_2, false, "name", 'n', required_argument, NULL, 0, eArgTypeName, "A name for this summary string."},
{ LLDB_OPT_SET_3, false, "python-script", 's', required_argument, NULL, 0, eArgTypeName, "Give a one-liner Python script as part of the command."},
{ LLDB_OPT_SET_3, false, "python-function", 'F', required_argument, NULL, 0, eArgTypeName, "Give the name of a Python function to use for this type."},
{ LLDB_OPT_SET_3, false, "input-python", 'P', no_argument, NULL, 0, eArgTypeName, "Input Python code to use for this type manually."},
+ { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "expand", 'e', no_argument, NULL, 0, eArgTypeBoolean, "Expand aggregate data types to show children on separate lines."},
+ { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "name", 'n', required_argument, NULL, 0, eArgTypeName, "A name for this summary string."},
{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
};
@@ -1049,12 +1092,73 @@
class CommandObjectTypeSummaryDelete : public CommandObject
{
+private:
+ class CommandOptions : public Options
+ {
+ public:
+
+ CommandOptions (CommandInterpreter &interpreter) :
+ Options (interpreter)
+ {
+ }
+
+ virtual
+ ~CommandOptions (){}
+
+ virtual Error
+ SetOptionValue (uint32_t option_idx, const char *option_arg)
+ {
+ Error error;
+ char short_option = (char) m_getopt_table[option_idx].val;
+
+ switch (short_option)
+ {
+ case 'a':
+ m_delete_system = true;
+ break;
+ default:
+ error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
+ break;
+ }
+
+ return error;
+ }
+
+ void
+ OptionParsingStarting ()
+ {
+ m_delete_system = false;
+ }
+
+ const OptionDefinition*
+ GetDefinitions ()
+ {
+ return g_option_table;
+ }
+
+ // Options table: Required for subclasses of Options.
+
+ static OptionDefinition g_option_table[];
+
+ // Instance variables to hold the values for command options.
+
+ bool m_delete_system;
+ };
+
+ CommandOptions m_options;
+
+ virtual Options *
+ GetOptions ()
+ {
+ return &m_options;
+ }
+
public:
CommandObjectTypeSummaryDelete (CommandInterpreter &interpreter) :
CommandObject (interpreter,
"type summary delete",
"Delete an existing summary style for a type.",
- NULL)
+ NULL), m_options(interpreter)
{
CommandArgumentEntry type_arg;
CommandArgumentData type_style_arg;
@@ -1087,7 +1191,7 @@
const char* typeA = command.GetArgumentAtIndex(0);
ConstString typeCS(typeA);
- if(!typeCS)
+ if (!typeCS)
{
result.AppendError("empty typenames not allowed");
result.SetStatus(eReturnStatusFailed);
@@ -1097,8 +1201,10 @@
bool delete_summary = Debugger::SummaryFormats::Delete(typeCS);
bool delete_regex = Debugger::RegexSummaryFormats::Delete(typeCS);
bool delete_named = Debugger::NamedSummaryFormats::Delete(typeCS);
+ bool delete_sys = m_options.m_delete_system ? Debugger::SystemSummaryFormats::Delete(typeCS) : false;
+ bool delete_sys_regex = m_options.m_delete_system ? Debugger::SystemRegexSummaryFormats::Delete(typeCS) : false;
- if (delete_summary || delete_regex || delete_named)
+ if (delete_summary || delete_regex || delete_named || delete_sys || delete_sys_regex)
{
result.SetStatus(eReturnStatusSuccessFinishNoResult);
return result.Succeeded();
@@ -1111,7 +1217,13 @@
}
}
-
+};
+
+OptionDefinition
+CommandObjectTypeSummaryDelete::CommandOptions::g_option_table[] =
+{
+ { LLDB_OPT_SET_ALL, false, "all", 'a', no_argument, NULL, 0, eArgTypeBoolean, "Also delete system summaries (not recommended)."},
+ { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
};
//-------------------------------------------------------------------------
@@ -1120,12 +1232,74 @@
class CommandObjectTypeSummaryClear : public CommandObject
{
+private:
+
+ class CommandOptions : public Options
+ {
+ public:
+
+ CommandOptions (CommandInterpreter &interpreter) :
+ Options (interpreter)
+ {
+ }
+
+ virtual
+ ~CommandOptions (){}
+
+ virtual Error
+ SetOptionValue (uint32_t option_idx, const char *option_arg)
+ {
+ Error error;
+ char short_option = (char) m_getopt_table[option_idx].val;
+
+ switch (short_option)
+ {
+ case 'a':
+ m_delete_system = true;
+ break;
+ default:
+ error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
+ break;
+ }
+
+ return error;
+ }
+
+ void
+ OptionParsingStarting ()
+ {
+ m_delete_system = false;
+ }
+
+ const OptionDefinition*
+ GetDefinitions ()
+ {
+ return g_option_table;
+ }
+
+ // Options table: Required for subclasses of Options.
+
+ static OptionDefinition g_option_table[];
+
+ // Instance variables to hold the values for command options.
+
+ bool m_delete_system;
+ };
+
+ CommandOptions m_options;
+
+ virtual Options *
+ GetOptions ()
+ {
+ return &m_options;
+ }
+
public:
CommandObjectTypeSummaryClear (CommandInterpreter &interpreter) :
CommandObject (interpreter,
"type summary clear",
"Delete all existing summary styles.",
- NULL)
+ NULL), m_options(interpreter)
{
}
@@ -1139,12 +1313,26 @@
Debugger::SummaryFormats::Clear();
Debugger::RegexSummaryFormats::Clear();
Debugger::NamedSummaryFormats::Clear();
+
+ if (m_options.m_delete_system)
+ {
+ Debugger::SystemSummaryFormats::Clear();
+ Debugger::SystemRegexSummaryFormats::Clear();
+ }
+
result.SetStatus(eReturnStatusSuccessFinishResult);
return result.Succeeded();
}
};
+OptionDefinition
+CommandObjectTypeSummaryClear::CommandOptions::g_option_table[] =
+{
+ { LLDB_OPT_SET_ALL, false, "all", 'a', no_argument, NULL, 0, eArgTypeBoolean, "Also clear system summaries (not recommended)."},
+ { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
+};
+
//-------------------------------------------------------------------------
// CommandObjectTypeSummaryList
//-------------------------------------------------------------------------
@@ -1210,9 +1398,10 @@
else
param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result);
Debugger::SummaryFormats::LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param);
+ Debugger::SystemSummaryFormats::LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param);
delete param;
- if(Debugger::RegexSummaryFormats::GetCount() > 0)
+ if (Debugger::RegexSummaryFormats::GetCount() > 0 || Debugger::SystemRegexSummaryFormats::GetCount() > 0 )
{
result.GetOutputStream().Printf("Regex-based summaries (slower):\n");
if (argc == 1) {
@@ -1223,10 +1412,11 @@
else
rxparam = new CommandObjectTypeRXSummaryList_LoopCallbackParam(this,&result);
Debugger::RegexSummaryFormats::LoopThrough(CommandObjectTypeRXSummaryList_LoopCallback, rxparam);
+ Debugger::SystemRegexSummaryFormats::LoopThrough(CommandObjectTypeRXSummaryList_LoopCallback, rxparam);
delete rxparam;
}
- if(Debugger::NamedSummaryFormats::GetCount() > 0)
+ if (Debugger::NamedSummaryFormats::GetCount() > 0)
{
result.GetOutputStream().Printf("Named summaries:\n");
if (argc == 1) {
@@ -1259,7 +1449,6 @@
friend bool CommandObjectTypeSummaryList_LoopCallback(void* pt2self, const char* type, const SummaryFormat::SharedPointer& entry);
friend bool CommandObjectTypeRXSummaryList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SummaryFormat::SharedPointer& entry);
-
};
bool
@@ -1282,7 +1471,6 @@
return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result);
}
-
class CommandObjectTypeFormat : public CommandObjectMultiword
{
public:
Modified: lldb/trunk/source/Commands/CommandObjectType.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectType.h?rev=135326&r1=135325&r2=135326&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectType.h (original)
+++ lldb/trunk/source/Commands/CommandObjectType.h Fri Jul 15 18:30:15 2011
@@ -19,13 +19,57 @@
#include "lldb/lldb-types.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
+#include "lldb/Interpreter/Options.h"
namespace lldb_private {
-//-------------------------------------------------------------------------
-// CommandObjectMultiwordBreakpoint
-//-------------------------------------------------------------------------
-
+class ScriptAddOptions
+{
+
+public:
+
+ bool m_skip_pointers;
+ bool m_skip_references;
+ bool m_cascade;
+ StringList m_target_types;
+ StringList m_user_source;
+
+ bool m_no_children;
+ bool m_no_value;
+ bool m_one_liner;
+ bool m_regex;
+
+ bool m_is_system;
+
+ ConstString* m_name;
+
+ ScriptAddOptions(bool sptr,
+ bool sref,
+ bool casc,
+ bool noch,
+ bool novl,
+ bool onel,
+ bool regx,
+ bool syst,
+ ConstString* name) :
+ m_skip_pointers(sptr),
+ m_skip_references(sref),
+ m_cascade(casc),
+ m_target_types(),
+ m_user_source(),
+ m_no_children(noch),
+ m_no_value(novl),
+ m_one_liner(onel),
+ m_regex(regx),
+ m_is_system(syst),
+ m_name(name)
+ {
+ }
+
+ typedef lldb::SharedPtr::Type SharedPointer;
+
+};
+
class CommandObjectType : public CommandObjectMultiword
{
public:
@@ -35,6 +79,99 @@
~CommandObjectType ();
};
+class CommandObjectTypeSummaryAdd : public CommandObject
+{
+
+private:
+
+ class CommandOptions : public Options
+ {
+ public:
+
+ CommandOptions (CommandInterpreter &interpreter) :
+ Options (interpreter)
+ {
+ }
+
+ virtual
+ ~CommandOptions (){}
+
+ virtual Error
+ SetOptionValue (uint32_t option_idx, const char *option_arg);
+
+ void
+ OptionParsingStarting ();
+
+ const OptionDefinition*
+ GetDefinitions ()
+ {
+ return g_option_table;
+ }
+
+ // Options table: Required for subclasses of Options.
+
+ static OptionDefinition g_option_table[];
+
+ // Instance variables to hold the values for command options.
+
+ bool m_cascade;
+ bool m_no_children;
+ bool m_no_value;
+ bool m_one_liner;
+ bool m_skip_references;
+ bool m_skip_pointers;
+ bool m_regex;
+ std::string m_format_string;
+ ConstString* m_name;
+ std::string m_python_script;
+ std::string m_python_function;
+ bool m_is_add_script;
+ bool m_is_system;
+ };
+
+ CommandOptions m_options;
+
+ virtual Options *
+ GetOptions ()
+ {
+ return &m_options;
+ }
+
+ void
+ CollectPythonScript(ScriptAddOptions *options,
+ CommandReturnObject &result);
+
+ bool
+ Execute_ScriptSummary (Args& command, CommandReturnObject &result);
+
+ bool
+ Execute_StringSummary (Args& command, CommandReturnObject &result);
+
+public:
+
+ enum SummaryFormatType
+ {
+ eRegularSummary,
+ eRegexSummary,
+ eNamedSummary,
+ };
+
+ CommandObjectTypeSummaryAdd (CommandInterpreter &interpreter);
+
+ ~CommandObjectTypeSummaryAdd ()
+ {
+ }
+
+ bool
+ Execute (Args& command, CommandReturnObject &result);
+
+ static bool
+ AddSummary(const ConstString& type_name,
+ lldb::SummaryFormatSP entry,
+ SummaryFormatType type,
+ bool is_system,
+ Error* error = NULL);
+};
} // namespace lldb_private
Modified: lldb/trunk/source/Core/Debugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=135326&r1=135325&r2=135326&view=diff
==============================================================================
--- lldb/trunk/source/Core/Debugger.cpp (original)
+++ lldb/trunk/source/Core/Debugger.cpp Fri Jul 15 18:30:15 2011
@@ -1798,6 +1798,48 @@
}
bool
+Debugger::SystemSummaryFormats::Get(ValueObject& vobj, SummaryFormat::SharedPointer &entry)
+{
+ return GetFormatManager().SystemSummary().Get(vobj,entry);
+}
+
+void
+Debugger::SystemSummaryFormats::Add(const ConstString &type, const SummaryFormat::SharedPointer &entry)
+{
+ GetFormatManager().SystemSummary().Add(type.AsCString(),entry);
+}
+
+bool
+Debugger::SystemSummaryFormats::Delete(const ConstString &type)
+{
+ return GetFormatManager().SystemSummary().Delete(type.AsCString());
+}
+
+void
+Debugger::SystemSummaryFormats::Clear()
+{
+ GetFormatManager().SystemSummary().Clear();
+}
+
+void
+Debugger::SystemSummaryFormats::LoopThrough(SummaryFormat::SummaryCallback callback, void* callback_baton)
+{
+ GetFormatManager().SystemSummary().LoopThrough(callback, callback_baton);
+}
+
+uint32_t
+Debugger::SystemSummaryFormats::GetCurrentRevision()
+{
+ return GetFormatManager().GetCurrentRevision();
+}
+
+uint32_t
+Debugger::SystemSummaryFormats::GetCount()
+{
+ return GetFormatManager().SystemSummary().GetCount();
+}
+
+bool
Debugger::RegexSummaryFormats::Get(ValueObject& vobj, SummaryFormat::SharedPointer &entry)
{
return GetFormatManager().RegexSummary().Get(vobj,entry);
@@ -1840,6 +1882,48 @@
}
bool
+Debugger::SystemRegexSummaryFormats::Get(ValueObject& vobj, SummaryFormat::SharedPointer &entry)
+{
+ return GetFormatManager().SystemRegexSummary().Get(vobj,entry);
+}
+
+void
+Debugger::SystemRegexSummaryFormats::Add(const lldb::RegularExpressionSP &type, const SummaryFormat::SharedPointer &entry)
+{
+ GetFormatManager().SystemRegexSummary().Add(type,entry);
+}
+
+bool
+Debugger::SystemRegexSummaryFormats::Delete(const ConstString &type)
+{
+ return GetFormatManager().SystemRegexSummary().Delete(type.AsCString());
+}
+
+void
+Debugger::SystemRegexSummaryFormats::Clear()
+{
+ GetFormatManager().SystemRegexSummary().Clear();
+}
+
+void
+Debugger::SystemRegexSummaryFormats::LoopThrough(SummaryFormat::RegexSummaryCallback callback, void* callback_baton)
+{
+ GetFormatManager().SystemRegexSummary().LoopThrough(callback, callback_baton);
+}
+
+uint32_t
+Debugger::SystemRegexSummaryFormats::GetCurrentRevision()
+{
+ return GetFormatManager().GetCurrentRevision();
+}
+
+uint32_t
+Debugger::SystemRegexSummaryFormats::GetCount()
+{
+ return GetFormatManager().SystemRegexSummary().GetCount();
+}
+
+bool
Debugger::NamedSummaryFormats::Get(const ConstString &type, SummaryFormat::SharedPointer &entry)
{
return GetFormatManager().NamedSummary().Get(type.AsCString(),entry);
Modified: lldb/trunk/source/Core/InputReaderEZ.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/InputReaderEZ.cpp?rev=135326&r1=135325&r2=135326&view=diff
==============================================================================
--- lldb/trunk/source/Core/InputReaderEZ.cpp (original)
+++ lldb/trunk/source/Core/InputReaderEZ.cpp Fri Jul 15 18:30:15 2011
@@ -75,6 +75,16 @@
echo);
}
+Error
+InputReaderEZ::Initialize(InitializationParameters& params)
+{
+ return Initialize(params.m_baton,
+ params.m_token_size,
+ params.m_end_token,
+ params.m_prompt,
+ params.m_echo);
+}
+
InputReaderEZ::~InputReaderEZ ()
{
}
\ No newline at end of file
Modified: lldb/trunk/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=135326&r1=135325&r2=135326&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObject.cpp (original)
+++ lldb/trunk/source/Core/ValueObject.cpp Fri Jul 15 18:30:15 2011
@@ -209,8 +209,14 @@
if (m_last_value_format.get())
m_last_value_format.reset((ValueFormat*)NULL);
Debugger::ValueFormats::Get(*this, m_last_value_format);
+ // to find a summary we look for a direct summary, then if there is none
+ // we look for a regex summary. if there is none we look for a system
+ // summary (direct), and if also that fails, we look for a system
+ // regex summary
if (!Debugger::SummaryFormats::Get(*this, m_last_summary_format))
- Debugger::RegexSummaryFormats::Get(*this, m_last_summary_format);
+ if (!Debugger::RegexSummaryFormats::Get(*this, m_last_summary_format))
+ if (!Debugger::SystemSummaryFormats::Get(*this, m_last_summary_format))
+ Debugger::SystemRegexSummaryFormats::Get(*this, m_last_summary_format);
m_last_format_mgr_revision = Debugger::ValueFormats::GetCurrentRevision();
ClearUserVisibleData();
@@ -518,7 +524,7 @@
{
clang_type_t clang_type = GetClangType();
- // See if this is a pointer to a C string?
+ // Do some default printout for function pointers
if (clang_type)
{
StreamString sstr;
@@ -530,116 +536,7 @@
ExecutionContextScope *exe_scope = GetExecutionContextScope();
if (exe_scope)
{
- if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
- ClangASTContext::IsCharType (elem_or_pointee_clang_type))
- {
- Target *target = exe_scope->CalculateTarget();
- if (target != NULL)
- {
- lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
- AddressType cstr_address_type = eAddressTypeInvalid;
-
- size_t cstr_len = 0;
- bool capped_data = false;
- if (type_flags.Test (ClangASTContext::eTypeIsArray))
- {
- // We have an array
- cstr_len = ClangASTContext::GetArraySize (clang_type);
- if (cstr_len > 512) // TODO: make cap a setting
- {
- cstr_len = ClangASTContext::GetArraySize (clang_type);
- if (cstr_len > 512) // TODO: make cap a setting
- {
- capped_data = true;
- cstr_len = 512;
- }
- }
- cstr_address = GetAddressOf (cstr_address_type, true);
- }
- else
- {
- // We have a pointer
- cstr_address = GetPointerValue (cstr_address_type, true);
- }
- if (cstr_address != LLDB_INVALID_ADDRESS)
- {
- Address cstr_so_addr (NULL, cstr_address);
- DataExtractor data;
- size_t bytes_read = 0;
- std::vector data_buffer;
- Error error;
- bool prefer_file_cache = false;
- if (cstr_len > 0)
- {
- data_buffer.resize(cstr_len);
- data.SetData (&data_buffer.front(), data_buffer.size(), lldb::endian::InlHostByteOrder());
- bytes_read = target->ReadMemory (cstr_so_addr,
- prefer_file_cache,
- &data_buffer.front(),
- cstr_len,
- error);
- if (bytes_read > 0)
- {
- sstr << '"';
- data.Dump (&sstr,
- 0, // Start offset in "data"
- eFormatCharArray, // Print as characters
- 1, // Size of item (1 byte for a char!)
- bytes_read, // How many bytes to print?
- UINT32_MAX, // num per line
- LLDB_INVALID_ADDRESS,// base address
- 0, // bitfield bit size
- 0); // bitfield bit offset
- if (capped_data)
- sstr << "...";
- sstr << '"';
- }
- }
- else
- {
- const size_t k_max_buf_size = 256;
- data_buffer.resize (k_max_buf_size + 1);
- // NULL terminate in case we don't get the entire C string
- data_buffer.back() = '\0';
-
- sstr << '"';
-
- data.SetData (&data_buffer.front(), data_buffer.size(), endian::InlHostByteOrder());
- while ((bytes_read = target->ReadMemory (cstr_so_addr,
- prefer_file_cache,
- &data_buffer.front(),
- k_max_buf_size,
- error)) > 0)
- {
- size_t len = strlen(&data_buffer.front());
- if (len == 0)
- break;
- if (len > bytes_read)
- len = bytes_read;
-
- data.Dump (&sstr,
- 0, // Start offset in "data"
- eFormatCharArray, // Print as characters
- 1, // Size of item (1 byte for a char!)
- len, // How many bytes to print?
- UINT32_MAX, // num per line
- LLDB_INVALID_ADDRESS,// base address
- 0, // bitfield bit size
- 0); // bitfield bit offset
-
- if (len < k_max_buf_size)
- break;
- cstr_so_addr.Slide (k_max_buf_size);
- }
- sstr << '"';
- }
- }
- }
-
- if (sstr.GetSize() > 0)
- m_summary_str.assign (sstr.GetData(), sstr.GetSize());
- }
- else if (ClangASTContext::IsFunctionPointerType (clang_type))
+ if (ClangASTContext::IsFunctionPointerType (clang_type))
{
AddressType func_ptr_address_type = eAddressTypeInvalid;
lldb::addr_t func_ptr_address = GetPointerValue (func_ptr_address_type, true);
@@ -988,7 +885,7 @@
RefCounter ref(&m_dump_printable_counter);
- if(custom_format != lldb::eFormatInvalid)
+ if (custom_format != lldb::eFormatInvalid)
SetFormat(custom_format);
const char * return_value;
@@ -1146,10 +1043,10 @@
return false;
}
const char *targetvalue = GetPrintableRepresentation(val_obj_display, custom_format);
- if(targetvalue)
+ if (targetvalue)
s.PutCString(targetvalue);
bool var_success = (targetvalue != NULL);
- if(custom_format != eFormatInvalid)
+ if (custom_format != eFormatInvalid)
SetFormat(eFormatDefault);
return var_success;
}
@@ -1624,7 +1521,7 @@
{
const bool is_deref_of_parent = IsDereferenceOfParent ();
- if(is_deref_of_parent && epformat == eDereferencePointers) {
+ if (is_deref_of_parent && epformat == eDereferencePointers) {
// this is the original format of GetExpressionPath() producing code like *(a_ptr).memberName, which is entirely
// fine, until you put this into StackFrame::GetValueForVariableExpressionPath() which prefers to see a_ptr->memberName.
// the eHonorPointers mode is meant to produce strings in this latter format
@@ -1639,7 +1536,7 @@
// if we are a deref_of_parent just because we are synthetic array
// members made up to allow ptr[%d] syntax to work in variable
// printing, then add our name ([%d]) to the expression path
- if(m_is_array_item_for_pointer && epformat == eHonorPointers)
+ if (m_is_array_item_for_pointer && epformat == eHonorPointers)
s.PutCString(m_name.AsCString());
if (!IsBaseClass())
@@ -1654,7 +1551,7 @@
{
const uint32_t non_base_class_parent_type_info = ClangASTContext::GetTypeInfo (non_base_class_parent_clang_type, NULL, NULL);
- if(parent && parent->IsDereferenceOfParent() && epformat == eHonorPointers)
+ if (parent && parent->IsDereferenceOfParent() && epformat == eHonorPointers)
{
s.PutCString("->");
}
@@ -2584,7 +2481,7 @@
if (val_cstr && (!entry || entry->DoesPrintValue() || !sum_cstr))
s.Printf(" %s", valobj->GetValueAsCString());
- if(sum_cstr)
+ if (sum_cstr)
{
// for some reason, using %@ (ObjC description) in a summary string, makes
// us believe we need to reset ourselves, thus invalidating the content of
Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=135326&r1=135325&r2=135326&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp Fri Jul 15 18:30:15 2011
@@ -117,7 +117,7 @@
clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
// We currently can't complete objective C types through the newly added ASTContext
// because it only supports TagDecl objects right now...
- if(class_interface_decl)
+ if (class_interface_decl)
{
bool is_forward_decl = class_interface_decl->isForwardDecl();
if (is_forward_decl && class_interface_decl->hasExternalLexicalStorage())
Modified: lldb/trunk/source/Symbol/TypeHierarchyNavigator.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/TypeHierarchyNavigator.cpp?rev=135326&r1=135325&r2=135326&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/TypeHierarchyNavigator.cpp (original)
+++ lldb/trunk/source/Symbol/TypeHierarchyNavigator.cpp Fri Jul 15 18:30:15 2011
@@ -61,7 +61,7 @@
*/
Error error;
ValueObject* target = m_value_object.Dereference(error).get();
- if(error.Fail() || !target)
+ if (error.Fail() || !target)
return true;
if (LoopThrough(typePtr->getPointeeType(), callback, eStrippedPointer, callback_baton) == false)
return false;
@@ -73,10 +73,10 @@
if (ClangASTContext::GetCompleteType(ast, m_value_object.GetClangType()) && !objc_class_type->isObjCId())
{
clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
- if(class_interface_decl)
+ if (class_interface_decl)
{
clang::ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
- if(superclass_interface_decl)
+ if (superclass_interface_decl)
{
clang::QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl));
return LoopThrough(ivar_qual_type, callback, eObjCBaseClass, callback_baton);
@@ -95,7 +95,7 @@
if (record->hasDefinition())
{
clang::CXXRecordDecl::base_class_iterator pos,end;
- if( record->getNumBases() > 0)
+ if ( record->getNumBases() > 0)
{
end = record->bases_end();
for (pos = record->bases_begin(); pos != end; pos++)
Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py?rev=135326&r1=135325&r2=135326&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py Fri Jul 15 18:30:15 2011
@@ -56,7 +56,7 @@
# Set the script here to ease the formatting
script = 'a = valobj.GetChildMemberWithName(\'integer\'); a_val = a.GetValue(); str = \'Hello from Python, \' + a_val + \' time\'; return str + (\'!\' if a_val == \'1\' else \'s!\');'
- self.runCmd("type summary add add i_am_cool -s \"%s\"" % script)
+ self.runCmd("type summary add i_am_cool -s \"%s\"" % script)
self.expect("frame variable one",
substrs = ['Hello from Python',
@@ -85,6 +85,9 @@
self.expect("frame variable two",
substrs = ['int says 1'])
+
+ self.expect("frame variable twoptr",
+ substrs = ['int says 1'])
# Change the summary
self.runCmd("type summary add -f \"int says ${var.integer}, and float says ${var.floating}\" i_am_cool")
@@ -103,6 +106,72 @@
self.expect("frame variable twoptr", matching=False,
substrs = ['and float says 2.71'])
+ script = 'return \'Python summary\'';
+
+ self.runCmd("type summary add --name test_summary -s \"%s\"" % script)
+
+ # attach the Python named summary to someone
+ self.runCmd("frame variable one --summary test_summary")
+
+ self.expect("frame variable one",
+ substrs = ['Python summary'])
+
+ # should not bind to the type
+ self.expect("frame variable two", matching=False,
+ substrs = ['Python summary'])
+
+ self.runCmd("type summary add i_am_cool -f \"Text summary\"")
+
+ self.expect("frame variable one",
+ substrs = ['Python summary'])
+
+ # use the type summary
+ self.expect("frame variable two",
+ substrs = ['Text summary'])
+
+ self.runCmd("n"); # skip ahead to make values change
+
+ # both should use the type summary now
+ self.expect("frame variable one",
+ substrs = ['Text summary'])
+
+ self.expect("frame variable two",
+ substrs = ['Text summary'])
+
+ # disable type summary for pointers, and make a Python regex summary
+ self.runCmd("type summary add i_am_cool -p -f \"Text summary\"")
+ self.runCmd("type summary add -x cool -s \"%s\"" % script)
+
+ # variables should stick to the type summary
+ self.expect("frame variable one",
+ substrs = ['Text summary'])
+
+ self.expect("frame variable two",
+ substrs = ['Text summary'])
+
+ # array and pointer should match the Python one
+ self.expect("frame variable twoptr",
+ substrs = ['Python summary'])
+
+ self.expect("frame variable array",
+ substrs = ['Python summary'])
+
+ # return pointers to the type summary
+ self.runCmd("type summary add i_am_cool -f \"Text summary\"")
+
+ self.expect("frame variable one",
+ substrs = ['Text summary'])
+
+ self.expect("frame variable two",
+ substrs = ['Text summary'])
+
+ self.expect("frame variable twoptr",
+ substrs = ['Text summary'])
+
+ self.expect("frame variable array",
+ substrs = ['Python summary'])
+
+
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-script/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-script/main.cpp?rev=135326&r1=135325&r2=135326&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-script/main.cpp (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-script/main.cpp Fri Jul 15 18:30:15 2011
@@ -41,9 +41,13 @@
i_am_cool* twoptr = &two;
+ i_am_cool array[5];
+
i_am_cooler three(10,4,1985,1/1/2011,'B','E'); // Set break point at this line.
two.integer = 1;
+ int dummy = 1;
+
return 0;
}
\ No newline at end of file
From scallanan at apple.com Fri Jul 15 19:49:19 2011
From: scallanan at apple.com (Sean Callanan)
Date: Sat, 16 Jul 2011 00:49:19 -0000
Subject: [Lldb-commits] [lldb] r135331 - in /lldb/trunk:
include/lldb/Core/RegisterValue.h
tools/debugserver/debugserver.xcodeproj/project.pbxproj
tools/debugserver/source/MacOSX/HasAVX.h
tools/debugserver/source/MacOSX/HasAVX.s
tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h
tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h
Message-ID: <20110716004919.EC05C312800A@llvm.org>
Author: spyffe
Date: Fri Jul 15 19:49:19 2011
New Revision: 135331
URL: http://llvm.org/viewvc/llvm-project?rev=135331&view=rev
Log:
Added support for dynamic detection of AVX, and
fixed a few bugs that revealed. Now the "register
read" command should show AVX registers
(ymm0-ymm15) on Mac OS X platforms that support
them.
When testing this on Mac OS X, run debugserver
manually, like this:
debugserver --native-regs localhost:1111 /path/to/executable
Then
lldb /path/to/executable
...
(lldb) process connect connect://localhost:1111
Added:
lldb/trunk/tools/debugserver/source/MacOSX/HasAVX.h
lldb/trunk/tools/debugserver/source/MacOSX/HasAVX.s
Modified:
lldb/trunk/include/lldb/Core/RegisterValue.h
lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj
lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h
lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h
Modified: lldb/trunk/include/lldb/Core/RegisterValue.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/RegisterValue.h?rev=135331&r1=135330&r2=135331&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/RegisterValue.h (original)
+++ lldb/trunk/include/lldb/Core/RegisterValue.h Fri Jul 15 19:49:19 2011
@@ -28,7 +28,7 @@
public:
enum
{
- kMaxRegisterByteSize = 16u
+ kMaxRegisterByteSize = 32u
};
enum Type
{
Modified: lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj?rev=135331&r1=135330&r2=135331&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj Fri Jul 15 19:49:19 2011
@@ -41,6 +41,7 @@
26CE05C5115C36590022F371 /* CFBundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2695DD910D3EBFF6007E4CA2 /* CFBundle.cpp */; };
26CE05CF115C36F70022F371 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26ACA3340D3E956300A2120B /* CoreFoundation.framework */; };
26CE05F1115C387C0022F371 /* PseudoTerminal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF67ABFF0D34604D0022D128 /* PseudoTerminal.cpp */; };
+ 4971AE7213D10F4F00649E37 /* HasAVX.s in Sources */ = {isa = PBXBuildFile; fileRef = 4971AE7113D10F4F00649E37 /* HasAVX.s */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@@ -125,6 +126,8 @@
26CF99A21142EB7400011AAB /* DNBArchImplX86_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DNBArchImplX86_64.cpp; sourceTree = ""; };
26CF99A31142EB7400011AAB /* DNBArchImplX86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DNBArchImplX86_64.h; sourceTree = ""; };
26E6B9DA0D1329010037ECDD /* RNBDefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNBDefs.h; sourceTree = ""; };
+ 4971AE7013D10F4F00649E37 /* HasAVX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HasAVX.h; sourceTree = ""; };
+ 4971AE7113D10F4F00649E37 /* HasAVX.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = HasAVX.s; sourceTree = ""; };
49F530111331519C008956F6 /* MachRegisterStatesI386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachRegisterStatesI386.h; sourceTree = ""; };
49F5301213316D7F008956F6 /* MachRegisterStatesX86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachRegisterStatesX86_64.h; sourceTree = ""; };
AF67ABFF0D34604D0022D128 /* PseudoTerminal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PseudoTerminal.cpp; sourceTree = ""; };
@@ -278,6 +281,8 @@
26C637E90C71334A0024798E /* i386 */,
26C637FA0C71334A0024798E /* ppc */,
26CF99A11142EB7400011AAB /* x86_64 */,
+ 4971AE7013D10F4F00649E37 /* HasAVX.h */,
+ 4971AE7113D10F4F00649E37 /* HasAVX.s */,
26C637E80C71334A0024798E /* dbgnub-mig.defs */,
26C637ED0C71334A0024798E /* MachDYLD.h */,
26C637EC0C71334A0024798E /* MachDYLD.cpp */,
@@ -452,6 +457,7 @@
26CE05F1115C387C0022F371 /* PseudoTerminal.cpp in Sources */,
2660D9CE1192280900958FBD /* StringExtractor.cpp in Sources */,
264D5D581293835600ED4C01 /* DNBArch.cpp in Sources */,
+ 4971AE7213D10F4F00649E37 /* HasAVX.s in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Added: lldb/trunk/tools/debugserver/source/MacOSX/HasAVX.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/HasAVX.h?rev=135331&view=auto
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/HasAVX.h (added)
+++ lldb/trunk/tools/debugserver/source/MacOSX/HasAVX.h Fri Jul 15 19:49:19 2011
@@ -0,0 +1,27 @@
+//===-- HasAVX.h ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef HasAVX_h
+#define HasAVX_h
+
+#if defined (__i386__) || defined (__x86_64__)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int HasAVX ();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
Added: lldb/trunk/tools/debugserver/source/MacOSX/HasAVX.s
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/HasAVX.s?rev=135331&view=auto
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/HasAVX.s (added)
+++ lldb/trunk/tools/debugserver/source/MacOSX/HasAVX.s Fri Jul 15 19:49:19 2011
@@ -0,0 +1,32 @@
+//===-- HasAVX.s ---------------------------------------*- x86 Assembly -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#if defined (__i386__) || defined (__x86_64__)
+
+.globl _HasAVX
+
+_HasAVX:
+ mov $1, %eax
+ cpuid
+ and $0x018000000, %ecx
+ cmp $0x018000000, %ecx
+ jne not_supported
+ mov $0, %ecx
+.byte 0x0f, 0x01, 0xd0 // xgetbv, for those assemblers that don't know it
+ and $0x06, %eax
+ cmp $0x06, %eax
+ jne not_supported
+ mov $1, %eax
+ jmp done
+not_supported:
+ mov $0, %eax
+done:
+ ret
+
+#endif
\ No newline at end of file
Modified: lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp?rev=135331&r1=135330&r2=135331&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp Fri Jul 15 19:49:19 2011
@@ -330,7 +330,7 @@
{
if (DEBUG_FPU_REGS)
{
- if (HasAVX() || FORCE_AVX_REGS)
+ if (CPUHasAVX() || FORCE_AVX_REGS)
{
m_state.context.fpu.avx.__fpu_reserved[0] = -1;
m_state.context.fpu.avx.__fpu_reserved[1] = -1;
@@ -460,7 +460,7 @@
}
else
{
- if (HasAVX() || FORCE_AVX_REGS)
+ if (CPUHasAVX() || FORCE_AVX_REGS)
{
mach_msg_type_number_t count = e_regSetWordSizeAVX;
m_state.SetError(e_regSetFPU, Read, ::thread_get_state(m_thread->ThreadID(), __i386_AVX_STATE, (thread_state_t)&m_state.context.fpu.avx, &count));
@@ -503,7 +503,7 @@
}
else
{
- if (HasAVX() || FORCE_AVX_REGS)
+ if (CPUHasAVX() || FORCE_AVX_REGS)
m_state.SetError(e_regSetFPU, Write, ::thread_set_state(m_thread->ThreadID(), __i386_AVX_STATE, (thread_state_t)&m_state.context.fpu.avx, e_regSetWordSizeAVX));
else
m_state.SetError(e_regSetFPU, Write, ::thread_set_state(m_thread->ThreadID(), __i386_FLOAT_STATE, (thread_state_t)&m_state.context.fpu.no_avx, e_regSetWordSizeFPR));
@@ -813,7 +813,7 @@
DNBArchImplI386::GetRegisterSetInfo(nub_size_t *num_reg_sets)
{
*num_reg_sets = k_num_register_sets;
- if (HasAVX() || FORCE_AVX_REGS)
+ if (CPUHasAVX() || FORCE_AVX_REGS)
return g_reg_sets_avx;
else
return g_reg_sets_no_avx;
@@ -886,7 +886,7 @@
break;
case e_regSetFPU:
- if (HasAVX() || FORCE_AVX_REGS)
+ if (CPUHasAVX() || FORCE_AVX_REGS)
{
switch (reg)
{
@@ -1033,7 +1033,7 @@
break;
case e_regSetFPU:
- if (HasAVX() || FORCE_AVX_REGS)
+ if (CPUHasAVX() || FORCE_AVX_REGS)
{
switch (reg)
{
Modified: lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h?rev=135331&r1=135330&r2=135331&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h Fri Jul 15 19:49:19 2011
@@ -17,6 +17,7 @@
#if defined (__i386__) || defined (__x86_64__)
#include "DNBArch.h"
+#include "../HasAVX.h"
#include "MachRegisterStatesI386.h"
class MachThread;
@@ -199,10 +200,10 @@
GetRegisterSetInfo(nub_size_t *num_reg_sets);
static bool
- HasAVX()
+ CPUHasAVX()
{
if (s_has_avx == kAVXUnknown)
- s_has_avx = kAVXNotPresent;
+ s_has_avx = (::HasAVX() ? kAVXPresent : kAVXNotPresent);
return (s_has_avx == kAVXPresent);
}
Modified: lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp?rev=135331&r1=135330&r2=135331&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp Fri Jul 15 19:49:19 2011
@@ -213,7 +213,7 @@
if (force || m_state.GetError(e_regSetFPU, Read))
{
if (DEBUG_FPU_REGS) {
- if (HasAVX() || FORCE_AVX_REGS)
+ if (CPUHasAVX() || FORCE_AVX_REGS)
{
m_state.context.fpu.avx.__fpu_reserved[0] = -1;
m_state.context.fpu.avx.__fpu_reserved[1] = -1;
@@ -365,7 +365,7 @@
}
else
{
- if (HasAVX() || FORCE_AVX_REGS)
+ if (CPUHasAVX() || FORCE_AVX_REGS)
{
mach_msg_type_number_t count = e_regSetWordSizeAVX;
m_state.SetError(e_regSetFPU, Read, ::thread_get_state(m_thread->ThreadID(), __x86_64_AVX_STATE, (thread_state_t)&m_state.context.fpu.avx, &count));
@@ -427,7 +427,7 @@
}
else
{
- if (HasAVX() || FORCE_AVX_REGS)
+ if (CPUHasAVX() || FORCE_AVX_REGS)
{
m_state.SetError(e_regSetFPU, Write, ::thread_set_state(m_thread->ThreadID(), __x86_64_AVX_STATE, (thread_state_t)&m_state.context.fpu.avx, e_regSetWordSizeAVX));
return m_state.GetError(e_regSetFPU, Write);
@@ -1013,7 +1013,7 @@
{
*num_reg_sets = k_num_register_sets;
- if (HasAVX() || FORCE_AVX_REGS)
+ if (CPUHasAVX() || FORCE_AVX_REGS)
return g_reg_sets_avx;
else
return g_reg_sets_no_avx;
@@ -1085,7 +1085,7 @@
break;
case e_regSetFPU:
- if (HasAVX() || FORCE_AVX_REGS)
+ if (CPUHasAVX() || FORCE_AVX_REGS)
{
switch (reg)
{
@@ -1264,7 +1264,7 @@
break;
case e_regSetFPU:
- if (HasAVX() || FORCE_AVX_REGS)
+ if (CPUHasAVX() || FORCE_AVX_REGS)
{
switch (reg)
{
Modified: lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h?rev=135331&r1=135330&r2=135331&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h Fri Jul 15 19:49:19 2011
@@ -16,6 +16,7 @@
#if defined (__i386__) || defined (__x86_64__)
#include "DNBArch.h"
+#include "../HasAVX.h"
#include "MachRegisterStatesX86_64.h"
class MachThread;
@@ -206,10 +207,10 @@
GetRegisterSetInfo(nub_size_t *num_reg_sets);
static bool
- HasAVX()
+ CPUHasAVX()
{
if (s_has_avx == kAVXUnknown)
- s_has_avx = kAVXNotPresent;
+ s_has_avx = (::HasAVX() ? kAVXPresent : kAVXNotPresent);
return (s_has_avx == kAVXPresent);
}
From granata.enrico at gmail.com Fri Jul 15 20:22:04 2011
From: granata.enrico at gmail.com (Enrico Granata)
Date: Sat, 16 Jul 2011 01:22:04 -0000
Subject: [Lldb-commits] [lldb] r135336 - in /lldb/trunk: include/lldb/Core/
include/lldb/Interpreter/ source/API/ source/Commands/ source/Core/
source/Interpreter/
test/functionalities/data-formatter/data-formatter-skip-summary/
Message-ID: <20110716012204.B8CF4312800A@llvm.org>
Author: enrico
Date: Fri Jul 15 20:22:04 2011
New Revision: 135336
URL: http://llvm.org/viewvc/llvm-project?rev=135336&view=rev
Log:
Some descriptive text for the Python script feature:
- help type summary add now gives some hints on how to use it
frame variable and target variable now have a --no-summary-depth (-Y) option:
- simply using -Y without an argument will skip one level of summaries, i.e.
your aggregate types will expand their children and display no summary, even
if they have one. children will behave normally
- using -Y, as in -Y4, -Y7, ..., will skip as many levels of summaries as
given by the parameter (obviously, -Y and -Y1 are the same thing). children
beneath the given depth level will behave normally
-Y0 is the same as omitting the --no-summary-depth parameter entirely
This option replaces the defined-but-unimplemented --no-summary
Added:
lldb/trunk/test/functionalities/data-formatter/data-formatter-skip-summary/
lldb/trunk/test/functionalities/data-formatter/data-formatter-skip-summary/Makefile
lldb/trunk/test/functionalities/data-formatter/data-formatter-skip-summary/TestDataFormatterSkipSummary.py
lldb/trunk/test/functionalities/data-formatter/data-formatter-skip-summary/main.cpp
Modified:
lldb/trunk/include/lldb/Core/ValueObject.h
lldb/trunk/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h
lldb/trunk/source/API/SBValue.cpp
lldb/trunk/source/Commands/CommandObjectExpression.cpp
lldb/trunk/source/Commands/CommandObjectFrame.cpp
lldb/trunk/source/Commands/CommandObjectMemory.cpp
lldb/trunk/source/Commands/CommandObjectTarget.cpp
lldb/trunk/source/Commands/CommandObjectType.cpp
lldb/trunk/source/Core/ValueObject.cpp
lldb/trunk/source/Interpreter/OptionGroupValueObjectDisplay.cpp
Modified: lldb/trunk/include/lldb/Core/ValueObject.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=135336&r1=135335&r2=135336&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObject.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObject.h Fri Jul 15 20:22:04 2011
@@ -593,7 +593,8 @@
bool use_objc,
lldb::DynamicValueType use_dynamic,
bool scope_already_checked,
- bool flat_output);
+ bool flat_output,
+ uint32_t omit_summary_depth);
// returns true if this is a char* or a char[]
// if it is a char* and check_pointer is true,
Modified: lldb/trunk/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h?rev=135336&r1=135335&r2=135336&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h (original)
+++ lldb/trunk/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h Fri Jul 15 20:22:04 2011
@@ -47,7 +47,7 @@
OptionParsingStarting (CommandInterpreter &interpreter);
bool show_types;
- bool show_summary;
+ uint32_t no_summary_depth;
bool show_location;
bool flat_output;
bool use_objc;
Modified: lldb/trunk/source/API/SBValue.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBValue.cpp?rev=135336&r1=135335&r2=135336&view=diff
==============================================================================
--- lldb/trunk/source/API/SBValue.cpp (original)
+++ lldb/trunk/source/API/SBValue.cpp Fri Jul 15 20:22:04 2011
@@ -658,7 +658,8 @@
use_objc,
use_dynamic,
scope_already_checked,
- flat_output);
+ flat_output,
+ 0);
}
else
description.Printf ("No value");
Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?rev=135336&r1=135335&r2=135336&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectExpression.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectExpression.cpp Fri Jul 15 20:22:04 2011
@@ -329,7 +329,8 @@
m_options.print_object, // Print the objective C object?
use_dynamic,
true, // Scope is already checked. Const results are always in scope.
- false); // Don't flatten output
+ false, // Don't flatten output
+ 0); // Always use summaries (you might want an option --no-summary like there is for frame variable)
if (result)
result->SetStatus (eReturnStatusSuccessFinishResult);
}
Modified: lldb/trunk/source/Commands/CommandObjectFrame.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectFrame.cpp?rev=135336&r1=135335&r2=135336&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectFrame.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectFrame.cpp Fri Jul 15 20:22:04 2011
@@ -501,7 +501,8 @@
m_varobj_options.use_objc,
m_varobj_options.use_dynamic,
false,
- m_varobj_options.flat_output);
+ m_varobj_options.flat_output,
+ m_varobj_options.no_summary_depth);
}
}
}
@@ -552,7 +553,8 @@
m_varobj_options.use_objc,
m_varobj_options.use_dynamic,
false,
- m_varobj_options.flat_output);
+ m_varobj_options.flat_output,
+ m_varobj_options.no_summary_depth);
}
else
{
@@ -642,7 +644,8 @@
m_varobj_options.use_objc,
m_varobj_options.use_dynamic,
false,
- m_varobj_options.flat_output);
+ m_varobj_options.flat_output,
+ m_varobj_options.no_summary_depth);
}
}
}
Modified: lldb/trunk/source/Commands/CommandObjectMemory.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectMemory.cpp?rev=135336&r1=135335&r2=135336&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectMemory.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectMemory.cpp Fri Jul 15 20:22:04 2011
@@ -658,7 +658,8 @@
m_varobj_options.use_objc,
m_varobj_options.use_dynamic,
scope_already_checked,
- m_varobj_options.flat_output);
+ m_varobj_options.flat_output,
+ 0);
}
else
{
Modified: lldb/trunk/source/Commands/CommandObjectTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectTarget.cpp?rev=135336&r1=135335&r2=135336&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectTarget.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectTarget.cpp Fri Jul 15 20:22:04 2011
@@ -489,7 +489,8 @@
m_varobj_options.use_objc,
m_varobj_options.use_dynamic,
false,
- m_varobj_options.flat_output);
+ m_varobj_options.flat_output,
+ m_varobj_options.no_summary_depth);
}
Modified: lldb/trunk/source/Commands/CommandObjectType.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectType.cpp?rev=135336&r1=135335&r2=135336&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectType.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectType.cpp Fri Jul 15 20:22:04 2011
@@ -1009,6 +1009,18 @@
"\n"
"A command you may definitely want to try if you're doing C++ debugging is:\n"
"type summary add -f \"${var._M_dataplus._M_p}\" std::string\n"
+ "\n"
+ "You can also add Python summaries, in which case you will use lldb public API to gather information from your variables"
+ "and elaborate them to a meaningful summary inside a script written in Python. The variable object will be passed to your"
+ "script as an SBValue object. The following example might help you when starting to use the Python summaries feature:\n"
+ "type summary add JustADemo -s \"value = valobj.GetChildMemberWithName('value'); return 'My value is ' + value.GetValue();\"\n"
+ "If you prefer to type your scripts on multiple lines, you will use the -P option and then type your script, ending it with "
+ "the word DONE on a line by itself to mark you're finished editing your code:\n"
+ "(lldb)type summary add JustADemo -P\n"
+ " value = valobj.GetChildMemberWithName('value');\n"
+ " return 'My value is ' + value.GetValue();\n"
+ "DONE\n"
+ "(lldb)"
);
}
Modified: lldb/trunk/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=135336&r1=135335&r2=135336&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObject.cpp (original)
+++ lldb/trunk/source/Core/ValueObject.cpp Fri Jul 15 20:22:04 2011
@@ -2398,7 +2398,8 @@
bool use_objc,
lldb::DynamicValueType use_dynamic,
bool scope_already_checked,
- bool flat_output
+ bool flat_output,
+ uint32_t omit_summary_depth
)
{
if (valobj)
@@ -2458,6 +2459,9 @@
const char *sum_cstr = NULL;
SummaryFormat* entry = valobj->GetSummaryFormat().get();
+ if (omit_summary_depth > 0)
+ entry = NULL;
+
if (err_cstr == NULL)
{
val_cstr = valobj->GetValueAsCString();
@@ -2474,7 +2478,7 @@
if (print_valobj)
{
- sum_cstr = valobj->GetSummaryAsCString();
+ sum_cstr = (omit_summary_depth == 0) ? valobj->GetSummaryAsCString() : NULL;
// We must calculate this value in realtime because entry might alter this variable's value
// (e.g. by saying ${var%fmt}) and render precached values useless
@@ -2571,7 +2575,8 @@
false,
use_dynamic,
true,
- flat_output);
+ flat_output,
+ omit_summary_depth > 1 ? omit_summary_depth - 1 : 0);
}
}
Modified: lldb/trunk/source/Interpreter/OptionGroupValueObjectDisplay.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/OptionGroupValueObjectDisplay.cpp?rev=135336&r1=135335&r2=135336&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/OptionGroupValueObjectDisplay.cpp (original)
+++ lldb/trunk/source/Interpreter/OptionGroupValueObjectDisplay.cpp Fri Jul 15 20:22:04 2011
@@ -38,7 +38,7 @@
{ LLDB_OPT_SET_1, false, "objc", 'O', no_argument, NULL, 0, eArgTypeNone, "Print as an Objective-C object."},
{ LLDB_OPT_SET_1, false, "ptr-depth", 'P', required_argument, NULL, 0, eArgTypeCount, "The number of pointers to be traversed when dumping values (default is zero)."},
{ LLDB_OPT_SET_1, false, "show-types", 'T', no_argument, NULL, 0, eArgTypeNone, "Show variable types when dumping values."},
- { LLDB_OPT_SET_1, false, "no-summary", 'Y', no_argument, NULL, 0, eArgTypeNone, "Omit summary information."},
+ { LLDB_OPT_SET_1, false, "no-summary-depth",'Y', optional_argument, NULL, 0, eArgTypeCount, "Set a depth for omitting summary information (default is 1)."},
{ 0, false, NULL, 0, 0, NULL, NULL, eArgTypeNone, NULL }
};
@@ -80,7 +80,6 @@
}
break;
case 'T': show_types = true; break;
- case 'Y': show_summary = false; break;
case 'L': show_location= true; break;
case 'F': flat_output = true; break;
case 'O': use_objc = true; break;
@@ -96,6 +95,17 @@
error.SetErrorStringWithFormat("Invalid pointer depth '%s'.\n", option_arg);
break;
+ case 'Y':
+ if (option_arg)
+ {
+ no_summary_depth = Args::StringToUInt32 (option_arg, 0, 0, &success);
+ if (!success)
+ error.SetErrorStringWithFormat("Invalid pointer depth '%s'.\n", option_arg);
+ }
+ else
+ no_summary_depth = 1;
+ break;
+
default:
error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
break;
@@ -107,13 +117,13 @@
void
OptionGroupValueObjectDisplay::OptionParsingStarting (CommandInterpreter &interpreter)
{
- show_types = false;
- show_summary = true;
- show_location = false;
- flat_output = false;
- use_objc = false;
- max_depth = UINT32_MAX;
- ptr_depth = 0;
+ show_types = false;
+ no_summary_depth = 0;
+ show_location = false;
+ flat_output = false;
+ use_objc = false;
+ max_depth = UINT32_MAX;
+ ptr_depth = 0;
Target *target = interpreter.GetExecutionContext().target;
if (target != NULL)
Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-skip-summary/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-skip-summary/Makefile?rev=135336&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-skip-summary/Makefile (added)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-skip-summary/Makefile Fri Jul 15 20:22:04 2011
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-skip-summary/TestDataFormatterSkipSummary.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-skip-summary/TestDataFormatterSkipSummary.py?rev=135336&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-skip-summary/TestDataFormatterSkipSummary.py (added)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-skip-summary/TestDataFormatterSkipSummary.py Fri Jul 15 20:22:04 2011
@@ -0,0 +1,169 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+
+class DataFormatterTestCase(TestBase):
+
+ mydir = os.path.join("functionalities", "data-formatter", "data-formatter-skip-summary")
+
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ def test_with_dsym_and_run_command(self):
+ """Test data formatter commands."""
+ self.buildDsym()
+ self.data_formatter_commands()
+
+ def test_with_dwarf_and_run_command(self):
+ """Test data formatter commands."""
+ self.buildDwarf()
+ self.data_formatter_commands()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break at.
+ self.line = line_number('main.cpp', '// Set break point at this line.')
+
+ def data_formatter_commands(self):
+ """Test that that file and class static variables display correctly."""
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ self.expect("breakpoint set -f main.cpp -l %d" % self.line,
+ BREAKPOINT_CREATED,
+ startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" %
+ self.line)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # This is the function to remove the custom formats in order to have a
+ # clean slate for the next test case.
+ def cleanup():
+ self.runCmd('type format clear', check=False)
+ self.runCmd('type summary clear', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ # Setup the summaries for this scenario
+ self.runCmd("type summary add -f \"${var._M_dataplus._M_p}\" std::string") # This works fine on OSX 10.6.8, if it differs on your implementation, submit a patch to adapt it to your C++ stdlib
+ self.runCmd("type summary add -f \"Level 1\" \"DeepData_1\"")
+ self.runCmd("type summary add -f \"Level 2\" \"DeepData_2\" -e")
+ self.runCmd("type summary add -f \"Level 3\" \"DeepData_3\"")
+ self.runCmd("type summary add -f \"Level 4\" \"DeepData_4\"")
+ self.runCmd("type summary add -f \"Level 5\" \"DeepData_5\"")
+
+ # Default case, just print out summaries
+ self.expect('frame variable',
+ substrs = ['(DeepData_1) data1 = Level 1',
+ '(DeepData_2) data2 = Level 2 {',
+ 'm_child1 = Level 3',
+ 'm_child2 = Level 3',
+ 'm_child3 = Level 3',
+ 'm_child4 = Level 3',
+ '}'])
+
+ # Skip the default (should be 1) levels of summaries
+ self.expect('frame variable -Y',
+ substrs = ['(DeepData_1) data1 = {',
+ 'm_child1 = 0x',
+ '}',
+ '(DeepData_2) data2 = {',
+ 'm_child1 = Level 3',
+ 'm_child2 = Level 3',
+ 'm_child3 = Level 3',
+ 'm_child4 = Level 3',
+ '}'])
+
+ # Now skip 2 levels of summaries
+ self.expect('frame variable -Y2',
+ substrs = ['(DeepData_1) data1 = {',
+ 'm_child1 = 0x',
+ '}',
+ '(DeepData_2) data2 = {',
+ 'm_child1 = {',
+ 'm_child1 = 0x',
+ 'Level 4',
+ 'm_child2 = {',
+ 'm_child3 = {',
+ '}'])
+
+ # Check that no "Level 3" comes out
+ self.expect('frame variable data1.m_child1 -Y2', matching=False,
+ substrs = ['Level 3'])
+
+ # Now expand a pointer with 2 level of skipped summaries
+ self.expect('frame variable data1.m_child1 -Y2',
+ substrs = ['(DeepData_2 *) data1.m_child1 = 0x'])
+
+ # Deref and expand said pointer
+ self.expect('frame variable *data1.m_child1 -Y2',
+ substrs = ['(DeepData_2) *data1.m_child1 = {',
+ 'm_child2 = {',
+ 'm_child1 = 0x',
+ 'Level 4',
+ '}'])
+
+ # Expand an expression, skipping 2 layers of summaries
+ self.expect('frame variable data1.m_child1->m_child2 -Y2',
+ substrs = ['(DeepData_3) data1.m_child1->m_child2 = {',
+ 'm_child2 = {',
+ 'm_child1 = Level 5',
+ 'm_child2 = Level 5',
+ 'm_child3 = Level 5',
+ '}'])
+
+ # Expand same expression, skipping only 1 layer of summaries
+ self.expect('frame variable data1.m_child1->m_child2 -Y1',
+ substrs = ['(DeepData_3) data1.m_child1->m_child2 = {',
+ 'm_child1 = 0x',
+ 'Level 4',
+ 'm_child2 = Level 4',
+ '}'])
+
+ # Expand same expression, skipping 3 layers of summaries
+ self.expect('frame variable data1.m_child1->m_child2 -Y3',
+ substrs = ['(DeepData_3) data1.m_child1->m_child2 = {',
+ 'm_some_text = "Just a test"',
+ 'm_child2 = {',
+ 'm_some_text = "Just a test"'])
+
+ # Expand within a standard string (might depend on the implementation of the C++ stdlib you use)
+ self.expect('frame variable data1.m_child1->m_child2.m_child1.m_child2 -Y2',
+ substrs = ['(DeepData_5) data1.m_child1->m_child2.m_child1.m_child2 = {',
+ 'm_some_text = {',
+ '_M_dataplus = {',
+ '_M_p = 0x',
+ '"Just a test"'])
+
+ # Repeat the above, but only skip 1 level of summaries
+ self.expect('frame variable data1.m_child1->m_child2.m_child1.m_child2 -Y1',
+ substrs = ['(DeepData_5) data1.m_child1->m_child2.m_child1.m_child2 = {',
+ 'm_some_text = "Just a test"',
+ '}'])
+
+ # Change summary and expand, first without -Y then with -Y
+ self.runCmd("type summary add -f \"${var.m_some_text}\" DeepData_5")
+
+ self.expect('fr var data2.m_child4.m_child2.m_child2',
+ substrs = ['(DeepData_5) data2.m_child4.m_child2.m_child2 = "Just a test"'])
+
+ self.expect('fr var data2.m_child4.m_child2.m_child2 -Y',
+ substrs = ['(DeepData_5) data2.m_child4.m_child2.m_child2 = {',
+ 'm_some_text = "Just a test"',
+ '}'])
+
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-skip-summary/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-skip-summary/main.cpp?rev=135336&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-skip-summary/main.cpp (added)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-skip-summary/main.cpp Fri Jul 15 20:22:04 2011
@@ -0,0 +1,57 @@
+#include
+
+struct DeepData_5
+{
+ std::string m_some_text;
+ DeepData_5() :
+ m_some_text("Just a test") {}
+};
+
+struct DeepData_4
+{
+ DeepData_5 m_child1;
+ DeepData_5 m_child2;
+ DeepData_5 m_child3;
+};
+
+struct DeepData_3
+{
+ DeepData_4& m_child1;
+ DeepData_4 m_child2;
+
+ DeepData_3() : m_child1(* (new DeepData_4())), m_child2(DeepData_4()) {}
+};
+
+struct DeepData_2
+{
+ DeepData_3 m_child1;
+ DeepData_3 m_child2;
+ DeepData_3 m_child3;
+ DeepData_3 m_child4;
+};
+
+struct DeepData_1
+{
+ DeepData_2 *m_child1;
+
+ DeepData_1() :
+ m_child1(new DeepData_2())
+ {}
+};
+
+/*
+ type summary add -f "${var._M_dataplus._M_p}" std::string
+ type summary add -f "Level 1" "DeepData_1"
+ type summary add -f "Level 2" "DeepData_2" -e
+ type summary add -f "Level 3" "DeepData_3"
+ type summary add -f "Level 4" "DeepData_4"
+ type summary add -f "Level 5" "DeepData_5"
+ */
+
+int main()
+{
+ DeepData_1 data1;
+ DeepData_2 data2;
+
+ return 0; // Set break point at this line.
+}
\ No newline at end of file
From gclayton at apple.com Fri Jul 15 22:19:08 2011
From: gclayton at apple.com (Greg Clayton)
Date: Sat, 16 Jul 2011 03:19:08 -0000
Subject: [Lldb-commits] [lldb] r135338 - in /lldb/trunk:
include/lldb/Core/ConnectionFileDescriptor.h
include/lldb/Core/DataExtractor.h include/lldb/Core/StreamBuffer.h
include/lldb/Core/StreamString.h include/lldb/lldb-forward.h
lldb.xcodeproj/project.pbxproj source/Core/ConnectionFileDescriptor.cpp
source/Core/DataExtractor.cpp source/Core/StreamString.cpp
source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
Message-ID: <20110716031909.042AA312800A@llvm.org>
Author: gclayton
Date: Fri Jul 15 22:19:08 2011
New Revision: 135338
URL: http://llvm.org/viewvc/llvm-project?rev=135338&view=rev
Log:
Completed more work on the KDP darwin kernel debugging Process plug-in.
Implemented connect, disconnect, reattach, version, and hostinfo.
Modified the ConnectionFileDescriptor class to be able to handle UDP.
Added a new Stream subclass called StreamBuffer that is backed by a
llvm::SmallVector for better efficiency.
Modified the DataExtractor class to have a static function that can
dump hex bytes into a stream. This is currently being used to dump incoming
binary packet data in the KDP plug-in.
Added:
lldb/trunk/include/lldb/Core/StreamBuffer.h
Modified:
lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h
lldb/trunk/include/lldb/Core/DataExtractor.h
lldb/trunk/include/lldb/Core/StreamString.h
lldb/trunk/include/lldb/lldb-forward.h
lldb/trunk/lldb.xcodeproj/project.pbxproj
lldb/trunk/source/Core/ConnectionFileDescriptor.cpp
lldb/trunk/source/Core/DataExtractor.cpp
lldb/trunk/source/Core/StreamString.cpp
lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
Modified: lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h?rev=135338&r1=135337&r2=135338&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h (original)
+++ lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h Fri Jul 15 22:19:08 2011
@@ -11,6 +11,10 @@
#define liblldb_ConnectionFileDescriptor_h_
// C Includes
+#include
+#include
+#include
+
// C++ Includes
// Other libraries and framework includes
// Project includes
@@ -75,8 +79,16 @@
lldb::ConnectionStatus
Close (int& fd, Error *error);
+ typedef enum
+ {
+ eFDTypeFile, // Other FD requireing read/write
+ eFDTypeSocket, // Socket requiring send/recv
+ eFDTypeSocketUDP // Unconnected UDP socket requiring sendto/recvfrom
+ } FDType;
int m_fd; // Socket we use to communicate once conn established
- bool m_is_socket;
+ FDType m_fd_type;
+ struct sockaddr_storage m_udp_sockaddr;
+ socklen_t m_udp_sockaddr_len;
bool m_should_close_fd; // True if this class should close the file descriptor when it goes away.
uint32_t m_socket_timeout_usec;
Modified: lldb/trunk/include/lldb/Core/DataExtractor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/DataExtractor.h?rev=135338&r1=135337&r2=135338&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/DataExtractor.h (original)
+++ lldb/trunk/include/lldb/Core/DataExtractor.h Fri Jul 15 22:19:08 2011
@@ -54,6 +54,11 @@
TypeSLEB128 ///< Format output as SLEB128 numbers
} Type;
+ static void
+ DumpHexBytes (Stream *s,
+ const void *src,
+ size_t src_len,
+ lldb::addr_t base_addr = LLDB_INVALID_ADDRESS);
//------------------------------------------------------------------
/// Default constructor.
///
Added: lldb/trunk/include/lldb/Core/StreamBuffer.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/StreamBuffer.h?rev=135338&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Core/StreamBuffer.h (added)
+++ lldb/trunk/include/lldb/Core/StreamBuffer.h Fri Jul 15 22:19:08 2011
@@ -0,0 +1,83 @@
+//===-- StreamBuffer.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_StreamBuffer_h_
+#define liblldb_StreamBuffer_h_
+
+#include
+#include
+#include "llvm/ADT/SmallVector.h"
+#include "lldb/Core/Stream.h"
+
+namespace lldb_private {
+
+template
+class StreamBuffer : public Stream
+{
+public:
+ StreamBuffer () :
+ Stream (0, 4, lldb::eByteOrderBig),
+ m_packet ()
+ {
+ }
+
+
+ StreamBuffer (uint32_t flags,
+ uint32_t addr_size,
+ lldb::ByteOrder byte_order) :
+ Stream (flags, addr_size, byte_order),
+ m_packet ()
+ {
+ }
+
+ virtual
+ ~StreamBuffer ()
+ {
+ }
+
+ virtual void
+ Flush ()
+ {
+ // Nothing to do when flushing a buffer based stream...
+ }
+
+ virtual int
+ Write (const void *s, size_t length)
+ {
+ if (s && length)
+ m_packet.append ((const char *)s, ((const char *)s) + length);
+ return length;
+ }
+
+ void
+ Clear()
+ {
+ m_packet.clear();
+ }
+
+ const char *
+ GetData () const
+ {
+ return m_packet.data();
+ }
+
+ size_t
+ GetSize() const
+ {
+ return m_packet.size();
+ }
+
+protected:
+ llvm::SmallVector m_packet;
+
+};
+
+} // namespace lldb_private
+
+#endif // #ifndef liblldb_StreamBuffer_h_
Modified: lldb/trunk/include/lldb/Core/StreamString.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/StreamString.h?rev=135338&r1=135337&r2=135338&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/StreamString.h (original)
+++ lldb/trunk/include/lldb/Core/StreamString.h Fri Jul 15 22:19:08 2011
@@ -37,9 +37,6 @@
void
Clear();
- void
- Dump(FILE *f);
-
const char *
GetData () const;
Modified: lldb/trunk/include/lldb/lldb-forward.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward.h?rev=135338&r1=135337&r2=135338&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-forward.h (original)
+++ lldb/trunk/include/lldb/lldb-forward.h Fri Jul 15 22:19:08 2011
@@ -129,6 +129,7 @@
class StoppointCallbackContext;
class StoppointLocation;
class Stream;
+template class StreamBuffer;
class StreamFile;
class StreamString;
class StringList;
Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=135338&r1=135337&r2=135338&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Fri Jul 15 22:19:08 2011
@@ -638,6 +638,7 @@
261B5A5311C3F2AD00AABD0A /* SharingPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SharingPtr.h; path = include/lldb/Utility/SharingPtr.h; sourceTree = ""; };
26217930133BC8640083B112 /* lldb-private-types.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "lldb-private-types.h"; path = "include/lldb/lldb-private-types.h"; sourceTree = ""; };
26217932133BCB850083B112 /* lldb-private-enumerations.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "lldb-private-enumerations.h"; path = "include/lldb/lldb-private-enumerations.h"; sourceTree = ""; };
+ 2623096E13D0EFFB006381D9 /* StreamBuffer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = StreamBuffer.h; path = include/lldb/Core/StreamBuffer.h; sourceTree = ""; };
263664921140A4930075843B /* Debugger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = Debugger.cpp; path = source/Core/Debugger.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
263664941140A4C10075843B /* Debugger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = Debugger.h; path = include/lldb/Core/Debugger.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
26368A3B126B697600E8659F /* darwin-debug.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "darwin-debug.cpp"; path = "tools/darwin-debug/darwin-debug.cpp"; sourceTree = ""; };
@@ -2003,6 +2004,7 @@
26BC7E9110F1B85900F91463 /* Stream.cpp */,
9A4F35111368A54100823F52 /* StreamAsynchronousIO.h */,
9A4F350F1368A51A00823F52 /* StreamAsynchronousIO.cpp */,
+ 2623096E13D0EFFB006381D9 /* StreamBuffer.h */,
26BC7D7A10F1B77400F91463 /* StreamFile.h */,
26BC7E9210F1B85900F91463 /* StreamFile.cpp */,
26BC7D7B10F1B77400F91463 /* StreamString.h */,
Modified: lldb/trunk/source/Core/ConnectionFileDescriptor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ConnectionFileDescriptor.cpp?rev=135338&r1=135337&r2=135338&view=diff
==============================================================================
--- lldb/trunk/source/Core/ConnectionFileDescriptor.cpp (original)
+++ lldb/trunk/source/Core/ConnectionFileDescriptor.cpp Fri Jul 15 22:19:08 2011
@@ -38,33 +38,42 @@
ConnectionFileDescriptor::ConnectionFileDescriptor () :
Connection(),
m_fd (-1),
- m_is_socket (false),
+ m_fd_type (eFDTypeFile),
+ m_udp_sockaddr (),
+ m_udp_sockaddr_len (0),
m_should_close_fd (false),
m_socket_timeout_usec(0)
{
+ memset (&m_udp_sockaddr, 0, sizeof(m_udp_sockaddr));
+
lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT,
- "%p ConnectionFileDescriptor::ConnectionFileDescriptor ()",
- this);
+ "%p ConnectionFileDescriptor::ConnectionFileDescriptor ()",
+ this);
}
ConnectionFileDescriptor::ConnectionFileDescriptor (int fd, bool owns_fd) :
Connection(),
m_fd (fd),
- m_is_socket (false),
+ m_fd_type (eFDTypeFile),
+ m_udp_sockaddr (),
+ m_udp_sockaddr_len (0),
m_should_close_fd (owns_fd),
m_socket_timeout_usec(0)
{
+ memset (&m_udp_sockaddr, 0, sizeof(m_udp_sockaddr));
lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT,
- "%p ConnectionFileDescriptor::ConnectionFileDescriptor (fd = %i, owns_fd = %i)",
- this, fd, owns_fd);
+ "%p ConnectionFileDescriptor::ConnectionFileDescriptor (fd = %i, owns_fd = %i)",
+ this,
+ fd,
+ owns_fd);
}
ConnectionFileDescriptor::~ConnectionFileDescriptor ()
{
lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT,
- "%p ConnectionFileDescriptor::~ConnectionFileDescriptor ()",
- this);
+ "%p ConnectionFileDescriptor::~ConnectionFileDescriptor ()",
+ this);
Disconnect (NULL);
}
@@ -78,8 +87,9 @@
ConnectionFileDescriptor::Connect (const char *s, Error *error_ptr)
{
lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION,
- "%p ConnectionFileDescriptor::Connect (url = '%s')",
- this, s);
+ "%p ConnectionFileDescriptor::Connect (url = '%s')",
+ this,
+ s);
if (s && s[0])
{
@@ -134,7 +144,9 @@
// Try and get a socket option from this file descriptor to
// see if this is a socket and set m_is_socket accordingly.
int resuse;
- m_is_socket = GetSocketOption (m_fd, SOL_SOCKET, SO_REUSEADDR, resuse) == 0;
+ bool is_socket = GetSocketOption (m_fd, SOL_SOCKET, SO_REUSEADDR, resuse) == 0;
+ if (is_socket)
+ m_fd_type = eFDTypeSocket;
m_should_close_fd = true;
return eConnectionStatusSuccess;
}
@@ -204,28 +216,40 @@
log->Printf ("%p ConnectionFileDescriptor::Read () ::read (fd = %i, dst = %p, dst_len = %zu)...",
this, m_fd, dst, dst_len);
- if (timeout_usec == UINT32_MAX)
- {
- if (m_is_socket && SetSocketReceiveTimeout (timeout_usec))
+ ssize_t bytes_read = 0;
+ struct sockaddr_storage from;
+ socklen_t from_len = sizeof(from);
+
+ switch (m_fd_type)
+ {
+ case eFDTypeFile: // Other FD requireing read/write
+ status = BytesAvailable (timeout_usec, error_ptr);
+ if (status == eConnectionStatusSuccess)
+ bytes_read = ::read (m_fd, dst, dst_len);
+ break;
+
+ case eFDTypeSocket: // Socket requiring send/recv
+ if (SetSocketReceiveTimeout (timeout_usec))
+ {
status = eConnectionStatusSuccess;
- }
- else
- {
- if (m_is_socket && SetSocketReceiveTimeout (timeout_usec))
+ bytes_read = ::recv (m_fd, dst, dst_len, 0);
+ }
+ break;
+
+ case eFDTypeSocketUDP: // Unconnected UDP socket requiring sendto/recvfrom
+ if (SetSocketReceiveTimeout (timeout_usec))
+ {
status = eConnectionStatusSuccess;
- else
- status = BytesAvailable (timeout_usec, error_ptr);
+ ::memset (&from, 0, sizeof(from));
+ bytes_read = ::recvfrom (m_fd, dst, dst_len, 0, (struct sockaddr *)&from, &from_len);
+ }
+ break;
}
+
if (status != eConnectionStatusSuccess)
return 0;
Error error;
- ssize_t bytes_read;
- if (m_is_socket)
- bytes_read = ::recv (m_fd, dst, dst_len, 0);
- else
- bytes_read = ::read (m_fd, dst, dst_len);
-
if (bytes_read == 0)
{
error.Clear(); // End-of-file. Do not automatically close; pass along for the end-of-file handlers.
@@ -319,10 +343,26 @@
ssize_t bytes_sent = 0;
- if (m_is_socket)
- bytes_sent = ::send (m_fd, src, src_len, 0);
- else
- bytes_sent = ::write (m_fd, src, src_len);
+ switch (m_fd_type)
+ {
+ case eFDTypeFile: // Other FD requireing read/write
+ bytes_sent = ::write (m_fd, src, src_len);
+ break;
+
+ case eFDTypeSocket: // Socket requiring send/recv
+ bytes_sent = ::send (m_fd, src, src_len, 0);
+ break;
+
+ case eFDTypeSocketUDP: // Unconnected UDP socket requiring sendto/recvfrom
+ assert (m_udp_sockaddr_len != 0);
+ bytes_sent = ::sendto (m_fd,
+ src,
+ src_len,
+ 0,
+ (struct sockaddr *)&m_udp_sockaddr,
+ m_udp_sockaddr_len);
+ break;
+ }
if (bytes_sent < 0)
error.SetErrorToErrno ();
@@ -331,12 +371,38 @@
if (log)
{
- if (m_is_socket)
- log->Printf ("%p ConnectionFileDescriptor::Write() ::send (socket = %i, src = %p, src_len = %zu, flags = 0) => %zi (error = %s)",
- this, m_fd, src, src_len, bytes_sent, error.AsCString());
- else
- log->Printf ("%p ConnectionFileDescriptor::Write() ::write (fd = %i, src = %p, src_len = %zu) => %zi (error = %s)",
- this, m_fd, src, src_len, bytes_sent, error.AsCString());
+ switch (m_fd_type)
+ {
+ case eFDTypeFile: // Other FD requireing read/write
+ log->Printf ("%p ConnectionFileDescriptor::Write() ::write (fd = %i, src = %p, src_len = %zu) => %zi (error = %s)",
+ this,
+ m_fd,
+ src,
+ src_len,
+ bytes_sent,
+ error.AsCString());
+ break;
+
+ case eFDTypeSocket: // Socket requiring send/recv
+ log->Printf ("%p ConnectionFileDescriptor::Write() ::send (socket = %i, src = %p, src_len = %zu, flags = 0) => %zi (error = %s)",
+ this,
+ m_fd,
+ src,
+ src_len,
+ bytes_sent,
+ error.AsCString());
+ break;
+
+ case eFDTypeSocketUDP: // Unconnected UDP socket requiring sendto/recvfrom
+ log->Printf ("%p ConnectionFileDescriptor::Write() ::sendto (socket = %i, src = %p, src_len = %zu, flags = 0) => %zi (error = %s)",
+ this,
+ m_fd,
+ src,
+ src_len,
+ bytes_sent,
+ error.AsCString());
+ break;
+ }
}
if (error_ptr)
@@ -477,7 +543,7 @@
}
fd = -1;
}
- m_is_socket = false;
+ m_fd_type = eFDTypeFile;
if (success)
return eConnectionStatusSuccess;
else
@@ -490,7 +556,7 @@
ConnectionStatus result = eConnectionStatusError;
struct sockaddr_un saddr_un;
- m_is_socket = true;
+ m_fd_type = eFDTypeSocket;
int listen_socket = ::socket (AF_UNIX, SOCK_STREAM, 0);
if (listen_socket == -1)
@@ -537,7 +603,7 @@
ConnectionFileDescriptor::NamedSocketConnect (const char *socket_name, Error *error_ptr)
{
Close (m_fd, NULL);
- m_is_socket = true;
+ m_fd_type = eFDTypeSocket;
// Open the socket that was passed in as an option
struct sockaddr_un saddr_un;
@@ -576,7 +642,7 @@
this, listen_port_num);
Close (m_fd, NULL);
- m_is_socket = true;
+ m_fd_type = eFDTypeSocket;
int listen_port = ::socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (listen_port == -1)
{
@@ -640,7 +706,7 @@
"%p ConnectionFileDescriptor::ConnectTCP (host/port = %s)",
this, host_and_port);
Close (m_fd, NULL);
- m_is_socket = true;
+ m_fd_type = eFDTypeSocket;
RegularExpression regex ("([^:]+):([0-9]+)");
if (regex.Execute (host_and_port, 2) == false)
@@ -730,7 +796,7 @@
"%p ConnectionFileDescriptor::ConnectUDP (host/port = %s)",
this, host_and_port);
Close (m_fd, NULL);
- m_is_socket = true;
+ m_fd_type = eFDTypeSocketUDP;
RegularExpression regex ("([^:]+):([0-9]+)");
if (regex.Execute (host_and_port, 2) == false)
@@ -839,20 +905,27 @@
bool
ConnectionFileDescriptor::SetSocketReceiveTimeout (uint32_t timeout_usec)
{
- if (m_is_socket)
+ switch (m_fd_type)
{
- // Check in case timeout for m_fd has already been set to this value
- if (timeout_usec == m_socket_timeout_usec)
- return true;
- //printf ("ConnectionFileDescriptor::SetSocketReceiveTimeout (timeout_usec = %u)\n", timeout_usec);
-
- struct timeval timeout;
- timeout.tv_sec = timeout_usec / TimeValue::MicroSecPerSec;
- timeout.tv_usec = timeout_usec % TimeValue::MicroSecPerSec;
- if (::setsockopt (m_fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) == 0)
+ case eFDTypeFile: // Other FD requireing read/write
+ break;
+
+ case eFDTypeSocket: // Socket requiring send/recv
+ case eFDTypeSocketUDP: // Unconnected UDP socket requiring sendto/recvfrom
{
- m_socket_timeout_usec = timeout_usec;
- return true;
+ // Check in case timeout for m_fd has already been set to this value
+ if (timeout_usec == m_socket_timeout_usec)
+ return true;
+ //printf ("ConnectionFileDescriptor::SetSocketReceiveTimeout (timeout_usec = %u)\n", timeout_usec);
+
+ struct timeval timeout;
+ timeout.tv_sec = timeout_usec / TimeValue::MicroSecPerSec;
+ timeout.tv_usec = timeout_usec % TimeValue::MicroSecPerSec;
+ if (::setsockopt (m_fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) == 0)
+ {
+ m_socket_timeout_usec = timeout_usec;
+ return true;
+ }
}
}
return false;
Modified: lldb/trunk/source/Core/DataExtractor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/DataExtractor.cpp?rev=135338&r1=135337&r2=135338&view=diff
==============================================================================
--- lldb/trunk/source/Core/DataExtractor.cpp (original)
+++ lldb/trunk/source/Core/DataExtractor.cpp Fri Jul 15 22:19:08 2011
@@ -1789,4 +1789,19 @@
}
}
-
+void
+DataExtractor::DumpHexBytes (Stream *s,
+ const void *src,
+ size_t src_len,
+ addr_t base_addr)
+{
+ DataExtractor data (src, src_len, eByteOrderLittle, 4);
+ data.Dump (s,
+ 0, // Offset into "src"
+ eFormatBytes, // Dump as hex bytes
+ 1, // Size of each item is 1 for single bytes
+ src_len, // Number of bytes
+ 32, // Num bytes per line
+ base_addr, // Base address
+ 0, 0); // Bitfield info
+}
Modified: lldb/trunk/source/Core/StreamString.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/StreamString.cpp?rev=135338&r1=135337&r2=135338&view=diff
==============================================================================
--- lldb/trunk/source/Core/StreamString.cpp (original)
+++ lldb/trunk/source/Core/StreamString.cpp Fri Jul 15 22:19:08 2011
@@ -47,14 +47,6 @@
m_packet.clear();
}
-void
-StreamString::Dump(FILE *f)
-{
- int size = GetSize();
- if (size > 0)
- fprintf(f, "%*.*s", size, size, m_packet.c_str());
-}
-
const char *
StreamString::GetData () const
{
Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp?rev=135338&r1=135337&r2=135338&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp Fri Jul 15 22:19:08 2011
@@ -16,14 +16,13 @@
// C++ Includes
// Other libraries and framework includes
+#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Log.h"
-#include "lldb/Core/StreamString.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/TimeValue.h"
#include "lldb/Target/Process.h"
-#include "Utility/StringExtractor.h"
// Project includes
#include "ProcessKDPLog.h"
@@ -38,13 +37,19 @@
//----------------------------------------------------------------------
CommunicationKDP::CommunicationKDP (const char *comm_name) :
Communication(comm_name),
+ m_byte_order (eByteOrderLittle),
m_packet_timeout (1),
m_sequence_mutex (Mutex::eMutexTypeRecursive),
m_public_is_running (false),
m_private_is_running (false),
- m_session_key (0),
- m_request_sequence_id (0),
- m_exception_sequence_id (0)
+ m_session_key (0u),
+ m_request_sequence_id (0u),
+ m_exception_sequence_id (0u),
+ m_kdp_version_version (0u),
+ m_kdp_version_feature (0u),
+ m_kdp_hostinfo_cpu_mask (0u),
+ m_kdp_hostinfo_cpu_type (0u),
+ m_kdp_hostinfo_cpu_subtype (0u)
{
}
@@ -60,27 +65,61 @@
}
bool
-CommunicationKDP::SendRequestPacket (const StreamString &request_packet)
+CommunicationKDP::SendRequestPacket (const PacketStreamType &request_packet)
{
Mutex::Locker locker(m_sequence_mutex);
return SendRequestPacketNoLock (request_packet);
}
+#if 0
+typedef struct {
+ uint8_t request; // Either: CommandType | ePacketTypeRequest, or CommandType | ePacketTypeReply
+ uint8_t sequence;
+ uint16_t length; // Length of entire packet including this header
+ uint32_t key; // Session key
+} kdp_hdr_t;
+#endif
+
void
-CommunicationKDP::MakeRequestPacketHeader (RequestType request_type,
- StreamString &request_packet)
+CommunicationKDP::MakeRequestPacketHeader (CommandType request_type,
+ PacketStreamType &request_packet,
+ uint16_t request_length)
{
request_packet.Clear();
- request_packet.PutHex32 (request_type); // Set the request type
- request_packet.PutHex8 (ePacketTypeRequest); // Set the packet type
- request_packet.PutHex8 (++m_request_sequence_id); // Sequence number
- request_packet.PutHex16 (0); // Pad1 and Pad2 bytes
- request_packet.PutHex32 (m_session_key); // Session key
+ request_packet.PutHex8 (request_type | ePacketTypeRequest); // Set the request type
+ request_packet.PutHex8 (m_request_sequence_id++); // Sequence number
+ request_packet.PutHex16 (request_length); // Length of the packet including this header
+ request_packet.PutHex32 (m_session_key); // Session key
}
+bool
+CommunicationKDP::SendRequestAndGetReply (const CommandType command,
+ const uint8_t request_sequence_id,
+ const PacketStreamType &request_packet,
+ DataExtractor &reply_packet)
+{
+
+ Mutex::Locker locker(m_sequence_mutex);
+ if (SendRequestPacketNoLock(request_packet))
+ {
+ if (WaitForPacketWithTimeoutMicroSecondsNoLock (reply_packet, m_packet_timeout))
+ {
+ uint32_t offset = 0;
+ const uint8_t reply_command = reply_packet.GetU8 (&offset);
+ const uint8_t reply_sequence_id = reply_packet.GetU8 (&offset);
+ if ((reply_command & eCommandTypeMask) == command)
+ {
+ if (request_sequence_id == reply_sequence_id)
+ return true;
+ }
+ }
+ }
+ reply_packet.Clear();
+ return false;
+}
bool
-CommunicationKDP::SendRequestPacketNoLock (const StreamString &request_packet)
+CommunicationKDP::SendRequestPacketNoLock (const PacketStreamType &request_packet)
{
if (IsConnected())
{
@@ -90,22 +129,11 @@
LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
if (log)
{
- StreamString log_strm;
- DataExtractor data (packet_data,
- packet_size,
- request_packet.GetByteOrder(),
- request_packet.GetAddressByteSize());
- data.Dump (&log_strm,
- 0,
- eFormatBytes,
- 1,
- packet_size,
- 32, // Num bytes per line
- 0, // Base address
- 0,
- 0);
+ PacketStreamType log_strm;
+
+ DataExtractor::DumpHexBytes (&log_strm, packet_data, packet_size, 0);
- log->Printf("request packet: <%u>\n%s", packet_size, log_strm.GetString().c_str());
+ log->Printf("request packet: <%u>\n%s", packet_size, log_strm.GetData());
}
ConnectionStatus status = eConnectionStatusSuccess;
@@ -137,14 +165,14 @@
}
size_t
-CommunicationKDP::WaitForPacketWithTimeoutMicroSeconds (StringExtractor &packet, uint32_t timeout_usec)
+CommunicationKDP::WaitForPacketWithTimeoutMicroSeconds (DataExtractor &packet, uint32_t timeout_usec)
{
Mutex::Locker locker(m_sequence_mutex);
return WaitForPacketWithTimeoutMicroSecondsNoLock (packet, timeout_usec);
}
size_t
-CommunicationKDP::WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractor &packet, uint32_t timeout_usec)
+CommunicationKDP::WaitForPacketWithTimeoutMicroSecondsNoLock (DataExtractor &packet, uint32_t timeout_usec)
{
uint8_t buffer[8192];
Error error;
@@ -153,7 +181,7 @@
// Check for a packet from our cache first without trying any reading...
if (CheckForPacket (NULL, 0, packet))
- return packet.GetStringRef().size();
+ return packet.GetByteSize();
bool timed_out = false;
while (IsConnected() && !timed_out)
@@ -172,7 +200,7 @@
if (bytes_read > 0)
{
if (CheckForPacket (buffer, bytes_read, packet))
- return packet.GetStringRef().size();
+ return packet.GetByteSize();
}
else
{
@@ -199,7 +227,7 @@
}
bool
-CommunicationKDP::CheckForPacket (const uint8_t *src, size_t src_len, StringExtractor &packet)
+CommunicationKDP::CheckForPacket (const uint8_t *src, size_t src_len, DataExtractor &packet)
{
// Put the packet data into the buffer in a thread safe fashion
Mutex::Locker locker(m_bytes_mutex);
@@ -210,43 +238,229 @@
{
if (log && log->GetVerbose())
{
- StreamString s;
- log->Printf ("CommunicationKDP::%s adding %u bytes: %.*s",
+ PacketStreamType log_strm;
+ DataExtractor::DumpHexBytes (&log_strm, src, src_len, 0);
+ log->Printf ("CommunicationKDP::%s adding %u bytes: %s",
__FUNCTION__,
(uint32_t)src_len,
- (uint32_t)src_len,
- src);
+ log_strm.GetData());
}
m_bytes.append ((const char *)src, src_len);
}
- // Parse up the packets into gdb remote packets
- if (!m_bytes.empty())
+ // Make sure we at least have enough bytes for a packet header
+ const size_t bytes_available = m_bytes.size();
+ if (bytes_available >= 8)
{
- // TODO: Figure out if we have a full packet reply
+ packet.SetData (&m_bytes[0], bytes_available, m_byte_order);
+ uint32_t offset = 0;
+ uint8_t reply_command = packet.GetU8(&offset);
+ switch (reply_command)
+ {
+ case ePacketTypeReply | eCommandTypeConnect:
+ case ePacketTypeReply | eCommandTypeDisconnect:
+ case ePacketTypeReply | eCommandTypeHostInfo:
+ case ePacketTypeReply | eCommandTypeVersion:
+ case ePacketTypeReply | eCommandTypeMaxBytes:
+ case ePacketTypeReply | eCommandTypeReadMemory:
+ case ePacketTypeReply | eCommandTypeWriteMemory:
+ case ePacketTypeReply | eCommandTypeReadRegisters:
+ case ePacketTypeReply | eCommandTypeWriteRegisters:
+ case ePacketTypeReply | eCommandTypeLoad:
+ case ePacketTypeReply | eCommandTypeImagePath:
+ case ePacketTypeReply | eCommandTypeSuspend:
+ case ePacketTypeReply | eCommandTypeResume:
+ case ePacketTypeReply | eCommandTypeException:
+ case ePacketTypeReply | eCommandTypeTermination:
+ case ePacketTypeReply | eCommandTypeBreakpointSet:
+ case ePacketTypeReply | eCommandTypeBreakpointRemove:
+ case ePacketTypeReply | eCommandTypeRegions:
+ case ePacketTypeReply | eCommandTypeReattach:
+ case ePacketTypeReply | eCommandTypeHostReboot:
+ case ePacketTypeReply | eCommandTypeReadMemory64:
+ case ePacketTypeReply | eCommandTypeWriteMemory64:
+ case ePacketTypeReply | eCommandTypeBreakpointSet64:
+ case ePacketTypeReply | eCommandTypeBreakpointRemove64:
+ case ePacketTypeReply | eCommandTypeKernelVersion:
+ {
+ offset = 2;
+ const uint16_t length = packet.GetU16 (&offset);
+ if (length <= bytes_available)
+ {
+ // We have an entire packet ready, we need to copy the data
+ // bytes into a buffer that will be owned by the packet and
+ // erase the bytes from our communcation buffer "m_bytes"
+ packet.SetData (DataBufferSP (new DataBufferHeap (&m_bytes[0], length)));
+ m_bytes.erase (0, length);
+ return true;
+ }
+ }
+ break;
+
+ default:
+ // Unrecognized reply command byte, erase this byte and try to get back on track
+ if (log)
+ log->Printf ("CommunicationKDP::%s: tossing junk byte: 0x%2.2x",
+ __FUNCTION__,
+ (uint8_t)m_bytes[0]);
+ m_bytes.erase(0, 1);
+ break;
+ }
}
packet.Clear();
return false;
}
-CommunicationKDP::ErrorType
+bool
CommunicationKDP::Connect (uint16_t reply_port,
uint16_t exc_port,
const char *greeting)
{
- StreamString request_packet (Stream::eBinary, 4, eByteOrderLittle);
- MakeRequestPacketHeader (eRequestTypeConnect, request_packet);
+ PacketStreamType request_packet (Stream::eBinary, 4, m_byte_order);
+ if (greeting == NULL)
+ greeting = "";
+
+ const CommandType command = eCommandTypeConnect;
+ // Length is 82 uint16_t and the length of the greeting C string
+ const uint32_t command_length = 8 + 2 + 2 + ::strlen(greeting);
+ const uint32_t request_sequence_id = m_request_sequence_id;
+ MakeRequestPacketHeader (command, request_packet, command_length);
request_packet.PutHex16(reply_port);
request_packet.PutHex16(exc_port);
request_packet.PutCString(greeting);
-
- return eErrorUnimplemented;
+ DataExtractor reply_packet;
+ return SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet);
+}
+
+void
+CommunicationKDP::ClearKDPSettings ()
+{
+ m_request_sequence_id = 0;
+ m_kdp_version_version = 0;
+ m_kdp_version_feature = 0;
+ m_kdp_hostinfo_cpu_mask = 0;
+ m_kdp_hostinfo_cpu_type = 0;
+ m_kdp_hostinfo_cpu_subtype = 0;
+}
+
+bool
+CommunicationKDP::Reattach (uint16_t reply_port)
+{
+ PacketStreamType request_packet (Stream::eBinary, 4, m_byte_order);
+ const CommandType command = eCommandTypeReattach;
+ // Length is 8 bytes for the header plus 2 bytes for the reply UDP port
+ const uint32_t command_length = 8 + 2;
+ const uint32_t request_sequence_id = m_request_sequence_id;
+ MakeRequestPacketHeader (command, request_packet, command_length);
+ request_packet.PutHex16(reply_port);
+ DataExtractor reply_packet;
+ if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ {
+ // Reset the sequence ID to zero for reattach
+ ClearKDPSettings ();
+ uint32_t offset = 4;
+ m_session_key = reply_packet.GetU32 (&offset);
+ return true;
+ }
+ return false;
}
-CommunicationKDP::ErrorType
+uint32_t
+CommunicationKDP::GetVersion ()
+{
+ if (!VersionIsValid())
+ SendRequestVersion();
+ return m_kdp_version_version;
+}
+
+uint32_t
+CommunicationKDP::GetFeatureFlags ()
+{
+ if (!VersionIsValid())
+ SendRequestVersion();
+ return m_kdp_version_feature;
+}
+
+bool
+CommunicationKDP::SendRequestVersion ()
+{
+ PacketStreamType request_packet (Stream::eBinary, 4, m_byte_order);
+ const CommandType command = eCommandTypeVersion;
+ const uint32_t command_length = 8;
+ const uint32_t request_sequence_id = m_request_sequence_id;
+ MakeRequestPacketHeader (command, request_packet, command_length);
+ DataExtractor reply_packet;
+ if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ {
+ // Reset the sequence ID to zero for reattach
+ uint32_t offset = 8;
+ m_kdp_version_version = reply_packet.GetU32 (&offset);
+ m_kdp_version_feature = reply_packet.GetU32 (&offset);
+ return true;
+ }
+ return false;
+}
+
+uint32_t
+CommunicationKDP::GetCPUMask ()
+{
+ if (!HostInfoIsValid())
+ SendRequestHostInfo();
+ return m_kdp_hostinfo_cpu_mask;
+}
+
+uint32_t
+CommunicationKDP::GetCPUType ()
+{
+ if (!HostInfoIsValid())
+ SendRequestHostInfo();
+ return m_kdp_hostinfo_cpu_type;
+}
+
+uint32_t
+CommunicationKDP::GetCPUSubtype ()
+{
+ if (!HostInfoIsValid())
+ SendRequestHostInfo();
+ return m_kdp_hostinfo_cpu_subtype;
+}
+
+bool
+CommunicationKDP::SendRequestHostInfo ()
+{
+ PacketStreamType request_packet (Stream::eBinary, 4, m_byte_order);
+ const CommandType command = eCommandTypeHostInfo;
+ const uint32_t command_length = 8;
+ const uint32_t request_sequence_id = m_request_sequence_id;
+ MakeRequestPacketHeader (command, request_packet, command_length);
+ DataExtractor reply_packet;
+ if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ {
+ // Reset the sequence ID to zero for reattach
+ uint32_t offset = 8;
+ m_kdp_hostinfo_cpu_mask = reply_packet.GetU32 (&offset);
+ m_kdp_hostinfo_cpu_type = reply_packet.GetU32 (&offset);
+ m_kdp_hostinfo_cpu_subtype = reply_packet.GetU32 (&offset);
+ return true;
+ }
+ return false;
+}
+
+bool
CommunicationKDP::Disconnect ()
{
- return eErrorUnimplemented;
+ PacketStreamType request_packet (Stream::eBinary, 4, m_byte_order);
+ const CommandType command = eCommandTypeDisconnect;
+ const uint32_t command_length = 8;
+ const uint32_t request_sequence_id = m_request_sequence_id;
+ MakeRequestPacketHeader (command, request_packet, command_length);
+ DataExtractor reply_packet;
+ if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ {
+ // Are we supposed to get a reply for disconnect?
+ }
+ ClearKDPSettings ();
+ return true;
}
Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h?rev=135338&r1=135337&r2=135338&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h Fri Jul 15 22:19:08 2011
@@ -20,12 +20,11 @@
#include "lldb/lldb-private.h"
#include "lldb/Core/Communication.h"
#include "lldb/Core/Listener.h"
+#include "lldb/Core/StreamBuffer.h"
#include "lldb/Host/Mutex.h"
#include "lldb/Host/Predicate.h"
#include "lldb/Host/TimeValue.h"
-class StringExtractor;
-
class CommunicationKDP : public lldb_private::Communication
{
public:
@@ -36,49 +35,50 @@
const static uint32_t kMaxPacketSize = 1200;
const static uint32_t kMaxDataSize = 1024;
-
+ typedef lldb_private::StreamBuffer<1024> PacketStreamType;
typedef enum
{
- eRequestTypeConnect = 0u,
- eRequestTypeDisconnect,
- eRequestTypeHostInfo,
- eRequestTypeVersion,
- eRequestTypeMaxBytes,
- eRequestTypeReadMemory,
- eRequestTypeWriteMemory,
- eRequestTypeReadRegisters,
- eRequestTypeWriteRegisters,
- eRequestTypeLoad,
- eRequestTypeImagePath,
- eRequestTypeSuspend,
- eRequestTypeResume,
- eRequestTypeException,
- eRequestTypeTermination,
- eRequestTypeBreakpointSet,
- eRequestTypeBreakpointRemove,
- eRequestTypeRegions,
- eRequestTypeReattach,
- eRequestTypeHostReboot,
- eRequestTypeReadMemory64,
- eRequestTypeWriteMemory64,
- eRequestTypeBreakpointSet64,
- eRequestTypeBreakpointRemove64,
- eRequestTypeKernelVersion
- } RequestType;
+ eCommandTypeConnect = 0u,
+ eCommandTypeDisconnect,
+ eCommandTypeHostInfo,
+ eCommandTypeVersion,
+ eCommandTypeMaxBytes,
+ eCommandTypeReadMemory,
+ eCommandTypeWriteMemory,
+ eCommandTypeReadRegisters,
+ eCommandTypeWriteRegisters,
+ eCommandTypeLoad,
+ eCommandTypeImagePath,
+ eCommandTypeSuspend,
+ eCommandTypeResume,
+ eCommandTypeException,
+ eCommandTypeTermination,
+ eCommandTypeBreakpointSet,
+ eCommandTypeBreakpointRemove,
+ eCommandTypeRegions,
+ eCommandTypeReattach,
+ eCommandTypeHostReboot,
+ eCommandTypeReadMemory64,
+ eCommandTypeWriteMemory64,
+ eCommandTypeBreakpointSet64,
+ eCommandTypeBreakpointRemove64,
+ eCommandTypeKernelVersion
+ } CommandType;
- typedef enum
+ typedef enum
{
- eErrorSuccess = 0,
- eErrorAlreadyConnected,
- eErrorPacketToBig,
- eErrorInvalidRegisterFlavor,
- eErrorUnimplemented
- } ErrorType;
+ KDP_PROTERR_SUCCESS = 0,
+ KDP_PROTERR_ALREADY_CONNECTED,
+ KDP_PROTERR_BAD_NBYTES,
+ KDP_PROTERR_BADFLAVOR
+ } KDPError;
typedef enum
{
- ePacketTypeRequest = 0u,
- ePacketTypeReply = 1u
+ ePacketTypeRequest = 0x00u,
+ ePacketTypeReply = 0x80u,
+ ePacketTypeMask = 0x80u,
+ eCommandTypeMask = 0x7fu
} PacketType;
//------------------------------------------------------------------
// Constructors and Destructors
@@ -89,11 +89,11 @@
~CommunicationKDP();
bool
- SendRequestPacket (const lldb_private::StreamString &request_packet);
+ SendRequestPacket (const PacketStreamType &request_packet);
// Wait for a packet within 'nsec' seconds
size_t
- WaitForPacketWithTimeoutMicroSeconds (StringExtractor &response,
+ WaitForPacketWithTimeoutMicroSeconds (lldb_private::DataExtractor &response,
uint32_t usec);
bool
@@ -102,7 +102,7 @@
bool
CheckForPacket (const uint8_t *src,
size_t src_len,
- StringExtractor &packet);
+ lldb_private::DataExtractor &packet);
bool
IsRunning() const
{
@@ -140,34 +140,81 @@
lldb_private::ProcessLaunchInfo &launch_info);
- ErrorType
+ bool
Connect (uint16_t reply_port,
uint16_t exc_port,
const char *greeting);
- ErrorType
+ bool
+ Reattach (uint16_t reply_port);
+
+ bool
Disconnect ();
+
+ uint32_t
+ GetVersion ();
+
+ uint32_t
+ GetFeatureFlags ();
+
+ uint32_t
+ GetCPUMask ();
+
+ uint32_t
+ GetCPUType ();
+
+ uint32_t
+ GetCPUSubtype ();
protected:
typedef std::list packet_collection;
bool
- SendRequestPacketNoLock (const lldb_private::StreamString &request_packet);
+ SendRequestPacketNoLock (const PacketStreamType &request_packet);
size_t
- WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractor &response,
+ WaitForPacketWithTimeoutMicroSecondsNoLock (lldb_private::DataExtractor &response,
uint32_t timeout_usec);
bool
WaitForNotRunningPrivate (const lldb_private::TimeValue *timeout_ptr);
void
- MakeRequestPacketHeader (RequestType request_type,
- lldb_private::StreamString &request_packet);
+ MakeRequestPacketHeader (CommandType request_type,
+ PacketStreamType &request_packet,
+ uint16_t request_length);
+ bool
+ SendRequestVersion ();
+
+
+ bool
+ VersionIsValid() const
+ {
+ return m_kdp_version_version != 0;
+ }
+
+ bool
+ HostInfoIsValid() const
+ {
+ return m_kdp_hostinfo_cpu_type != 0;
+ }
+
+ bool
+ SendRequestHostInfo ();
+
+ void
+ ClearKDPSettings ();
+
+ bool
+ SendRequestAndGetReply (const CommandType command,
+ const uint8_t request_sequence_id,
+ const PacketStreamType &request_packet,
+ lldb_private::DataExtractor &reply_packet);
//------------------------------------------------------------------
// Classes that inherit from CommunicationKDP can see and modify these
//------------------------------------------------------------------
+ lldb::ByteOrder m_byte_order;
uint32_t m_packet_timeout;
lldb_private::Mutex m_sequence_mutex; // Restrict access to sending/receiving packets to a single thread at a time
lldb_private::Predicate m_public_is_running;
@@ -175,6 +222,11 @@
uint32_t m_session_key;
uint8_t m_request_sequence_id;
uint8_t m_exception_sequence_id;
+ uint32_t m_kdp_version_version;
+ uint32_t m_kdp_version_feature;
+ uint32_t m_kdp_hostinfo_cpu_mask;
+ uint32_t m_kdp_hostinfo_cpu_type;
+ uint32_t m_kdp_hostinfo_cpu_subtype;
private:
//------------------------------------------------------------------
// For CommunicationKDP only
Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp?rev=135338&r1=135337&r2=135338&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp Fri Jul 15 22:19:08 2011
@@ -63,7 +63,6 @@
if (triple_ref.getOS() == llvm::Triple::Darwin &&
triple_ref.getVendor() == llvm::Triple::Apple)
{
-
ObjectFile *exe_objfile = exe_module_sp->GetObjectFile();
if (exe_objfile->GetType() == ObjectFile::eTypeExecutable &&
exe_objfile->GetStrata() == ObjectFile::eStrataKernel)
From peter at pcc.me.uk Sat Jul 16 10:58:57 2011
From: peter at pcc.me.uk (Peter Collingbourne)
Date: Sat, 16 Jul 2011 15:58:57 -0000
Subject: [Lldb-commits] [lldb] r135346 -
/lldb/trunk/include/lldb/Core/InputReader.h
Message-ID: <20110716155857.CE8262A6C12C@llvm.org>
Author: pcc
Date: Sat Jul 16 10:58:57 2011
New Revision: 135346
URL: http://llvm.org/viewvc/llvm-project?rev=135346&view=rev
Log:
Add missing #include, fixes Linux build
Modified:
lldb/trunk/include/lldb/Core/InputReader.h
Modified: lldb/trunk/include/lldb/Core/InputReader.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/InputReader.h?rev=135346&r1=135345&r2=135346&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/InputReader.h (original)
+++ lldb/trunk/include/lldb/Core/InputReader.h Sat Jul 16 10:58:57 2011
@@ -10,6 +10,8 @@
#ifndef liblldb_InputReader_h_
#define liblldb_InputReader_h_
+#include
+
#include "lldb/lldb-public.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/Core/Error.h"
From johnny.chen at apple.com Sat Jul 16 13:55:04 2011
From: johnny.chen at apple.com (Johnny Chen)
Date: Sat, 16 Jul 2011 11:55:04 -0700
Subject: [Lldb-commits] [PATCH] Begin cleanup to silence G++ warnings
In-Reply-To: <4E20A28C.9070402@crhc.illinois.edu>
References: <4E20A28C.9070402@crhc.illinois.edu>
Message-ID:
Hi Matt,
Thanks for the patch for silencing G++ warnings. I'll be looking into and applying the patch.
For the Python docstrings / SWIG warnings by G++, we have been using clang and have
not observed the warnings at all. However, I think I am going to create, for example, a separate
SWIG interface file SBTarget.i, to spare the SBTarget.h header file from the Python-specific
docstring litter.
And .i interface files for other SB API objects will follow.
Thanks.
Johnny Chen
On Jul 15, 2011, at 1:26 PM, Matt Johnson wrote:
> Hi all,
> This is the beginning of a cleanup effort to reduce the (vast) number of (mostly benign) warnings when compiling LLDB HEAD under G++ 4.5.2 on Ubuntu 11.04. Getting these warnings out of the way makes it much easier to spot more important warnings, if nothing else. The fixes here can be categorized as follows:
>
> * Use of a signed type as a for loop induction variable, when the loop bound is an unsigned type
> * Assigning NULL (a pointer constant) to non-pointer types (e.g., uint32_t, addr_t)
> * Declaring class members in one order, and including them in constructor initializer lists in a different order
>
> There are many more of the above warnings that I haven't gotten to yet, as well as things like the following:
> * Python docstrings in e.g. SBTarget.h use a nonstandard gcc preprocessor extension that allows multi-line string literals.
> - This causes *tons* of warnings (one per line of the literal, per inclusion of the relevant header). e.g.:
>
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:23:1: warning: missing terminating " character
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:48:1: warning: missing terminating " character
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:91:27: warning: missing terminating " character
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:164:5: warning: missing terminating " character
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:180:27: warning: missing terminating " character
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:216:5: warning: missing terminating " character
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:224:27: warning: missing terminating " character
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:245:5: warning: missing terminating " character
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:253:27: warning: missing terminating " character
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:277:5: warning: missing terminating " character
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:286:27: warning: missing terminating " character
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:310:5: warning: missing terminating " character
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:334:27: warning: missing terminating " character
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:361:5: warning: missing terminating " character
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:370:27: warning: missing terminating " character
> /media/d2/llvm/tools/lldb/source/Target/../../include/lldb/API/SBTarget.h:386:5: warning: missing terminating " character
>
> - These literals should be formed like:
>
> #ifdef SWIG
> %feature("docstring",
> "Represents the target program running under the debugger.\n"
> "\n"
> "SBTarget supports module and breakpoint iterations. For example,\n"
> ...
>
> - instead of:
>
> %feature("docstring",
> "Represents the target program running under the debugger.
>
> SBTarget supports module and breakpoint iterations. For example,
> ...
>
>
> * Use of (deprecated) instead of
> * Not handling some enum values in a switch statement. e.g., "ClangASTType.cpp:283:12: warning: enumeration value ?UnaryTransform? not handled in switch"
> * Defining static helper functions that are never used. e.g., "RegisterContextLinux_x86_64.cpp:408:17: warning: ?unsigned int GetRegSize(unsigned int)? defined but not used"
>
> Comments welcome.
> Best,
> Matt
> _______________________________________________
> lldb-commits mailing list
> lldb-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits
From johnny.chen at apple.com Sat Jul 16 16:15:39 2011
From: johnny.chen at apple.com (Johnny Chen)
Date: Sat, 16 Jul 2011 21:15:39 -0000
Subject: [Lldb-commits] [lldb] r135355 - in /lldb/trunk:
include/lldb/API/SBTarget.h scripts/Python/interface/
scripts/Python/interface/SBTarget.i scripts/Python/modify-python-lldb.py
scripts/lldb.swig
Message-ID: <20110716211539.DFAB82A6C12C@llvm.org>
Author: johnny
Date: Sat Jul 16 16:15:39 2011
New Revision: 135355
URL: http://llvm.org/viewvc/llvm-project?rev=135355&view=rev
Log:
Create an interface file for SBTarget named SBTarget.i which relieves SBTarget.h
of the duty of having SWIG docstring features and multiline string literals
embedded within.
lldb.swig now %include .../SBTarget.i, instead of .../SBTarget.h. Will create
other interface files and transition them over.
Also update modify-python-lldb.py to better handle the trailing blank line right
before the ending '"""' Python docstring delimiter.
Added:
lldb/trunk/scripts/Python/interface/
lldb/trunk/scripts/Python/interface/SBTarget.i
Modified:
lldb/trunk/include/lldb/API/SBTarget.h
lldb/trunk/scripts/Python/modify-python-lldb.py
lldb/trunk/scripts/lldb.swig
Modified: lldb/trunk/include/lldb/API/SBTarget.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBTarget.h?rev=135355&r1=135354&r2=135355&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBTarget.h (original)
+++ lldb/trunk/include/lldb/API/SBTarget.h Sat Jul 16 16:15:39 2011
@@ -18,41 +18,8 @@
class SBBreakpoint;
-#ifdef SWIG
-%feature("docstring",
-"Represents the target program running under the debugger.
-
-SBTarget supports module and breakpoint iterations. For example,
-
- for m in target.module_iter():
- print m
-
-produces:
-
-(x86_64) /Volumes/data/lldb/svn/trunk/test/python_api/lldbutil/iter/a.out
-(x86_64) /usr/lib/dyld
-(x86_64) /usr/lib/libstdc++.6.dylib
-(x86_64) /usr/lib/libSystem.B.dylib
-(x86_64) /usr/lib/system/libmathCommon.A.dylib
-(x86_64) /usr/lib/libSystem.B.dylib(__commpage)
-
-and,
-
- for b in target.breakpoint_iter():
- print b
-
-produces:
-
-SBBreakpoint: id = 1, file ='main.cpp', line = 66, locations = 1
-SBBreakpoint: id = 2, file ='main.cpp', line = 85, locations = 1
-"
- ) SBTarget;
-#endif
class SBTarget
{
-#ifdef SWIG
- %feature("autodoc", "1");
-#endif
public:
//------------------------------------------------------------------
// Broadcaster bits.
@@ -87,9 +54,6 @@
lldb::SBProcess
GetProcess ();
-#ifdef SWIG
- %feature("docstring", "
-#endif
//------------------------------------------------------------------
/// Launch a new process.
///
@@ -146,23 +110,6 @@
/// @return
/// A process object for the newly created process.
//------------------------------------------------------------------
-#ifdef SWIG
-
-For example,
-
- process = target.Launch(self.dbg.GetListener(), None, None,
- None, '/tmp/stdout.txt', None,
- None, 0, False, error)
-
-launches a new process by passing nothing for both the args and the envs
-and redirect the standard output of the inferior to the /tmp/stdout.txt
-file. It does not specify a working directory so that the debug server
-will use its idea of what the current working directory is for the
-inferior. Also, we ask the debugger not to stop the inferior at the
-entry point. If no breakpoint is specified for the inferior, it should
-run to completion if no user interaction is required.
- ") Launch;
-#endif
lldb::SBProcess
Launch (SBListener &listener,
char const **argv,
@@ -176,9 +123,6 @@
lldb::SBError& error);
-#ifdef SWIG
- %feature("docstring", "
-#endif
//------------------------------------------------------------------
/// Launch a new process with sensible defaults.
///
@@ -205,24 +149,11 @@
/// @return
/// A process object for the newly created process.
//------------------------------------------------------------------
-#ifdef SWIG
-
-For example,
-
- process = target.LaunchSimple(['X', 'Y', 'Z'], None, os.getcwd())
-
-launches a new process by passing 'X', 'Y', 'Z' as the args to the
-executable.
- ") LaunchSimple;
-#endif
lldb::SBProcess
LaunchSimple (const char **argv,
const char **envp,
const char *working_directory);
-#ifdef SWIG
- %feature("docstring", "
-#endif
//------------------------------------------------------------------
/// Attach to process with pid.
///
@@ -241,17 +172,11 @@
/// @return
/// A process object for the attached process.
//------------------------------------------------------------------
-#ifdef SWIG
- ") AttachToProcessWithID;
-#endif
lldb::SBProcess
AttachToProcessWithID (SBListener &listener,
lldb::pid_t pid,
lldb::SBError& error);
-#ifdef SWIG
- %feature("docstring", "
-#endif
//------------------------------------------------------------------
/// Attach to process with name.
///
@@ -273,18 +198,12 @@
/// @return
/// A process object for the attached process.
//------------------------------------------------------------------
-#ifdef SWIG
- ") AttachToProcessWithName;
-#endif
lldb::SBProcess
AttachToProcessWithName (SBListener &listener,
const char *name,
bool wait_for,
lldb::SBError& error);
-#ifdef SWIG
- %feature("docstring", "
-#endif
//------------------------------------------------------------------
/// Connect to a remote debug server with url.
///
@@ -306,9 +225,6 @@
/// @return
/// A process object for the connected process.
//------------------------------------------------------------------
-#ifdef SWIG
- ") ConnectRemote;
-#endif
lldb::SBProcess
ConnectRemote (SBListener &listener,
const char *url,
@@ -330,9 +246,6 @@
lldb::SBModule
FindModule (const lldb::SBFileSpec &file_spec);
-#ifdef SWIG
- %feature("docstring", "
-#endif
//------------------------------------------------------------------
/// Find functions by name.
///
@@ -357,18 +270,12 @@
/// @return
/// The number of matches added to \a sc_list.
//------------------------------------------------------------------
-#ifdef SWIG
- ") FindFunctions;
-#endif
uint32_t
FindFunctions (const char *name,
uint32_t name_type_mask, // Logical OR one or more FunctionNameType enum bits
bool append,
lldb::SBSymbolContextList& sc_list);
-#ifdef SWIG
- %feature("docstring", "
-#endif
//------------------------------------------------------------------
/// Find global and static variables by name.
///
@@ -382,9 +289,6 @@
/// @return
/// A list of matched variables in an SBValueList.
//------------------------------------------------------------------
-#ifdef SWIG
- ") FindGlobalVariables;
-#endif
lldb::SBValueList
FindGlobalVariables (const char *name,
uint32_t max_matches);
Added: lldb/trunk/scripts/Python/interface/SBTarget.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBTarget.i?rev=135355&view=auto
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBTarget.i (added)
+++ lldb/trunk/scripts/Python/interface/SBTarget.i Sat Jul 16 16:15:39 2011
@@ -0,0 +1,449 @@
+//===-- SWIG Interface for SBTarget -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+namespace lldb {
+
+%feature("docstring",
+"Represents the target program running under the debugger.
+
+SBTarget supports module and breakpoint iterations. For example,
+
+ for m in target.module_iter():
+ print m
+
+produces:
+
+(x86_64) /Volumes/data/lldb/svn/trunk/test/python_api/lldbutil/iter/a.out
+(x86_64) /usr/lib/dyld
+(x86_64) /usr/lib/libstdc++.6.dylib
+(x86_64) /usr/lib/libSystem.B.dylib
+(x86_64) /usr/lib/system/libmathCommon.A.dylib
+(x86_64) /usr/lib/libSystem.B.dylib(__commpage)
+
+and,
+
+ for b in target.breakpoint_iter():
+ print b
+
+produces:
+
+SBBreakpoint: id = 1, file ='main.cpp', line = 66, locations = 1
+SBBreakpoint: id = 2, file ='main.cpp', line = 85, locations = 1
+"
+ ) SBTarget;
+class SBTarget
+{
+ %feature("autodoc", "1");
+public:
+ //------------------------------------------------------------------
+ // Broadcaster bits.
+ //------------------------------------------------------------------
+ enum
+ {
+ eBroadcastBitBreakpointChanged = (1 << 0),
+ eBroadcastBitModulesLoaded = (1 << 1),
+ eBroadcastBitModulesUnloaded = (1 << 2)
+ };
+
+ //------------------------------------------------------------------
+ // Constructors
+ //------------------------------------------------------------------
+ SBTarget ();
+
+ SBTarget (const lldb::SBTarget& rhs);
+
+#ifndef SWIG
+ const lldb::SBTarget&
+ operator = (const lldb::SBTarget& rhs);
+#endif
+
+ //------------------------------------------------------------------
+ // Destructor
+ //------------------------------------------------------------------
+ ~SBTarget();
+
+ bool
+ IsValid() const;
+
+ lldb::SBProcess
+ GetProcess ();
+
+ %feature("docstring", "
+ //------------------------------------------------------------------
+ /// Launch a new process.
+ ///
+ /// Launch a new process by spawning a new process using the
+ /// target object's executable module's file as the file to launch.
+ /// Arguments are given in \a argv, and the environment variables
+ /// are in \a envp. Standard input and output files can be
+ /// optionally re-directed to \a stdin_path, \a stdout_path, and
+ /// \a stderr_path.
+ ///
+ /// @param[in] listener
+ /// An optional listener that will receive all process events.
+ /// If \a listener is valid then \a listener will listen to all
+ /// process events. If not valid, then this target's debugger
+ /// (SBTarget::GetDebugger()) will listen to all process events.
+ ///
+ /// @param[in] argv
+ /// The argument array.
+ ///
+ /// @param[in] envp
+ /// The environment array.
+ ///
+ /// @param[in] launch_flags
+ /// Flags to modify the launch (@see lldb::LaunchFlags)
+ ///
+ /// @param[in] stdin_path
+ /// The path to use when re-directing the STDIN of the new
+ /// process. If all stdXX_path arguments are NULL, a pseudo
+ /// terminal will be used.
+ ///
+ /// @param[in] stdout_path
+ /// The path to use when re-directing the STDOUT of the new
+ /// process. If all stdXX_path arguments are NULL, a pseudo
+ /// terminal will be used.
+ ///
+ /// @param[in] stderr_path
+ /// The path to use when re-directing the STDERR of the new
+ /// process. If all stdXX_path arguments are NULL, a pseudo
+ /// terminal will be used.
+ ///
+ /// @param[in] working_directory
+ /// The working directory to have the child process run in
+ ///
+ /// @param[in] launch_flags
+ /// Some launch options specified by logical OR'ing
+ /// lldb::LaunchFlags enumeration values together.
+ ///
+ /// @param[in] stop_at_endtry
+ /// If false do not stop the inferior at the entry point.
+ ///
+ /// @param[out]
+ /// An error object. Contains the reason if there is some failure.
+ ///
+ /// @return
+ /// A process object for the newly created process.
+ //------------------------------------------------------------------
+
+ For example,
+
+ process = target.Launch(self.dbg.GetListener(), None, None,
+ None, '/tmp/stdout.txt', None,
+ None, 0, False, error)
+
+ launches a new process by passing nothing for both the args and the envs
+ and redirect the standard output of the inferior to the /tmp/stdout.txt
+ file. It does not specify a working directory so that the debug server
+ will use its idea of what the current working directory is for the
+ inferior. Also, we ask the debugger not to stop the inferior at the
+ entry point. If no breakpoint is specified for the inferior, it should
+ run to completion if no user interaction is required.
+ ") Launch;
+ lldb::SBProcess
+ Launch (SBListener &listener,
+ char const **argv,
+ char const **envp,
+ const char *stdin_path,
+ const char *stdout_path,
+ const char *stderr_path,
+ const char *working_directory,
+ uint32_t launch_flags, // See LaunchFlags
+ bool stop_at_entry,
+ lldb::SBError& error);
+
+ %feature("docstring", "
+ //------------------------------------------------------------------
+ /// Launch a new process with sensible defaults.
+ ///
+ /// @param[in] argv
+ /// The argument array.
+ ///
+ /// @param[in] envp
+ /// The environment array.
+ ///
+ /// @param[in] working_directory
+ /// The working directory to have the child process run in
+ ///
+ /// Default: listener
+ /// Set to the target's debugger (SBTarget::GetDebugger())
+ ///
+ /// Default: launch_flags
+ /// Empty launch flags
+ ///
+ /// Default: stdin_path
+ /// Default: stdout_path
+ /// Default: stderr_path
+ /// A pseudo terminal will be used.
+ ///
+ /// @return
+ /// A process object for the newly created process.
+ //------------------------------------------------------------------
+
+ For example,
+
+ process = target.LaunchSimple(['X', 'Y', 'Z'], None, os.getcwd())
+
+ launches a new process by passing 'X', 'Y', 'Z' as the args to the
+ executable.
+ ") LaunchSimple;
+ lldb::SBProcess
+ LaunchSimple (const char **argv,
+ const char **envp,
+ const char *working_directory);
+
+ %feature("docstring", "
+ //------------------------------------------------------------------
+ /// Attach to process with pid.
+ ///
+ /// @param[in] listener
+ /// An optional listener that will receive all process events.
+ /// If \a listener is valid then \a listener will listen to all
+ /// process events. If not valid, then this target's debugger
+ /// (SBTarget::GetDebugger()) will listen to all process events.
+ ///
+ /// @param[in] pid
+ /// The process ID to attach to.
+ ///
+ /// @param[out]
+ /// An error explaining what went wrong if attach fails.
+ ///
+ /// @return
+ /// A process object for the attached process.
+ //------------------------------------------------------------------
+ ") AttachToProcessWithID;
+ lldb::SBProcess
+ AttachToProcessWithID (SBListener &listener,
+ lldb::pid_t pid,
+ lldb::SBError& error);
+
+ %feature("docstring", "
+ //------------------------------------------------------------------
+ /// Attach to process with name.
+ ///
+ /// @param[in] listener
+ /// An optional listener that will receive all process events.
+ /// If \a listener is valid then \a listener will listen to all
+ /// process events. If not valid, then this target's debugger
+ /// (SBTarget::GetDebugger()) will listen to all process events.
+ ///
+ /// @param[in] name
+ /// Basename of process to attach to.
+ ///
+ /// @param[in] wait_for
+ /// If true wait for a new instance of 'name' to be launched.
+ ///
+ /// @param[out]
+ /// An error explaining what went wrong if attach fails.
+ ///
+ /// @return
+ /// A process object for the attached process.
+ //------------------------------------------------------------------
+ ") AttachToProcessWithName;
+ lldb::SBProcess
+ AttachToProcessWithName (SBListener &listener,
+ const char *name,
+ bool wait_for,
+ lldb::SBError& error);
+
+ %feature("docstring", "
+ //------------------------------------------------------------------
+ /// Connect to a remote debug server with url.
+ ///
+ /// @param[in] listener
+ /// An optional listener that will receive all process events.
+ /// If \a listener is valid then \a listener will listen to all
+ /// process events. If not valid, then this target's debugger
+ /// (SBTarget::GetDebugger()) will listen to all process events.
+ ///
+ /// @param[in] url
+ /// The url to connect to, e.g., 'connect://localhost:12345'.
+ ///
+ /// @param[in] plugin_name
+ /// The plugin name to be used; can be NULL.
+ ///
+ /// @param[out]
+ /// An error explaining what went wrong if the connect fails.
+ ///
+ /// @return
+ /// A process object for the connected process.
+ //------------------------------------------------------------------
+ ") ConnectRemote;
+ lldb::SBProcess
+ ConnectRemote (SBListener &listener,
+ const char *url,
+ const char *plugin_name,
+ SBError& error);
+
+ lldb::SBFileSpec
+ GetExecutable ();
+
+ uint32_t
+ GetNumModules () const;
+
+ lldb::SBModule
+ GetModuleAtIndex (uint32_t idx);
+
+ lldb::SBDebugger
+ GetDebugger() const;
+
+ lldb::SBModule
+ FindModule (const lldb::SBFileSpec &file_spec);
+
+ %feature("docstring", "
+ //------------------------------------------------------------------
+ /// Find functions by name.
+ ///
+ /// @param[in] name
+ /// The name of the function we are looking for.
+ ///
+ /// @param[in] name_type_mask
+ /// A logical OR of one or more FunctionNameType enum bits that
+ /// indicate what kind of names should be used when doing the
+ /// lookup. Bits include fully qualified names, base names,
+ /// C++ methods, or ObjC selectors.
+ /// See FunctionNameType for more details.
+ ///
+ /// @param[in] append
+ /// If true, any matches will be appended to \a sc_list, else
+ /// matches replace the contents of \a sc_list.
+ ///
+ /// @param[out] sc_list
+ /// A symbol context list that gets filled in with all of the
+ /// matches.
+ ///
+ /// @return
+ /// The number of matches added to \a sc_list.
+ //------------------------------------------------------------------
+ ") FindFunctions;
+ uint32_t
+ FindFunctions (const char *name,
+ uint32_t name_type_mask, // Logical OR one or more FunctionNameType enum bits
+ bool append,
+ lldb::SBSymbolContextList& sc_list);
+
+ %feature("docstring", "
+ //------------------------------------------------------------------
+ /// Find global and static variables by name.
+ ///
+ /// @param[in] name
+ /// The name of the global or static variable we are looking
+ /// for.
+ ///
+ /// @param[in] max_matches
+ /// Allow the number of matches to be limited to \a max_matches.
+ ///
+ /// @return
+ /// A list of matched variables in an SBValueList.
+ //------------------------------------------------------------------
+ ") FindGlobalVariables;
+ lldb::SBValueList
+ FindGlobalVariables (const char *name,
+ uint32_t max_matches);
+
+ void
+ Clear ();
+
+ bool
+ ResolveLoadAddress (lldb::addr_t vm_addr,
+ lldb::SBAddress& addr);
+
+ SBSymbolContext
+ ResolveSymbolContextForAddress (const SBAddress& addr,
+ uint32_t resolve_scope);
+
+ lldb::SBBreakpoint
+ BreakpointCreateByLocation (const char *file, uint32_t line);
+
+ lldb::SBBreakpoint
+ BreakpointCreateByLocation (const lldb::SBFileSpec &file_spec, uint32_t line);
+
+ lldb::SBBreakpoint
+ BreakpointCreateByName (const char *symbol_name, const char *module_name = NULL);
+
+ lldb::SBBreakpoint
+ BreakpointCreateByRegex (const char *symbol_name_regex, const char *module_name = NULL);
+
+ lldb::SBBreakpoint
+ BreakpointCreateByAddress (addr_t address);
+
+ uint32_t
+ GetNumBreakpoints () const;
+
+ lldb::SBBreakpoint
+ GetBreakpointAtIndex (uint32_t idx) const;
+
+ bool
+ BreakpointDelete (break_id_t break_id);
+
+ lldb::SBBreakpoint
+ FindBreakpointByID (break_id_t break_id);
+
+ bool
+ EnableAllBreakpoints ();
+
+ bool
+ DisableAllBreakpoints ();
+
+ bool
+ DeleteAllBreakpoints ();
+
+ lldb::SBBroadcaster
+ GetBroadcaster () const;
+
+#ifndef SWIG
+ bool
+ operator == (const lldb::SBTarget &rhs) const;
+
+ bool
+ operator != (const lldb::SBTarget &rhs) const;
+
+#endif
+
+#ifndef SWIG
+ bool
+ GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level);
+#endif
+
+ bool
+ GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level) const;
+
+protected:
+ friend class SBAddress;
+ friend class SBDebugger;
+ friend class SBFunction;
+ friend class SBProcess;
+ friend class SBSymbol;
+ friend class SBModule;
+
+ //------------------------------------------------------------------
+ // Constructors are private, use static Target::Create function to
+ // create an instance of this class.
+ //------------------------------------------------------------------
+
+ SBTarget (const lldb::TargetSP& target_sp);
+
+ void
+ reset (const lldb::TargetSP& target_sp);
+
+ lldb_private::Target *
+ operator ->() const;
+
+ lldb_private::Target *
+ get() const;
+
+private:
+ //------------------------------------------------------------------
+ // For Target only
+ //------------------------------------------------------------------
+
+ lldb::TargetSP m_opaque_sp;
+};
+
+} // namespace lldb
Modified: lldb/trunk/scripts/Python/modify-python-lldb.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/modify-python-lldb.py?rev=135355&r1=135354&r2=135355&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/modify-python-lldb.py (original)
+++ lldb/trunk/scripts/Python/modify-python-lldb.py Sat Jul 16 16:15:39 2011
@@ -36,9 +36,8 @@
c_endif_swig = "#endif"
c_ifdef_swig = "#ifdef SWIG"
c_comment_marker = "//------------"
-trailing_blank_line = ' '
# The pattern for recognizing the doxygen comment block line.
-doxygen_comment_start = re.compile("^\s*( /// ?)")
+doxygen_comment_start = re.compile("^\s*(/// ?)")
# The demarcation point for turning on/off residue removal state.
# When bracketed by the lines, the CLEANUP_DOCSTRING state (see below) is ON.
toggle_docstring_cleanup_line = ' """'
@@ -150,8 +149,31 @@
frag.write("self.{0}() == other.{0}()".format(list[i]))
return frag.getvalue()
+class NewContent(StringIO.StringIO):
+ """Simple facade to keep track of the previous line to be committed."""
+ def __init__(self):
+ StringIO.StringIO.__init__(self)
+ self.prev_line = None
+ def add_line(self, a_line):
+ """Add a line to the content, if there is a previous line, commit it."""
+ if self.prev_line != None:
+ print >> self, self.prev_line
+ self.prev_line = a_line
+ def del_line(self):
+ """Forget about the previous line, do not commit it."""
+ self.prev_line = None
+ def del_blank_line(self):
+ """Forget about the previous line if it is a blank line."""
+ if self.prev_line != None and not self.prev_line.strip():
+ self.prev_line = None
+ def finish(self):
+ """Call this when you're finished with populating content."""
+ if self.prev_line != None:
+ print >> self, self.prev_line
+ self.prev_line = None
+
# The new content will have the iteration protocol defined for our lldb objects.
-new_content = StringIO.StringIO()
+new_content = NewContent()
with open(output_name, 'r') as f_in:
content = f_in.read()
@@ -200,6 +222,9 @@
# CLEANUP_DOCSTRING state or out of it.
if line == toggle_docstring_cleanup_line:
if state & CLEANUP_DOCSTRING:
+ # Special handling of the trailing blank line right before the '"""'
+ # end docstring marker.
+ new_content.del_blank_line()
state ^= CLEANUP_DOCSTRING
else:
state |= CLEANUP_DOCSTRING
@@ -208,7 +233,7 @@
match = class_pattern.search(line)
# Inserts the lldb_iter() definition before the first class definition.
if not lldb_iter_defined and match:
- print >> new_content, lldb_iter_def
+ new_content.add_line(lldb_iter_def)
lldb_iter_defined = True
# If we are at the beginning of the class definitions, prepare to
@@ -231,15 +256,15 @@
#
# But note that SBTarget has two types of iterations.
if cls == "SBTarget":
- print >> new_content, module_iter % (d[cls]['module'])
- print >> new_content, breakpoint_iter % (d[cls]['breakpoint'])
+ new_content.add_line(module_iter % (d[cls]['module']))
+ new_content.add_line(breakpoint_iter % (d[cls]['breakpoint']))
else:
if (state & DEFINING_ITERATOR):
- print >> new_content, iter_def % d[cls]
- print >> new_content, len_def % d[cls][0]
+ new_content.add_line(iter_def % d[cls])
+ new_content.add_line(len_def % d[cls][0])
if (state & DEFINING_EQUALITY):
- print >> new_content, eq_def % (cls, list_to_frag(e[cls]))
- print >> new_content, ne_def
+ new_content.add_line(eq_def % (cls, list_to_frag(e[cls])))
+ new_content.add_line(ne_def)
# Next state will be NORMAL.
state = NORMAL
@@ -248,9 +273,10 @@
# Cleanse the lldb.py of the autodoc'ed residues.
if c_ifdef_swig in line or c_endif_swig in line:
continue
- # As well as the comment marker line and trailing blank line.
- if c_comment_marker in line or line == trailing_blank_line:
+ # As well as the comment marker line.
+ if c_comment_marker in line:
continue
+
# Also remove the '\a ' and '\b 'substrings.
line = line.replace('\a ', '')
line = line.replace('\b ', '')
@@ -272,11 +298,14 @@
# Look for 'def IsValid(*args):', and once located, add implementation
# of truth value testing for this object by delegation.
if isvalid_pattern.search(line):
- print >> new_content, nonzero_def
+ new_content.add_line(nonzero_def)
# Pass the original line of content to new_content.
- print >> new_content, line
-
+ new_content.add_line(line)
+
+# We are finished with recording new content.
+new_content.finish()
+
with open(output_name, 'w') as f_out:
f_out.write(new_content.getvalue())
f_out.write("debugger_unique_id = 0\n")
Modified: lldb/trunk/scripts/lldb.swig
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/lldb.swig?rev=135355&r1=135354&r2=135355&view=diff
==============================================================================
--- lldb/trunk/scripts/lldb.swig (original)
+++ lldb/trunk/scripts/lldb.swig Sat Jul 16 16:15:39 2011
@@ -223,7 +223,7 @@
%include "lldb/API/SBSymbol.h"
%include "lldb/API/SBSymbolContext.h"
%include "lldb/API/SBSymbolContextList.h"
-%include "lldb/API/SBTarget.h"
+%include "./Python/interface/SBTarget.i"
%include "lldb/API/SBThread.h"
%include "lldb/API/SBType.h"
%include "lldb/API/SBValue.h"
From johnny.chen at apple.com Sat Jul 16 16:27:36 2011
From: johnny.chen at apple.com (Johnny Chen)
Date: Sat, 16 Jul 2011 21:27:36 -0000
Subject: [Lldb-commits] [lldb] r135357 - in /lldb/trunk/scripts:
Python/interface/SBTarget.i lldb.swig
Message-ID: <20110716212736.D0C322A6C12C@llvm.org>
Author: johnny
Date: Sat Jul 16 16:27:36 2011
New Revision: 135357
URL: http://llvm.org/viewvc/llvm-project?rev=135357&view=rev
Log:
Have SWIG generate autodoc strings with parameter types for all SB API objects by default.
Modified:
lldb/trunk/scripts/Python/interface/SBTarget.i
lldb/trunk/scripts/lldb.swig
Modified: lldb/trunk/scripts/Python/interface/SBTarget.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBTarget.i?rev=135357&r1=135356&r2=135357&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBTarget.i (original)
+++ lldb/trunk/scripts/Python/interface/SBTarget.i Sat Jul 16 16:27:36 2011
@@ -39,7 +39,6 @@
) SBTarget;
class SBTarget
{
- %feature("autodoc", "1");
public:
//------------------------------------------------------------------
// Broadcaster bits.
Modified: lldb/trunk/scripts/lldb.swig
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/lldb.swig?rev=135357&r1=135356&r2=135357&view=diff
==============================================================================
--- lldb/trunk/scripts/lldb.swig (original)
+++ lldb/trunk/scripts/lldb.swig Sat Jul 16 16:27:36 2011
@@ -31,9 +31,11 @@
and a source file location. SBCompileUnit contains SBLineEntry(s)."
%enddef
-/* The name of the module to be created. */
+// The name of the module to be created.
%module(docstring=DOCSTRING) lldb
+// Parameter types will be used in the autodoc string.
+%feature("autodoc", "1");
/* Typemap definitions, to allow SWIG to properly handle 'char**' data types. */
From gclayton at apple.com Sun Jul 17 15:36:25 2011
From: gclayton at apple.com (Greg Clayton)
Date: Sun, 17 Jul 2011 20:36:25 -0000
Subject: [Lldb-commits] [lldb] r135363 - in /lldb/trunk: include/lldb/Core/
include/lldb/Target/ source/ source/Core/
source/Plugins/Process/MacOSX-Kernel/
source/Plugins/Process/MacOSX-User/source/
source/Plugins/Process/gdb-remote/ source/Target/
Message-ID: <20110717203625.CCCBF2A6C12C@llvm.org>
Author: gclayton
Date: Sun Jul 17 15:36:25 2011
New Revision: 135363
URL: http://llvm.org/viewvc/llvm-project?rev=135363&view=rev
Log:
Added a boolean to the pure virtual lldb_private::Process::CanDebug(...)
method so process plug-ins that are requested by name can answer yes when
asked if they can debug a target that might not have any file in the target.
Modified the ConnectionFileDescriptor to have both a read and a write file
descriptor. This allows us to support UDP, and eventually will allow us to
support pipes. The ConnectionFileDescriptor class also has a file descriptor
type for each of the read and write file decriptors so we can use the correct
read/recv/recvfrom call when reading, or write/send/sendto for writing.
Finished up an initial implementation of UDP where you can use the "udp://"
URL to specify a host and port to connect to:
(lldb) process connect --plugin kdp-remote udp://host:41139
This will cause a ConnectionFileDescriptor to be created that can send UDP
packets to "host:41139", and it will also bind to a localhost port that can
be given out to receive the connectionless UDP reply.
Added the ability to get to the IPv4/IPv6 socket port number from a
ConnectionFileDescriptor instance if either file descriptor is a socket.
The ProcessKDP can now successfully connect to a remote kernel and detach
using the above "processs connect" command!!! So far we have the following
packets working:
KDP_CONNECT
KDP_DISCONNECT
KDP_HOSTINFO
KDP_VERSION
KDP_REATTACH
Now that the packets are working, adding new packets will go very quickly.
Modified:
lldb/trunk/include/lldb/Core/Communication.h
lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h
lldb/trunk/include/lldb/Core/DataExtractor.h
lldb/trunk/include/lldb/Target/Process.h
lldb/trunk/source/Core/ConnectionFileDescriptor.cpp
lldb/trunk/source/Core/DataExtractor.cpp
lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp
lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h
lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
lldb/trunk/source/Target/Process.cpp
lldb/trunk/source/lldb.cpp
Modified: lldb/trunk/include/lldb/Core/Communication.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Communication.h?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Communication.h (original)
+++ lldb/trunk/include/lldb/Core/Communication.h Sun Jul 17 15:36:25 2011
@@ -167,6 +167,12 @@
bool
HasConnection () const;
+
+ lldb_private::Connection *
+ GetConnection ()
+ {
+ return m_connection_sp.get();
+ }
//------------------------------------------------------------------
/// Read bytes from the current connection.
///
Modified: lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h (original)
+++ lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h Sun Jul 17 15:36:25 2011
@@ -56,6 +56,16 @@
lldb::ConnectionStatus &status,
Error *error_ptr);
+ // If the read file descriptor is a socket, then return
+ // the port number that is being used by the socket.
+ in_port_t
+ GetReadPort () const;
+
+ // If the write file descriptor is a socket, then return
+ // the port number that is being used by the socket.
+ in_port_t
+ GetWritePort () const;
+
protected:
lldb::ConnectionStatus
@@ -68,7 +78,7 @@
ConnectTCP (const char *host_and_port, Error *error_ptr);
lldb::ConnectionStatus
- ConnectUDP (const char *host_and_port, Error *error_ptr);
+ ConnectUDP (const char *args, Error *error_ptr);
lldb::ConnectionStatus
NamedSocketAccept (const char *socket_name, Error *error_ptr);
@@ -85,13 +95,27 @@
eFDTypeSocket, // Socket requiring send/recv
eFDTypeSocketUDP // Unconnected UDP socket requiring sendto/recvfrom
} FDType;
- int m_fd; // Socket we use to communicate once conn established
- FDType m_fd_type;
- struct sockaddr_storage m_udp_sockaddr;
- socklen_t m_udp_sockaddr_len;
+
+ typedef union sockaddr_tag
+ {
+ struct sockaddr sa;
+ struct sockaddr_in sa_ipv4;
+ struct sockaddr_in6 sa_ipv6;
+ struct sockaddr_storage sa_storage;
+ } sockaddr_t;
+
+
+ int m_fd_send;
+ int m_fd_recv;
+ FDType m_fd_send_type;
+ FDType m_fd_recv_type;
+ sockaddr_t m_udp_send_sockaddr;
bool m_should_close_fd; // True if this class should close the file descriptor when it goes away.
uint32_t m_socket_timeout_usec;
+ static in_port_t
+ GetSocketPort (int fd);
+
static int
GetSocketOption(int fd, int level, int option_name, int &option_value);
Modified: lldb/trunk/include/lldb/Core/DataExtractor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/DataExtractor.h?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/DataExtractor.h (original)
+++ lldb/trunk/include/lldb/Core/DataExtractor.h Sun Jul 17 15:36:25 2011
@@ -58,7 +58,8 @@
DumpHexBytes (Stream *s,
const void *src,
size_t src_len,
- lldb::addr_t base_addr = LLDB_INVALID_ADDRESS);
+ uint32_t bytes_per_line,
+ lldb::addr_t base_addr); // Pass LLDB_INVALID_ADDRESS to not show address at start of line
//------------------------------------------------------------------
/// Default constructor.
///
Modified: lldb/trunk/include/lldb/Target/Process.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Process.h (original)
+++ lldb/trunk/include/lldb/Target/Process.h Sun Jul 17 15:36:25 2011
@@ -1169,7 +1169,8 @@
/// debug the executable, \b false otherwise.
//------------------------------------------------------------------
virtual bool
- CanDebug (Target &target) = 0;
+ CanDebug (Target &target,
+ bool plugin_specified_by_name) = 0;
//------------------------------------------------------------------
Modified: lldb/trunk/source/Core/ConnectionFileDescriptor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ConnectionFileDescriptor.cpp?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/source/Core/ConnectionFileDescriptor.cpp (original)
+++ lldb/trunk/source/Core/ConnectionFileDescriptor.cpp Sun Jul 17 15:36:25 2011
@@ -35,61 +35,88 @@
using namespace lldb;
using namespace lldb_private;
+static bool
+DecodeHostAndPort (const char *host_and_port,
+ std::string &host_str,
+ std::string &port_str,
+ int32_t& port,
+ Error *error_ptr)
+{
+ RegularExpression regex ("([^:]+):([0-9]+)");
+ if (regex.Execute (host_and_port, 2))
+ {
+ if (regex.GetMatchAtIndex (host_and_port, 1, host_str) &&
+ regex.GetMatchAtIndex (host_and_port, 2, port_str))
+ {
+ port = Args::StringToSInt32 (port_str.c_str(), INT32_MIN);
+ if (port != INT32_MIN)
+ {
+ if (error_ptr)
+ error_ptr->Clear();
+ return true;
+ }
+ }
+ }
+ host_str.clear();
+ port_str.clear();
+ port = INT32_MIN;
+ if (error_ptr)
+ error_ptr->SetErrorStringWithFormat("invalid host:port specification: '%s'", host_and_port);
+ return false;
+}
+
ConnectionFileDescriptor::ConnectionFileDescriptor () :
Connection(),
- m_fd (-1),
- m_fd_type (eFDTypeFile),
- m_udp_sockaddr (),
- m_udp_sockaddr_len (0),
+ m_fd_send (-1),
+ m_fd_recv (-1),
+ m_fd_send_type (eFDTypeFile),
+ m_fd_recv_type (eFDTypeFile),
m_should_close_fd (false),
m_socket_timeout_usec(0)
{
- memset (&m_udp_sockaddr, 0, sizeof(m_udp_sockaddr));
+ memset (&m_udp_send_sockaddr, 0, sizeof(m_udp_send_sockaddr));
- lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT,
- "%p ConnectionFileDescriptor::ConnectionFileDescriptor ()",
- this);
+ LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT));
+ if (log)
+ log->Printf ("%p ConnectionFileDescriptor::ConnectionFileDescriptor ()", this);
}
ConnectionFileDescriptor::ConnectionFileDescriptor (int fd, bool owns_fd) :
Connection(),
- m_fd (fd),
- m_fd_type (eFDTypeFile),
- m_udp_sockaddr (),
- m_udp_sockaddr_len (0),
+ m_fd_send (fd),
+ m_fd_recv (fd),
+ m_fd_send_type (eFDTypeFile),
+ m_fd_recv_type (eFDTypeFile),
m_should_close_fd (owns_fd),
m_socket_timeout_usec(0)
{
- memset (&m_udp_sockaddr, 0, sizeof(m_udp_sockaddr));
- lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT,
- "%p ConnectionFileDescriptor::ConnectionFileDescriptor (fd = %i, owns_fd = %i)",
- this,
- fd,
- owns_fd);
+ memset (&m_udp_send_sockaddr, 0, sizeof(m_udp_send_sockaddr));
+ LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT));
+ if (log)
+ log->Printf ("%p ConnectionFileDescriptor::ConnectionFileDescriptor (fd = %i, owns_fd = %i)", this, fd, owns_fd);
}
ConnectionFileDescriptor::~ConnectionFileDescriptor ()
{
- lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT,
- "%p ConnectionFileDescriptor::~ConnectionFileDescriptor ()",
- this);
+ LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT));
+ if (log)
+ log->Printf ("%p ConnectionFileDescriptor::~ConnectionFileDescriptor ()", this);
Disconnect (NULL);
}
bool
ConnectionFileDescriptor::IsConnected () const
{
- return m_fd >= 0;
+ return m_fd_send >= 0 || m_fd_recv >= 0;
}
ConnectionStatus
ConnectionFileDescriptor::Connect (const char *s, Error *error_ptr)
{
- lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION,
- "%p ConnectionFileDescriptor::Connect (url = '%s')",
- this,
- s);
+ LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
+ if (log)
+ log->Printf ("%p ConnectionFileDescriptor::Connect (url = '%s')", this, s);
if (s && s[0])
{
@@ -109,9 +136,9 @@
{
return ConnectTCP (s + strlen("connect://"), error_ptr);
}
- else if (strstr(s, "tcp://"))
+ else if (strstr(s, "tcp-connect://"))
{
- return ConnectTCP (s + strlen("tcp://"), error_ptr);
+ return ConnectTCP (s + strlen("tcp-connect://"), error_ptr);
}
else if (strstr(s, "udp://"))
{
@@ -123,7 +150,8 @@
// that is already opened (possibly from a service or other source).
s += strlen ("fd://");
bool success = false;
- m_fd = Args::StringToSInt32 (s, -1, 0, &success);
+ m_fd_send = m_fd_recv = Args::StringToSInt32 (s, -1, 0, &success);
+
if (success)
{
// We have what looks to be a valid file descriptor, but we
@@ -131,12 +159,12 @@
// get the flags from the file descriptor and making sure it
// isn't a bad fd.
errno = 0;
- int flags = ::fcntl (m_fd, F_GETFL, 0);
+ int flags = ::fcntl (m_fd_send, F_GETFL, 0);
if (flags == -1 || errno == EBADF)
{
if (error_ptr)
error_ptr->SetErrorStringWithFormat ("stale file descriptor: %s", s);
- m_fd = -1;
+ m_fd_send = m_fd_recv = -1;
return eConnectionStatusError;
}
else
@@ -144,9 +172,9 @@
// Try and get a socket option from this file descriptor to
// see if this is a socket and set m_is_socket accordingly.
int resuse;
- bool is_socket = GetSocketOption (m_fd, SOL_SOCKET, SO_REUSEADDR, resuse) == 0;
+ bool is_socket = GetSocketOption (m_fd_send, SOL_SOCKET, SO_REUSEADDR, resuse) == 0;
if (is_socket)
- m_fd_type = eFDTypeSocket;
+ m_fd_send_type = m_fd_recv_type = eFDTypeSocket;
m_should_close_fd = true;
return eConnectionStatusSuccess;
}
@@ -154,28 +182,28 @@
if (error_ptr)
error_ptr->SetErrorStringWithFormat ("invalid file descriptor: \"fd://%s\"", s);
- m_fd = -1;
+ m_fd_send = m_fd_recv = -1;
return eConnectionStatusError;
}
else if (strstr(s, "file://"))
{
// file:///PATH
const char *path = s + strlen("file://");
- m_fd = ::open (path, O_RDWR);
- if (m_fd == -1)
+ m_fd_send = m_fd_recv = ::open (path, O_RDWR);
+ if (m_fd_send == -1)
{
if (error_ptr)
error_ptr->SetErrorToErrno();
return eConnectionStatusError;
}
- int flags = ::fcntl (m_fd, F_GETFL, 0);
+ int flags = ::fcntl (m_fd_send, F_GETFL, 0);
if (flags >= 0)
{
if ((flags & O_NONBLOCK) == 0)
{
flags |= O_NONBLOCK;
- ::fcntl (m_fd, F_SETFL, flags);
+ ::fcntl (m_fd_send, F_SETFL, flags);
}
}
m_should_close_fd = true;
@@ -193,15 +221,34 @@
ConnectionStatus
ConnectionFileDescriptor::Disconnect (Error *error_ptr)
{
- lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION,
- "%p ConnectionFileDescriptor::Disconnect ()",
- this);
+ LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
+ if (log)
+ log->Printf ("%p ConnectionFileDescriptor::Disconnect ()", this);
if (m_should_close_fd == false)
{
- m_fd = -1;
+ m_fd_send = m_fd_recv = -1;
return eConnectionStatusSuccess;
}
- return Close (m_fd, error_ptr);
+ ConnectionStatus status = eConnectionStatusSuccess;
+ if (m_fd_send == m_fd_recv)
+ {
+ // Both file descriptors are the same, only close one
+ status = Close (m_fd_send, error_ptr);
+ m_fd_recv = -1;
+ }
+ else
+ {
+ // File descriptors are the different, close both if needed
+ if (m_fd_send >= 0)
+ status = Close (m_fd_send, error_ptr);
+ if (m_fd_recv >= 0)
+ {
+ ConnectionStatus recv_status = Close (m_fd_recv, error_ptr);
+ if (status == eConnectionStatusSuccess)
+ status = recv_status;
+ }
+ }
+ return status;
}
size_t
@@ -214,25 +261,23 @@
LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
if (log)
log->Printf ("%p ConnectionFileDescriptor::Read () ::read (fd = %i, dst = %p, dst_len = %zu)...",
- this, m_fd, dst, dst_len);
+ this, m_fd_recv, dst, dst_len);
ssize_t bytes_read = 0;
- struct sockaddr_storage from;
- socklen_t from_len = sizeof(from);
- switch (m_fd_type)
+ switch (m_fd_recv_type)
{
case eFDTypeFile: // Other FD requireing read/write
status = BytesAvailable (timeout_usec, error_ptr);
if (status == eConnectionStatusSuccess)
- bytes_read = ::read (m_fd, dst, dst_len);
+ bytes_read = ::read (m_fd_recv, dst, dst_len);
break;
case eFDTypeSocket: // Socket requiring send/recv
if (SetSocketReceiveTimeout (timeout_usec))
{
status = eConnectionStatusSuccess;
- bytes_read = ::recv (m_fd, dst, dst_len, 0);
+ bytes_read = ::recv (m_fd_recv, dst, dst_len, 0);
}
break;
@@ -240,8 +285,9 @@
if (SetSocketReceiveTimeout (timeout_usec))
{
status = eConnectionStatusSuccess;
- ::memset (&from, 0, sizeof(from));
- bytes_read = ::recvfrom (m_fd, dst, dst_len, 0, (struct sockaddr *)&from, &from_len);
+ sockaddr_t from = m_udp_send_sockaddr;
+ socklen_t from_len = m_udp_send_sockaddr.sa.sa_len;
+ bytes_read = ::recvfrom (m_fd_recv, dst, dst_len, 0, (struct sockaddr *)&from, &from_len);
}
break;
}
@@ -267,7 +313,7 @@
if (log)
log->Printf ("%p ConnectionFileDescriptor::Read () ::read (fd = %i, dst = %p, dst_len = %zu) => %zi, error = %s",
this,
- m_fd,
+ m_fd_recv,
dst,
dst_len,
bytes_read,
@@ -282,7 +328,10 @@
switch (error_value)
{
case EAGAIN: // The file was marked for non-blocking I/O, and no data were ready to be read.
- status = eConnectionStatusSuccess;
+ if (m_fd_recv_type == eFDTypeSocket || m_fd_recv_type == eFDTypeSocketUDP)
+ status = eConnectionStatusTimedOut;
+ else
+ status = eConnectionStatusSuccess;
return 0;
case EFAULT: // Buf points outside the allocated address space.
@@ -315,9 +364,7 @@
return 0;
}
-// if (log)
-// error->Log(log, "::read ( %i, %p, %zu ) => %i", m_fd, dst, dst_len, bytesread);
- Close (m_fd, NULL);
+ Disconnect (NULL);
return 0;
}
return bytes_read;
@@ -343,24 +390,24 @@
ssize_t bytes_sent = 0;
- switch (m_fd_type)
+ switch (m_fd_send_type)
{
case eFDTypeFile: // Other FD requireing read/write
- bytes_sent = ::write (m_fd, src, src_len);
+ bytes_sent = ::write (m_fd_send, src, src_len);
break;
case eFDTypeSocket: // Socket requiring send/recv
- bytes_sent = ::send (m_fd, src, src_len, 0);
+ bytes_sent = ::send (m_fd_send, src, src_len, 0);
break;
case eFDTypeSocketUDP: // Unconnected UDP socket requiring sendto/recvfrom
- assert (m_udp_sockaddr_len != 0);
- bytes_sent = ::sendto (m_fd,
+ assert (m_udp_send_sockaddr.sa_storage.ss_family != 0);
+ bytes_sent = ::sendto (m_fd_send,
src,
src_len,
0,
- (struct sockaddr *)&m_udp_sockaddr,
- m_udp_sockaddr_len);
+ &m_udp_send_sockaddr.sa,
+ m_udp_send_sockaddr.sa.sa_len);
break;
}
@@ -371,12 +418,12 @@
if (log)
{
- switch (m_fd_type)
+ switch (m_fd_send_type)
{
case eFDTypeFile: // Other FD requireing read/write
log->Printf ("%p ConnectionFileDescriptor::Write() ::write (fd = %i, src = %p, src_len = %zu) => %zi (error = %s)",
this,
- m_fd,
+ m_fd_send,
src,
src_len,
bytes_sent,
@@ -386,7 +433,7 @@
case eFDTypeSocket: // Socket requiring send/recv
log->Printf ("%p ConnectionFileDescriptor::Write() ::send (socket = %i, src = %p, src_len = %zu, flags = 0) => %zi (error = %s)",
this,
- m_fd,
+ m_fd_send,
src,
src_len,
bytes_sent,
@@ -396,7 +443,7 @@
case eFDTypeSocketUDP: // Unconnected UDP socket requiring sendto/recvfrom
log->Printf ("%p ConnectionFileDescriptor::Write() ::sendto (socket = %i, src = %p, src_len = %zu, flags = 0) => %zi (error = %s)",
this,
- m_fd,
+ m_fd_send,
src,
src_len,
bytes_sent,
@@ -427,7 +474,7 @@
break; // Break to close....
}
- Close (m_fd, NULL);
+ Disconnect (NULL);
return 0;
}
@@ -460,16 +507,15 @@
{
fd_set read_fds;
FD_ZERO (&read_fds);
- FD_SET (m_fd, &read_fds);
- int nfds = m_fd + 1;
+ FD_SET (m_fd_recv, &read_fds);
+ int nfds = m_fd_recv + 1;
Error error;
- log = lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION);
if (log)
log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds = %i, fd = %i, NULL, NULL, timeout = %p)...",
- this, nfds, m_fd, tv_ptr);
+ this, nfds, m_fd_recv, tv_ptr);
const int num_set_fds = ::select (nfds, &read_fds, NULL, NULL, tv_ptr);
if (num_set_fds < 0)
@@ -477,10 +523,9 @@
else
error.Clear();
- log = lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION);
if (log)
log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds = %i, fd = %i, NULL, NULL, timeout = %p) => %d, error = %s",
- this, nfds, m_fd, tv_ptr, num_set_fds, error.AsCString());
+ this, nfds, m_fd_recv, tv_ptr, num_set_fds, error.AsCString());
if (error_ptr)
*error_ptr = error;
@@ -528,10 +573,9 @@
bool success = true;
if (fd >= 0)
{
- lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION,
- "%p ConnectionFileDescriptor::Close (fd = %i)",
- this,
- fd);
+ LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
+ if (log)
+ log->Printf ("%p ConnectionFileDescriptor::Close (fd = %i)", this,fd);
success = ::close (fd) == 0;
if (!success && error_ptr)
@@ -543,7 +587,7 @@
}
fd = -1;
}
- m_fd_type = eFDTypeFile;
+ m_fd_send_type = m_fd_recv_type = eFDTypeFile;
if (success)
return eConnectionStatusSuccess;
else
@@ -556,7 +600,7 @@
ConnectionStatus result = eConnectionStatusError;
struct sockaddr_un saddr_un;
- m_fd_type = eFDTypeSocket;
+ m_fd_send_type = m_fd_recv_type = eFDTypeSocket;
int listen_socket = ::socket (AF_UNIX, SOCK_STREAM, 0);
if (listen_socket == -1)
@@ -577,8 +621,8 @@
{
if (::listen (listen_socket, 5) == 0)
{
- m_fd = ::accept (listen_socket, NULL, 0);
- if (m_fd > 0)
+ m_fd_send = m_fd_recv = ::accept (listen_socket, NULL, 0);
+ if (m_fd_send > 0)
{
m_should_close_fd = true;
@@ -602,13 +646,13 @@
ConnectionStatus
ConnectionFileDescriptor::NamedSocketConnect (const char *socket_name, Error *error_ptr)
{
- Close (m_fd, NULL);
- m_fd_type = eFDTypeSocket;
+ Disconnect (NULL);
+ m_fd_send_type = m_fd_recv_type = eFDTypeSocket;
// Open the socket that was passed in as an option
struct sockaddr_un saddr_un;
- m_fd = ::socket (AF_UNIX, SOCK_STREAM, 0);
- if (m_fd == -1)
+ m_fd_send = m_fd_recv = ::socket (AF_UNIX, SOCK_STREAM, 0);
+ if (m_fd_send == -1)
{
if (error_ptr)
error_ptr->SetErrorToErrno();
@@ -622,11 +666,11 @@
saddr_un.sun_len = SUN_LEN (&saddr_un);
#endif
- if (::connect (m_fd, (struct sockaddr *)&saddr_un, SUN_LEN (&saddr_un)) < 0)
+ if (::connect (m_fd_send, (struct sockaddr *)&saddr_un, SUN_LEN (&saddr_un)) < 0)
{
if (error_ptr)
error_ptr->SetErrorToErrno();
- Close (m_fd, NULL);
+ Disconnect (NULL);
return eConnectionStatusError;
}
if (error_ptr)
@@ -637,12 +681,12 @@
ConnectionStatus
ConnectionFileDescriptor::SocketListen (uint16_t listen_port_num, Error *error_ptr)
{
- lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION,
- "%p ConnectionFileDescriptor::SocketListen (port = %i)",
- this, listen_port_num);
+ LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
+ if (log)
+ log->Printf ("%p ConnectionFileDescriptor::SocketListen (port = %i)", this, listen_port_num);
- Close (m_fd, NULL);
- m_fd_type = eFDTypeSocket;
+ Disconnect (NULL);
+ m_fd_send_type = m_fd_recv_type = eFDTypeSocket;
int listen_port = ::socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (listen_port == -1)
{
@@ -678,8 +722,8 @@
return eConnectionStatusError;
}
- m_fd = ::accept (listen_port, NULL, 0);
- if (m_fd == -1)
+ m_fd_send = m_fd_recv = ::accept (listen_port, NULL, 0);
+ if (m_fd_send == -1)
{
if (error_ptr)
error_ptr->SetErrorToErrno();
@@ -693,7 +737,7 @@
m_should_close_fd = true;
// Keep our TCP packets coming without any delays.
- SetSocketOption (m_fd, IPPROTO_TCP, TCP_NODELAY, 1);
+ SetSocketOption (m_fd_send, IPPROTO_TCP, TCP_NODELAY, 1);
if (error_ptr)
error_ptr->Clear();
return eConnectionStatusSuccess;
@@ -702,39 +746,21 @@
ConnectionStatus
ConnectionFileDescriptor::ConnectTCP (const char *host_and_port, Error *error_ptr)
{
- lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION,
- "%p ConnectionFileDescriptor::ConnectTCP (host/port = %s)",
- this, host_and_port);
- Close (m_fd, NULL);
- m_fd_type = eFDTypeSocket;
+ LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
+ if (log)
+ log->Printf ("%p ConnectionFileDescriptor::ConnectTCP (host/port = %s)", this, host_and_port);
+ Disconnect (NULL);
- RegularExpression regex ("([^:]+):([0-9]+)");
- if (regex.Execute (host_and_port, 2) == false)
- {
- if (error_ptr)
- error_ptr->SetErrorStringWithFormat("invalid host:port specification: '%s'", host_and_port);
- return eConnectionStatusError;
- }
+ m_fd_send_type = m_fd_recv_type = eFDTypeSocket;
std::string host_str;
std::string port_str;
- if (regex.GetMatchAtIndex (host_and_port, 1, host_str) == false ||
- regex.GetMatchAtIndex (host_and_port, 2, port_str) == false)
- {
- if (error_ptr)
- error_ptr->SetErrorStringWithFormat("invalid host:port specification '%s'", host_and_port);
+ int32_t port = INT32_MIN;
+ if (!DecodeHostAndPort (host_and_port, host_str, port_str, port, error_ptr))
return eConnectionStatusError;
- }
- int32_t port = Args::StringToSInt32 (port_str.c_str(), INT32_MIN);
- if (port == INT32_MIN)
- {
- if (error_ptr)
- error_ptr->SetErrorStringWithFormat("invalid port '%s'", port_str.c_str());
- return eConnectionStatusError;
- }
// Create the socket
- m_fd = ::socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (m_fd == -1)
+ m_fd_send = m_fd_recv = ::socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (m_fd_send == -1)
{
if (error_ptr)
error_ptr->SetErrorToErrno();
@@ -744,7 +770,7 @@
m_should_close_fd = true;
// Enable local address reuse
- SetSocketOption (m_fd, SOL_SOCKET, SO_REUSEADDR, 1);
+ SetSocketOption (m_fd_send, SOL_SOCKET, SO_REUSEADDR, 1);
struct sockaddr_in sa;
::memset (&sa, 0, sizeof (sa));
@@ -769,21 +795,23 @@
else
error_ptr->SetErrorStringWithFormat("invalid host string: '%s'", host_str.c_str());
}
- Close (m_fd, NULL);
+ Disconnect (NULL);
+
return eConnectionStatusError;
}
}
- if (-1 == ::connect (m_fd, (const struct sockaddr *)&sa, sizeof(sa)))
+ if (-1 == ::connect (m_fd_send, (const struct sockaddr *)&sa, sizeof(sa)))
{
if (error_ptr)
error_ptr->SetErrorToErrno();
- Close (m_fd, NULL);
+ Disconnect (NULL);
+
return eConnectionStatusError;
}
// Keep our TCP packets coming without any delays.
- SetSocketOption (m_fd, IPPROTO_TCP, TCP_NODELAY, 1);
+ SetSocketOption (m_fd_send, IPPROTO_TCP, TCP_NODELAY, 1);
if (error_ptr)
error_ptr->Clear();
return eConnectionStatusSuccess;
@@ -792,90 +820,104 @@
ConnectionStatus
ConnectionFileDescriptor::ConnectUDP (const char *host_and_port, Error *error_ptr)
{
- lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION,
- "%p ConnectionFileDescriptor::ConnectUDP (host/port = %s)",
- this, host_and_port);
- Close (m_fd, NULL);
- m_fd_type = eFDTypeSocketUDP;
+ LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
+ if (log)
+ log->Printf ("%p ConnectionFileDescriptor::ConnectUDP (host/port = %s)", this, host_and_port);
+ Disconnect (NULL);
+
+ m_fd_send_type = m_fd_recv_type = eFDTypeSocketUDP;
- RegularExpression regex ("([^:]+):([0-9]+)");
- if (regex.Execute (host_and_port, 2) == false)
- {
- if (error_ptr)
- error_ptr->SetErrorStringWithFormat("invalid host:port specification: '%s'", host_and_port);
- return eConnectionStatusError;
- }
std::string host_str;
std::string port_str;
- if (regex.GetMatchAtIndex (host_and_port, 1, host_str) == false ||
- regex.GetMatchAtIndex (host_and_port, 2, port_str) == false)
+ int32_t port = INT32_MIN;
+ if (!DecodeHostAndPort (host_and_port, host_str, port_str, port, error_ptr))
+ return eConnectionStatusError;
+
+ // Setup the receiving end of the UDP connection on this localhost
+ // on port zero. After we bind to port zero we can read the port.
+ m_fd_recv = ::socket (AF_INET, SOCK_DGRAM, 0);
+ if (m_fd_recv == -1)
{
+ // Socket creation failed...
if (error_ptr)
- error_ptr->SetErrorStringWithFormat("invalid host:port specification '%s'", host_and_port);
- return eConnectionStatusError;
+ error_ptr->SetErrorToErrno();
}
-
- int32_t port = Args::StringToSInt32 (port_str.c_str(), INT32_MIN);
- if (port == INT32_MIN)
+ else
{
- if (error_ptr)
- error_ptr->SetErrorStringWithFormat("invalid port '%s'", port_str.c_str());
- return eConnectionStatusError;
+ // Socket was created, now lets bind to the requested port
+ struct sockaddr_in sin;
+ ::memset (&sin, 0, sizeof(sin));
+ sin.sin_len = sizeof(sin);
+ sin.sin_family = AF_INET;
+ sin.sin_port = 0;
+ sin.sin_addr.s_addr = htonl (INADDR_ANY);
+
+ if (::bind (m_fd_recv, (struct sockaddr *)&sin, sizeof(sin)) == -1)
+ {
+ // Bind failed...
+ if (error_ptr)
+ error_ptr->SetErrorToErrno();
+ Disconnect (NULL);
+ }
}
- // Create the socket
- m_fd = ::socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (m_fd == -1)
+
+ if (m_fd_recv == -1)
+ return eConnectionStatusError;
+
+ // At this point we have setup the recieve port, now we need to
+ // setup the UDP send socket
+
+ struct addrinfo hints;
+ struct addrinfo *service_info_list = NULL;
+
+ ::memset (&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_DGRAM;
+ int err = ::getaddrinfo (host_str.c_str(), port_str.c_str(), &hints, &service_info_list);
+ if (err != 0)
{
if (error_ptr)
- error_ptr->SetErrorToErrno();
- return eConnectionStatusError;
+ error_ptr->SetErrorStringWithFormat("getaddrinfo(%s, %s, &hints, &info) returned error %i (%s)",
+ host_str.c_str(),
+ port_str.c_str(),
+ err,
+ gai_strerror(err));
+ Disconnect (NULL);
+ return eConnectionStatusError;
}
- m_should_close_fd = true;
-
- // Enable local address reuse
- SetSocketOption (m_fd, SOL_SOCKET, SO_REUSEADDR, 1);
-
- struct sockaddr_in sa;
- ::memset (&sa, 0, sizeof (sa));
- sa.sin_family = AF_INET;
- sa.sin_port = htons (port);
-
- int inet_pton_result = ::inet_pton (AF_INET, host_str.c_str(), &sa.sin_addr);
-
- if (inet_pton_result <= 0)
+ for (struct addrinfo *service_info_ptr = service_info_list;
+ service_info_ptr != NULL;
+ service_info_ptr = service_info_ptr->ai_next)
{
- struct hostent *host_entry = gethostbyname (host_str.c_str());
- if (host_entry)
- host_str = ::inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list);
- inet_pton_result = ::inet_pton (AF_INET, host_str.c_str(), &sa.sin_addr);
- if (inet_pton_result <= 0)
+ m_fd_send = ::socket (service_info_ptr->ai_family,
+ service_info_ptr->ai_socktype,
+ service_info_ptr->ai_protocol);
+
+ if (m_fd_send != -1)
{
-
- if (error_ptr)
- {
- if (inet_pton_result == -1)
- error_ptr->SetErrorToErrno();
- else
- error_ptr->SetErrorStringWithFormat("invalid host string: '%s'", host_str.c_str());
- }
- Close (m_fd, NULL);
- return eConnectionStatusError;
+ ::memset (&m_udp_send_sockaddr, 0, sizeof(m_udp_send_sockaddr));
+ ::memcpy (&m_udp_send_sockaddr,
+ service_info_ptr->ai_addr,
+ service_info_ptr->ai_addrlen);
+ break;
}
+ else
+ continue;
}
- if (-1 == ::connect (m_fd, (const struct sockaddr *)&sa, sizeof(sa)))
+ :: freeaddrinfo (service_info_list);
+
+ if (m_fd_send == -1)
{
- if (error_ptr)
- error_ptr->SetErrorToErrno();
- Close (m_fd, NULL);
+ Disconnect (NULL);
return eConnectionStatusError;
}
-
- // Keep our TCP packets coming without any delays.
- SetSocketOption (m_fd, IPPROTO_TCP, TCP_NODELAY, 1);
+
if (error_ptr)
error_ptr->Clear();
+
+ m_should_close_fd = true;
return eConnectionStatusSuccess;
}
@@ -905,7 +947,7 @@
bool
ConnectionFileDescriptor::SetSocketReceiveTimeout (uint32_t timeout_usec)
{
- switch (m_fd_type)
+ switch (m_fd_recv_type)
{
case eFDTypeFile: // Other FD requireing read/write
break;
@@ -921,7 +963,7 @@
struct timeval timeout;
timeout.tv_sec = timeout_usec / TimeValue::MicroSecPerSec;
timeout.tv_usec = timeout_usec % TimeValue::MicroSecPerSec;
- if (::setsockopt (m_fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) == 0)
+ if (::setsockopt (m_fd_recv, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) == 0)
{
m_socket_timeout_usec = timeout_usec;
return true;
@@ -931,4 +973,38 @@
return false;
}
+in_port_t
+ConnectionFileDescriptor::GetSocketPort (int fd)
+{
+ // We bound to port zero, so we need to figure out which port we actually bound to
+ sockaddr_t sock_addr;
+ socklen_t sock_addr_len = sizeof (sock_addr);
+ if (::getsockname (fd, &sock_addr.sa, &sock_addr_len) == 0)
+ {
+ switch (sock_addr.sa.sa_family)
+ {
+ case AF_INET: return sock_addr.sa_ipv4.sin_port;
+ case AF_INET6: return sock_addr.sa_ipv6.sin6_port;
+ }
+ }
+ return 0;
+
+}
+
+// If the read file descriptor is a socket, then return
+// the port number that is being used by the socket.
+in_port_t
+ConnectionFileDescriptor::GetReadPort () const
+{
+ return ConnectionFileDescriptor::GetSocketPort (m_fd_recv);
+}
+
+// If the write file descriptor is a socket, then return
+// the port number that is being used by the socket.
+in_port_t
+ConnectionFileDescriptor::GetWritePort () const
+{
+ return ConnectionFileDescriptor::GetSocketPort (m_fd_send);
+}
+
Modified: lldb/trunk/source/Core/DataExtractor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/DataExtractor.cpp?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/source/Core/DataExtractor.cpp (original)
+++ lldb/trunk/source/Core/DataExtractor.cpp Sun Jul 17 15:36:25 2011
@@ -1793,6 +1793,7 @@
DataExtractor::DumpHexBytes (Stream *s,
const void *src,
size_t src_len,
+ uint32_t bytes_per_line,
addr_t base_addr)
{
DataExtractor data (src, src_len, eByteOrderLittle, 4);
@@ -1801,7 +1802,7 @@
eFormatBytes, // Dump as hex bytes
1, // Size of each item is 1 for single bytes
src_len, // Number of bytes
- 32, // Num bytes per line
+ bytes_per_line, // Num bytes per line
base_addr, // Base address
0, 0); // Bitfield info
}
Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp Sun Jul 17 15:36:25 2011
@@ -102,7 +102,7 @@
Mutex::Locker locker(m_sequence_mutex);
if (SendRequestPacketNoLock(request_packet))
{
- if (WaitForPacketWithTimeoutMicroSecondsNoLock (reply_packet, m_packet_timeout))
+ if (WaitForPacketWithTimeoutMicroSecondsNoLock (reply_packet, GetPacketTimeoutInMicroSeconds ()))
{
uint32_t offset = 0;
const uint8_t reply_command = reply_packet.GetU8 (&offset);
@@ -131,9 +131,11 @@
{
PacketStreamType log_strm;
- DataExtractor::DumpHexBytes (&log_strm, packet_data, packet_size, 0);
+ DataExtractor::DumpHexBytes (&log_strm, packet_data, packet_size, UINT32_MAX, LLDB_INVALID_ADDRESS);
- log->Printf("request packet: <%u>\n%s", packet_size, log_strm.GetData());
+ log->Printf("send kdp-packet: %.*s",
+ (uint32_t)log_strm.GetSize(),
+ log_strm.GetData());
}
ConnectionStatus status = eConnectionStatusSuccess;
@@ -239,7 +241,7 @@
if (log && log->GetVerbose())
{
PacketStreamType log_strm;
- DataExtractor::DumpHexBytes (&log_strm, src, src_len, 0);
+ DataExtractor::DumpHexBytes (&log_strm, src, src_len, UINT32_MAX, LLDB_INVALID_ADDRESS);
log->Printf ("CommunicationKDP::%s adding %u bytes: %s",
__FUNCTION__,
(uint32_t)src_len,
@@ -292,6 +294,23 @@
// erase the bytes from our communcation buffer "m_bytes"
packet.SetData (DataBufferSP (new DataBufferHeap (&m_bytes[0], length)));
m_bytes.erase (0, length);
+
+ if (log)
+ {
+ PacketStreamType log_strm;
+ packet.Dump (&log_strm, // Stream to dump to
+ 0, // Offset into "packet"
+ eFormatBytes, // Dump as hex bytes
+ 1, // Size of each item is 1 for single bytes
+ length, // Number of bytes
+ UINT32_MAX, // Num bytes per line
+ LLDB_INVALID_ADDRESS, // Base address
+ 0, 0); // Bitfield info set to not do anything bitfield related
+
+ log->Printf("recv kdp-packet: %.*s",
+ (uint32_t)log_strm.GetSize(),
+ log_strm.GetData());
+ }
return true;
}
}
@@ -313,22 +332,25 @@
bool
-CommunicationKDP::Connect (uint16_t reply_port,
- uint16_t exc_port,
- const char *greeting)
+CommunicationKDP::SendRequestConnect (uint16_t reply_port,
+ uint16_t exc_port,
+ const char *greeting)
{
PacketStreamType request_packet (Stream::eBinary, 4, m_byte_order);
if (greeting == NULL)
greeting = "";
const CommandType command = eCommandTypeConnect;
- // Length is 82 uint16_t and the length of the greeting C string
- const uint32_t command_length = 8 + 2 + 2 + ::strlen(greeting);
+ // Length is 82 uint16_t and the length of the greeting C string with the terminating NULL
+ const uint32_t command_length = 8 + 2 + 2 + ::strlen(greeting) + 1;
const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
- request_packet.PutHex16(reply_port);
- request_packet.PutHex16(exc_port);
- request_packet.PutCString(greeting);
+ // Always send connect ports as little endian
+ request_packet.SetByteOrder (eByteOrderLittle);
+ request_packet.PutHex16 (reply_port);
+ request_packet.PutHex16 (exc_port);
+ request_packet.SetByteOrder (m_byte_order);
+ request_packet.PutCString (greeting);
DataExtractor reply_packet;
return SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet);
}
@@ -345,7 +367,7 @@
}
bool
-CommunicationKDP::Reattach (uint16_t reply_port)
+CommunicationKDP::SendRequestReattach (uint16_t reply_port)
{
PacketStreamType request_packet (Stream::eBinary, 4, m_byte_order);
const CommandType command = eCommandTypeReattach;
@@ -353,7 +375,10 @@
const uint32_t command_length = 8 + 2;
const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
+ // Always send connect ports as little endian
+ request_packet.SetByteOrder (eByteOrderLittle);
request_packet.PutHex16(reply_port);
+ request_packet.SetByteOrder (m_byte_order);
DataExtractor reply_packet;
if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
{
@@ -448,7 +473,7 @@
}
bool
-CommunicationKDP::Disconnect ()
+CommunicationKDP::SendRequestDisconnect ()
{
PacketStreamType request_packet (Stream::eBinary, 4, m_byte_order);
const CommandType command = eCommandTypeDisconnect;
Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h Sun Jul 17 15:36:25 2011
@@ -141,15 +141,15 @@
bool
- Connect (uint16_t reply_port,
- uint16_t exc_port,
- const char *greeting);
+ SendRequestConnect (uint16_t reply_port,
+ uint16_t exc_port,
+ const char *greeting);
bool
- Reattach (uint16_t reply_port);
+ SendRequestReattach (uint16_t reply_port);
bool
- Disconnect ();
+ SendRequestDisconnect ();
uint32_t
GetVersion ();
Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp Sun Jul 17 15:36:25 2011
@@ -13,6 +13,7 @@
// C++ Includes
// Other libraries and framework includes
+#include "lldb/Core/ConnectionFileDescriptor.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/State.h"
#include "lldb/Host/Host.h"
@@ -53,7 +54,7 @@
}
bool
-ProcessKDP::CanDebug(Target &target)
+ProcessKDP::CanDebug(Target &target, bool plugin_specified_by_name)
{
// For now we are just making sure the file exists for a given module
ModuleSP exe_module_sp(target.GetExecutableModule());
@@ -68,8 +69,10 @@
exe_objfile->GetStrata() == ObjectFile::eStrataKernel)
return true;
}
+ return false;
}
- return false;
+ // No target executable, assume we can debug if our plug-in was specified by name
+ return plugin_specified_by_name;
}
//----------------------------------------------------------------------
@@ -143,7 +146,63 @@
{
// TODO: fill in the remote connection to the remote KDP here!
Error error;
- error.SetErrorString ("attaching to a by process name not supported in kdp-remote plug-in");
+
+ if (remote_url == NULL || remote_url[0] == '\0')
+ remote_url = "udp://localhost:41139";
+
+ std::auto_ptr conn_ap(new ConnectionFileDescriptor());
+ if (conn_ap.get())
+ {
+ // Only try once for now.
+ // TODO: check if we should be retrying?
+ const uint32_t max_retry_count = 1;
+ for (uint32_t retry_count = 0; retry_count < max_retry_count; ++retry_count)
+ {
+ if (conn_ap->Connect(remote_url, &error) == eConnectionStatusSuccess)
+ break;
+ usleep (100000);
+ }
+ }
+
+ if (conn_ap->IsConnected())
+ {
+ const uint16_t reply_port = conn_ap->GetReadPort ();
+
+ if (reply_port != 0)
+ {
+ m_comm.SetConnection(conn_ap.release());
+
+ if (m_comm.SendRequestReattach(reply_port))
+ {
+ if (m_comm.SendRequestConnect(reply_port, reply_port, "Greetings from LLDB..."))
+ {
+ m_comm.GetVersion();
+ uint32_t cpu = m_comm.GetCPUType();
+ uint32_t sub = m_comm.GetCPUSubtype();
+ ArchSpec kernel_arch;
+ kernel_arch.SetArchitecture(eArchTypeMachO, cpu, sub);
+ m_target.SetArchitecture(kernel_arch);
+ // TODO: thread registers based off of architecture...
+ }
+ }
+ else
+ {
+ error.SetErrorString("KDP reattach failed");
+ }
+ }
+ else
+ {
+ error.SetErrorString("invalid reply port from UDP connection");
+ }
+ }
+ else
+ {
+ if (error.Success())
+ error.SetErrorStringWithFormat ("failed to connect to '%s'", remote_url);
+ }
+ if (error.Fail())
+ m_comm.Disconnect();
+
return error;
}
@@ -414,13 +473,19 @@
m_thread_list.DiscardThreadPlans();
- size_t response_size = m_comm.Disconnect ();
- if (log)
+ if (m_comm.IsConnected())
{
- if (response_size)
- log->PutCString ("ProcessKDP::DoDetach() detach packet sent successfully");
- else
- log->PutCString ("ProcessKDP::DoDetach() detach packet send failed");
+
+ m_comm.SendRequestDisconnect();
+
+ size_t response_size = m_comm.Disconnect ();
+ if (log)
+ {
+ if (response_size)
+ log->PutCString ("ProcessKDP::DoDetach() detach packet sent successfully");
+ else
+ log->PutCString ("ProcessKDP::DoDetach() detach packet send failed");
+ }
}
// Sleep for one second to let the process get all detached...
StopAsyncThread ();
@@ -446,6 +511,8 @@
// Interrupt if our inferior is running...
if (m_comm.IsConnected())
{
+ m_comm.SendRequestDisconnect();
+
if (m_public_state.GetValue() == eStateAttaching)
{
// We are being asked to halt during an attach. We need to just close
Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h Sun Jul 17 15:36:25 2011
@@ -65,7 +65,8 @@
// Check if a given Process
//------------------------------------------------------------------
virtual bool
- CanDebug (lldb_private::Target &target);
+ CanDebug (lldb_private::Target &target,
+ bool plugin_specified_by_name);
// virtual uint32_t
// ListProcessesMatchingName (const char *name, lldb_private::StringList &matches, std::vector &pids);
Modified: lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp Sun Jul 17 15:36:25 2011
@@ -208,7 +208,7 @@
}
bool
-ProcessMacOSX::CanDebug(Target &target)
+ProcessMacOSX::CanDebug(Target &target, bool plugin_specified_by_name)
{
// For now we are just making sure the file exists for a given module
ModuleSP exe_module_sp(target.GetExecutableModule());
Modified: lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h Sun Jul 17 15:36:25 2011
@@ -81,7 +81,8 @@
// Check if a given Process
//------------------------------------------------------------------
virtual bool
- CanDebug (lldb_private::Target &target);
+ CanDebug (lldb_private::Target &target,
+ bool plugin_specified_by_name);
//------------------------------------------------------------------
// Creating a new process, or attaching to an existing one
Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Sun Jul 17 15:36:25 2011
@@ -101,7 +101,7 @@
}
bool
-ProcessGDBRemote::CanDebug(Target &target)
+ProcessGDBRemote::CanDebug (Target &target, bool plugin_specified_by_name)
{
// For now we are just making sure the file exists for a given module
ModuleSP exe_module_sp(target.GetExecutableModule());
Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h Sun Jul 17 15:36:25 2011
@@ -66,7 +66,8 @@
// Check if a given Process
//------------------------------------------------------------------
virtual bool
- CanDebug (lldb_private::Target &target);
+ CanDebug (lldb_private::Target &target,
+ bool plugin_specified_by_name);
// virtual uint32_t
// ListProcessesMatchingName (const char *name, lldb_private::StringList &matches, std::vector &pids);
Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Sun Jul 17 15:36:25 2011
@@ -549,7 +549,7 @@
if (create_callback)
{
std::auto_ptr debugger_ap(create_callback(target, listener));
- if (debugger_ap->CanDebug(target))
+ if (debugger_ap->CanDebug(target, true))
return debugger_ap.release();
}
}
@@ -558,7 +558,7 @@
for (uint32_t idx = 0; (create_callback = PluginManager::GetProcessCreateCallbackAtIndex(idx)) != NULL; ++idx)
{
std::auto_ptr debugger_ap(create_callback(target, listener));
- if (debugger_ap->CanDebug(target))
+ if (debugger_ap->CanDebug(target, false))
return debugger_ap.release();
}
}
Modified: lldb/trunk/source/lldb.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/lldb.cpp?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/source/lldb.cpp (original)
+++ lldb/trunk/source/lldb.cpp Sun Jul 17 15:36:25 2011
@@ -45,6 +45,7 @@
#include "Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h"
#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
#include "Plugins/Process/MacOSX-User/source/ProcessMacOSX.h"
+#include "Plugins/Process/MacOSX-Kernel/ProcessKDP.h"
#include "Plugins/Process/gdb-remote/ProcessGDBRemote.h"
#include "Plugins/Platform/MacOSX/PlatformMacOSX.h"
#include "Plugins/Platform/MacOSX/PlatformRemoteiOS.h"
@@ -102,6 +103,7 @@
AppleObjCRuntimeV1::Initialize();
ObjectContainerUniversalMachO::Initialize();
ObjectFileMachO::Initialize();
+ ProcessKDP::Initialize();
ProcessGDBRemote::Initialize();
//ProcessMacOSX::Initialize();
SymbolVendorMacOSX::Initialize();
@@ -167,6 +169,7 @@
AppleObjCRuntimeV1::Terminate();
ObjectContainerUniversalMachO::Terminate();
ObjectFileMachO::Terminate();
+ ProcessKDP::Terminate();
ProcessGDBRemote::Terminate();
//ProcessMacOSX::Terminate();
SymbolVendorMacOSX::Terminate();