[Lldb-commits] [lldb] r165328 - in /lldb/trunk: include/lldb/API/SBBreakpoint.h include/lldb/Breakpoint/Breakpoint.h include/lldb/Breakpoint/BreakpointOptions.h scripts/Python/interface/SBBreakpoint.i source/API/SBBreakpoint.cpp source/Breakpoint/Breakpoint.cpp source/Breakpoint/BreakpointOptions.cpp source/Commands/CommandObjectBreakpoint.cpp source/Interpreter/CommandInterpreter.cpp source/Target/StopInfo.cpp test/functionalities/abbreviation/TestAbbreviations.py

Jim Ingham jingham at apple.com
Fri Oct 5 12:16:31 PDT 2012


Author: jingham
Date: Fri Oct  5 14:16:31 2012
New Revision: 165328

URL: http://llvm.org/viewvc/llvm-project?rev=165328&view=rev
Log:
Add one-shot breakpoints (-o option to "break set") and a tbreak alias for our gdb friends.

Modified:
    lldb/trunk/include/lldb/API/SBBreakpoint.h
    lldb/trunk/include/lldb/Breakpoint/Breakpoint.h
    lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h
    lldb/trunk/scripts/Python/interface/SBBreakpoint.i
    lldb/trunk/source/API/SBBreakpoint.cpp
    lldb/trunk/source/Breakpoint/Breakpoint.cpp
    lldb/trunk/source/Breakpoint/BreakpointOptions.cpp
    lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp
    lldb/trunk/source/Interpreter/CommandInterpreter.cpp
    lldb/trunk/source/Target/StopInfo.cpp
    lldb/trunk/test/functionalities/abbreviation/TestAbbreviations.py

Modified: lldb/trunk/include/lldb/API/SBBreakpoint.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBBreakpoint.h?rev=165328&r1=165327&r2=165328&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBBreakpoint.h (original)
+++ lldb/trunk/include/lldb/API/SBBreakpoint.h Fri Oct  5 14:16:31 2012
@@ -64,6 +64,12 @@
     bool
     IsEnabled ();
     
+    void
+    SetOneShot (bool one_shot);
+
+    bool
+    IsOneShot () const;
+    
     bool
     IsInternal ();
 

Modified: lldb/trunk/include/lldb/Breakpoint/Breakpoint.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/Breakpoint.h?rev=165328&r1=165327&r2=165328&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Breakpoint/Breakpoint.h (original)
+++ lldb/trunk/include/lldb/Breakpoint/Breakpoint.h Fri Oct  5 14:16:31 2012
@@ -356,6 +356,20 @@
 
 
     //------------------------------------------------------------------
+    /// If \a one_shot is \b true, breakpoint will be deleted on first hit.
+    //------------------------------------------------------------------
+    void
+    SetOneShot (bool one_shot);
+
+    //------------------------------------------------------------------
+    /// Check the OneShot state.
+    /// @return
+    ///     \b true if the breakpoint is one shot, \b false otherwise.
+    //------------------------------------------------------------------
+    bool
+    IsOneShot () const;
+
+    //------------------------------------------------------------------
     /// Set the valid thread to be checked when the breakpoint is hit.
     /// @param[in] thread_id
     ///    If this thread hits the breakpoint, we stop, otherwise not.

Modified: lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h?rev=165328&r1=165327&r2=165328&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h (original)
+++ lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h Fri Oct  5 14:16:31 2012
@@ -67,7 +67,8 @@
                       void *baton,
                       bool enabled = true,
                       int32_t ignore = 0,
-                      lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID);
+                      lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID,
+                      bool one_shot = false);
 
     virtual ~BreakpointOptions();
 
@@ -195,13 +196,39 @@
     ///     \b true if the breakpoint is enabled, \b false if disabled.
     //------------------------------------------------------------------
     bool         
-    IsEnabled () const;
+    IsEnabled () const
+    {
+        return m_enabled;
+    }
+
+    //------------------------------------------------------------------
+    /// If \a enable is \b true, enable the breakpoint, if \b false disable it.
+    //------------------------------------------------------------------
+    void
+    SetEnabled (bool enabled)
+    {
+        m_enabled = enabled;
+    }
+
+    //------------------------------------------------------------------
+    /// Check the One-shot state.
+    /// @return
+    ///     \b true if the breakpoint is one-shot, \b false otherwise.
+    //------------------------------------------------------------------
+    bool         
+    IsOneShot () const
+    {
+        return m_one_shot;
+    }
 
     //------------------------------------------------------------------
     /// If \a enable is \b true, enable the breakpoint, if \b false disable it.
     //------------------------------------------------------------------
     void
-    SetEnabled (bool enabled);
+    SetOneShot (bool one_shot)
+    {
+        m_one_shot = one_shot;
+    }
 
     //------------------------------------------------------------------
     /// Set the breakpoint to ignore the next \a count breakpoint hits.
@@ -210,7 +237,10 @@
     //------------------------------------------------------------------
 
     void
-    SetIgnoreCount (uint32_t n);
+    SetIgnoreCount (uint32_t n)
+    {
+        m_ignore_count = n;
+    }
 
     //------------------------------------------------------------------
     /// Return the current Ignore Count.
@@ -218,7 +248,10 @@
     ///     The number of breakpoint hits to be ignored.
     //------------------------------------------------------------------
     uint32_t
-    GetIgnoreCount () const;
+    GetIgnoreCount () const
+    {
+        return m_ignore_count;
+    }
 
     //------------------------------------------------------------------
     /// Return the current thread spec for this option.  This will return NULL if the no thread
@@ -314,6 +347,7 @@
     lldb::BatonSP m_callback_baton_sp; // This is the client data for the callback
     bool m_callback_is_synchronous;
     bool m_enabled;
+    bool m_one_shot;
     uint32_t m_ignore_count; // Number of times to ignore this breakpoint
     std::auto_ptr<ThreadSpec> m_thread_spec_ap; // Thread for which this breakpoint will take
     std::auto_ptr<ClangUserExpression> m_condition_ap;  // The condition to test.

Modified: lldb/trunk/scripts/Python/interface/SBBreakpoint.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBBreakpoint.i?rev=165328&r1=165327&r2=165328&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBBreakpoint.i (original)
+++ lldb/trunk/scripts/Python/interface/SBBreakpoint.i Fri Oct  5 14:16:31 2012
@@ -119,6 +119,12 @@
     bool
     IsEnabled ();
     
+    void
+    SetOneShot (bool one_shot);
+
+    bool
+    IsOneShot ();
+    
     bool
     IsInternal ();
 

Modified: lldb/trunk/source/API/SBBreakpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBBreakpoint.cpp?rev=165328&r1=165327&r2=165328&view=diff
==============================================================================
--- lldb/trunk/source/API/SBBreakpoint.cpp (original)
+++ lldb/trunk/source/API/SBBreakpoint.cpp Fri Oct  5 14:16:31 2012
@@ -234,6 +234,33 @@
         return false;
 }
 
+void
+SBBreakpoint::SetOneShot (bool one_shot)
+{
+    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+
+    if (log)
+        log->Printf ("SBBreakpoint(%p)::SetOneShot (one_shot=%i)", m_opaque_sp.get(), one_shot);
+
+    if (m_opaque_sp)
+    {
+        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+        m_opaque_sp->SetOneShot (one_shot);
+    }
+}
+
+bool
+SBBreakpoint::IsOneShot () const
+{
+    if (m_opaque_sp)
+    {
+        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+        return m_opaque_sp->IsOneShot();
+    }
+    else
+        return false;
+}
+
 bool
 SBBreakpoint::IsInternal ()
 {

Modified: lldb/trunk/source/Breakpoint/Breakpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/Breakpoint.cpp?rev=165328&r1=165327&r2=165328&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/Breakpoint.cpp (original)
+++ lldb/trunk/source/Breakpoint/Breakpoint.cpp Fri Oct  5 14:16:31 2012
@@ -189,6 +189,18 @@
     return m_locations.GetHitCount();
 }
 
+bool
+Breakpoint::IsOneShot () const
+{
+    return m_options.IsOneShot();
+}
+
+void
+Breakpoint::SetOneShot (bool one_shot)
+{
+    m_options.SetOneShot (one_shot);
+}
+
 void
 Breakpoint::SetThreadID (lldb::tid_t thread_id)
 {

Modified: lldb/trunk/source/Breakpoint/BreakpointOptions.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointOptions.cpp?rev=165328&r1=165327&r2=165328&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/BreakpointOptions.cpp (original)
+++ lldb/trunk/source/Breakpoint/BreakpointOptions.cpp Fri Oct  5 14:16:31 2012
@@ -39,6 +39,7 @@
     m_callback_baton_sp (),
     m_callback_is_synchronous (false),
     m_enabled (true),
+    m_one_shot (false),
     m_ignore_count (0),
     m_thread_spec_ap (NULL),
     m_condition_ap()
@@ -53,6 +54,7 @@
     m_callback_baton_sp (rhs.m_callback_baton_sp),
     m_callback_is_synchronous (rhs.m_callback_is_synchronous),
     m_enabled (rhs.m_enabled),
+    m_one_shot (rhs.m_one_shot),
     m_ignore_count (rhs.m_ignore_count),
     m_thread_spec_ap (NULL),
     m_condition_ap (NULL)
@@ -73,6 +75,7 @@
     m_callback_baton_sp = rhs.m_callback_baton_sp;
     m_callback_is_synchronous = rhs.m_callback_is_synchronous;
     m_enabled = rhs.m_enabled;
+    m_one_shot = rhs.m_one_shot;
     m_ignore_count = rhs.m_ignore_count;
     if (rhs.m_thread_spec_ap.get() != NULL)
         m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get()));
@@ -179,33 +182,6 @@
         return NULL;
 }
 
-//------------------------------------------------------------------
-// Enabled/Ignore Count
-//------------------------------------------------------------------
-bool
-BreakpointOptions::IsEnabled () const
-{
-    return m_enabled;
-}
-
-void
-BreakpointOptions::SetEnabled (bool enabled)
-{
-    m_enabled = enabled;
-}
-
-uint32_t
-BreakpointOptions::GetIgnoreCount () const
-{
-    return m_ignore_count;
-}
-
-void
-BreakpointOptions::SetIgnoreCount (uint32_t n)
-{
-    m_ignore_count = n;
-}
-
 const ThreadSpec *
 BreakpointOptions::GetThreadSpecNoCreate () const
 {
@@ -234,7 +210,7 @@
     // Figure out if there are any options not at their default value, and only print 
     // anything if there are:
     
-    if (m_ignore_count != 0 || !m_enabled || (GetThreadSpecNoCreate() != NULL && GetThreadSpecNoCreate()->HasSpecification ()))
+    if (m_ignore_count != 0 || !m_enabled || m_one_shot || (GetThreadSpecNoCreate() != NULL && GetThreadSpecNoCreate()->HasSpecification ()))
     {
         if (level == lldb::eDescriptionLevelVerbose)
         {
@@ -252,6 +228,9 @@
             s->Printf("ignore: %d ", m_ignore_count);
         s->Printf("%sabled ", m_enabled ? "en" : "dis");
         
+        if (m_one_shot)
+            s->Printf ("one-shot ");
+        
         if (m_thread_spec_ap.get())
             m_thread_spec_ap->GetDescription (s, level);
         else if (level == eDescriptionLevelBrief)

Modified: lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp?rev=165328&r1=165327&r2=165328&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp Fri Oct  5 14:16:31 2012
@@ -105,7 +105,8 @@
             m_catch_bp (false),
             m_throw_bp (true),
             m_language (eLanguageTypeUnknown),
-            m_skip_prologue (eLazyBoolCalculate)
+            m_skip_prologue (eLazyBoolCalculate),
+            m_one_shot (false)
         {
         }
 
@@ -130,6 +131,11 @@
                         error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg);
                     break;
 
+                case 'b':
+                    m_func_names.push_back (option_arg);
+                    m_func_name_type_mask |= eFunctionNameTypeBase;
+                    break;
+
                 case 'C':
                     m_column = Args::StringToUInt32 (option_arg, 0);
                     break;
@@ -138,59 +144,116 @@
                     m_condition.assign(option_arg);
                     break;
 
+                case 'E':
+                {
+                    LanguageType language = LanguageRuntime::GetLanguageTypeFromString (option_arg);
+
+                    switch (language)
+                    {
+                        case eLanguageTypeC89:
+                        case eLanguageTypeC:
+                        case eLanguageTypeC99:
+                            m_language = eLanguageTypeC;
+                            break;
+                        case eLanguageTypeC_plus_plus:
+                            m_language = eLanguageTypeC_plus_plus;
+                            break;
+                        case eLanguageTypeObjC:
+                            m_language = eLanguageTypeObjC;
+                            break;
+                        case eLanguageTypeObjC_plus_plus:
+                            error.SetErrorStringWithFormat ("Set exception breakpoints separately for c++ and objective-c");
+                            break;
+                        case eLanguageTypeUnknown:
+                            error.SetErrorStringWithFormat ("Unknown language type: '%s' for exception breakpoint", option_arg);
+                            break;
+                        default:
+                            error.SetErrorStringWithFormat ("Unsupported language type: '%s' for exception breakpoint", option_arg);
+                    }
+                }
+                break;
+
                 case 'f':
                     m_filenames.AppendIfUnique (FileSpec(option_arg, false));
                     break;
 
-                case 'l':
-                    m_line_num = Args::StringToUInt32 (option_arg, 0);
+                case 'F':
+                    m_func_names.push_back (option_arg);
+                    m_func_name_type_mask |= eFunctionNameTypeFull;
                     break;
 
-                case 'b':
-                    m_func_names.push_back (option_arg);
-                    m_func_name_type_mask |= eFunctionNameTypeBase;
+                case 'h':
+                {
+                    bool success;
+                    m_catch_bp = Args::StringToBoolean (option_arg, true, &success);
+                    if (!success)
+                        error.SetErrorStringWithFormat ("Invalid boolean value for on-catch option: '%s'", option_arg);
+                }
+
+                case 'i':
+                {
+                    m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
+                    if (m_ignore_count == UINT32_MAX)
+                       error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
                     break;
+                }
 
-                case 'n':
-                    m_func_names.push_back (option_arg);
-                    m_func_name_type_mask |= eFunctionNameTypeAuto;
+                case 'K':
+                {
+                    bool success;
+                    bool value;
+                    value = Args::StringToBoolean (option_arg, true, &success);
+                    if (value)
+                        m_skip_prologue = eLazyBoolYes;
+                    else
+                        m_skip_prologue = eLazyBoolNo;
+                        
+                    if (!success)
+                        error.SetErrorStringWithFormat ("Invalid boolean value for skip prologue option: '%s'", option_arg);
+                }
+                break;
+
+                case 'l':
+                    m_line_num = Args::StringToUInt32 (option_arg, 0);
                     break;
 
-                case 'F':
+                case 'M':
                     m_func_names.push_back (option_arg);
-                    m_func_name_type_mask |= eFunctionNameTypeFull;
+                    m_func_name_type_mask |= eFunctionNameTypeMethod;
                     break;
 
-                case 'S':
+                case 'n':
                     m_func_names.push_back (option_arg);
-                    m_func_name_type_mask |= eFunctionNameTypeSelector;
+                    m_func_name_type_mask |= eFunctionNameTypeAuto;
                     break;
 
-                case 'M':
-                    m_func_names.push_back (option_arg);
-                    m_func_name_type_mask |= eFunctionNameTypeMethod;
+                case 'o':
+                    m_one_shot = true;
                     break;
 
                 case 'p':
                     m_source_text_regexp.assign (option_arg);
                     break;
                     
+                case 'q':
+                    m_queue_name.assign (option_arg);
+                    break;
+
                 case 'r':
                     m_func_regexp.assign (option_arg);
                     break;
 
                 case 's':
-                    {
-                        m_modules.AppendIfUnique (FileSpec (option_arg, false));
-                        break;
-                    }
-                case 'i':
                 {
-                    m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
-                    if (m_ignore_count == UINT32_MAX)
-                       error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
+                    m_modules.AppendIfUnique (FileSpec (option_arg, false));
+                    break;
                 }
-                break;
+                    
+                case 'S':
+                    m_func_names.push_back (option_arg);
+                    m_func_name_type_mask |= eFunctionNameTypeSelector;
+                    break;
+
                 case 't' :
                 {
                     m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
@@ -198,48 +261,11 @@
                        error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
                 }
                 break;
+
                 case 'T':
                     m_thread_name.assign (option_arg);
                     break;
-                case 'q':
-                    m_queue_name.assign (option_arg);
-                    break;
-                case 'x':
-                {
-                    m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
-                    if (m_thread_id == UINT32_MAX)
-                       error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
-                    
-                }
-                break;
-                case 'E':
-                {
-                    LanguageType language = LanguageRuntime::GetLanguageTypeFromString (option_arg);
 
-                    switch (language)
-                    {
-                        case eLanguageTypeC89:
-                        case eLanguageTypeC:
-                        case eLanguageTypeC99:
-                            m_language = eLanguageTypeC;
-                            break;
-                        case eLanguageTypeC_plus_plus:
-                            m_language = eLanguageTypeC_plus_plus;
-                            break;
-                        case eLanguageTypeObjC:
-                            m_language = eLanguageTypeObjC;
-                            break;
-                        case eLanguageTypeObjC_plus_plus:
-                            error.SetErrorStringWithFormat ("Set exception breakpoints separately for c++ and objective-c");
-                            break;
-                        case eLanguageTypeUnknown:
-                            error.SetErrorStringWithFormat ("Unknown language type: '%s' for exception breakpoint", option_arg);
-                            break;
-                        default:
-                            error.SetErrorStringWithFormat ("Unsupported language type: '%s' for exception breakpoint", option_arg);
-                    }
-                }
-                break;
                 case 'w':
                 {
                     bool success;
@@ -248,27 +274,16 @@
                         error.SetErrorStringWithFormat ("Invalid boolean value for on-throw option: '%s'", option_arg);
                 }
                 break;
-                case 'h':
-                {
-                    bool success;
-                    m_catch_bp = Args::StringToBoolean (option_arg, true, &success);
-                    if (!success)
-                        error.SetErrorStringWithFormat ("Invalid boolean value for on-catch option: '%s'", option_arg);
-                }
-                case 'K':
+
+                case 'x':
                 {
-                    bool success;
-                    bool value;
-                    value = Args::StringToBoolean (option_arg, true, &success);
-                    if (value)
-                        m_skip_prologue = eLazyBoolYes;
-                    else
-                        m_skip_prologue = eLazyBoolNo;
-                        
-                    if (!success)
-                        error.SetErrorStringWithFormat ("Invalid boolean value for skip prologue option: '%s'", option_arg);
+                    m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
+                    if (m_thread_id == UINT32_MAX)
+                       error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
+                    
                 }
                 break;
+
                 default:
                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
                     break;
@@ -298,6 +313,7 @@
             m_throw_bp = true;
             m_language = eLanguageTypeUnknown;
             m_skip_prologue = eLazyBoolCalculate;
+            m_one_shot = false;
         }
     
         const OptionDefinition*
@@ -331,6 +347,7 @@
         bool m_throw_bp;
         lldb::LanguageType m_language;
         LazyBool m_skip_prologue;
+        bool m_one_shot;
 
     };
 
@@ -511,6 +528,8 @@
 
             if (!m_options.m_condition.empty())
                 bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
+            
+            bp->SetOneShot (m_options.m_one_shot);
         }
         
         if (bp)
@@ -591,6 +610,9 @@
     { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', required_argument,   NULL, 0, eArgTypeCount,
         "Set the number of times this breakpoint is skipped before stopping." },
 
+    { LLDB_OPT_SET_ALL, false, "one-shot", 'o', no_argument,   NULL, 0, eArgTypeNone,
+        "The breakpoint is deleted the first time it stop causes a stop." },
+
     { LLDB_OPT_SET_ALL, false, "condition",    'c', required_argument, NULL, 0, eArgTypeExpression,
         "The breakpoint stops only if this condition expression evaluates to true."},
 
@@ -707,11 +729,13 @@
             m_thread_name(),
             m_queue_name(),
             m_condition (),
+            m_one_shot (false),
             m_enable_passed (false),
             m_enable_value (false),
             m_name_passed (false),
             m_queue_passed (false),
-            m_condition_passed (false)
+            m_condition_passed (false),
+            m_one_shot_passed (false)
         {
         }
 
@@ -748,6 +772,19 @@
                        error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
                 }
                 break;
+                case 'o':
+                {
+                    bool value, success;
+                    value = Args::StringToBoolean(option_arg, false, &success);
+                    if (success)
+                    {
+                        m_one_shot_passed = true;
+                        m_one_shot = value;
+                    }
+                    else
+                        error.SetErrorStringWithFormat("invalid boolean value '%s' passed for -o option", option_arg);
+                }
+                break;
                 case 't' :
                 {
                     if (option_arg[0] == '\0')
@@ -814,10 +851,12 @@
             m_thread_name.clear();
             m_queue_name.clear();
             m_condition.clear();
+            m_one_shot = false;
             m_enable_passed = false;
             m_queue_passed = false;
             m_name_passed = false;
             m_condition_passed = false;
+            m_one_shot_passed = false;
         }
         
         const OptionDefinition*
@@ -841,11 +880,13 @@
         std::string m_thread_name;
         std::string m_queue_name;
         std::string m_condition;
+        bool m_one_shot;
         bool m_enable_passed;
         bool m_enable_value;
         bool m_name_passed;
         bool m_queue_passed;
         bool m_condition_passed;
+        bool m_one_shot_passed;
 
     };
 
@@ -944,6 +985,7 @@
 CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
 {
 { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', required_argument, NULL, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
+{ LLDB_OPT_SET_ALL, false, "one-shot",     'o', required_argument, NULL, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." },
 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose indeX matches this argument."},
 { LLDB_OPT_SET_ALL, false, "thread-id",    't', required_argument, NULL, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument."},
 { LLDB_OPT_SET_ALL, false, "thread-name",  'T', required_argument, NULL, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument."},
@@ -951,7 +993,7 @@
 { LLDB_OPT_SET_ALL, false, "condition",    'c', required_argument, NULL, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."},
 { LLDB_OPT_SET_1,   false, "enable",       'e', no_argument,       NULL, 0, eArgTypeNone, "Enable the breakpoint."},
 { LLDB_OPT_SET_2,   false, "disable",      'd', no_argument,       NULL, 0, eArgTypeNone, "Disable the breakpoint."},
-{ 0,                false, NULL,            0 , 0,                 NULL, 0,    eArgTypeNone, NULL }
+{ 0,                false, NULL,            0 , 0,                 NULL, 0, eArgTypeNone, NULL }
 };
 
 //-------------------------------------------------------------------------

Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=165328&r1=165327&r2=165328&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original)
+++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Fri Oct  5 14:16:31 2012
@@ -156,6 +156,14 @@
     if (cmd_obj_sp)
         AddAlias ("b", cmd_obj_sp);
 
+    cmd_obj_sp = GetCommandSPExact ("_regexp-tbreak",false);
+    if (cmd_obj_sp)
+        AddAlias ("tbreak", cmd_obj_sp);
+
+    cmd_obj_sp = GetCommandSPExact ("thread backtrace", false);
+    if (cmd_obj_sp)
+        AddAlias ("bt", cmd_obj_sp);
+
     cmd_obj_sp = GetCommandSPExact ("thread step-inst", false);
     if (cmd_obj_sp)
     {
@@ -196,6 +204,12 @@
         AddAlias ("f", cmd_obj_sp);
     }
 
+    cmd_obj_sp = GetCommandSPExact ("thread select", false);
+    if (cmd_obj_sp)
+    {
+        AddAlias ("t", cmd_obj_sp);
+    }
+
     cmd_obj_sp = GetCommandSPExact ("source list", false);
     if (cmd_obj_sp)
     {
@@ -366,21 +380,34 @@
     m_command_dict["version"]   = CommandObjectSP (new CommandObjectVersion (*this));
     m_command_dict["watchpoint"]= CommandObjectSP (new CommandObjectMultiwordWatchpoint (*this));
 
+    const char *break_regexes[][2] = {{"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$", "breakpoint set --file '%1' --line %2"},
+                                      {"^([[:digit:]]+)[[:space:]]*$", "breakpoint set --line %1"},
+                                      {"^(0x[[:xdigit:]]+)[[:space:]]*$", "breakpoint set --address %1"},
+                                      {"^[\"']?([-+]\\[.*\\])[\"']?[[:space:]]*$", "breakpoint set --name '%1'"},
+                                      {"^(-.*)$", "breakpoint set %1"},
+                                      {"^(.*[^[:space:]])`(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%2' --shlib '%1'"},
+                                      {"^(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%1'"}};
+    
+    size_t num_regexes = sizeof break_regexes/sizeof(char *[2]);
+        
     std::auto_ptr<CommandObjectRegexCommand>
     break_regex_cmd_ap(new CommandObjectRegexCommand (*this,
                                                       "_regexp-break",
                                                       "Set a breakpoint using a regular expression to specify the location, where <linenum> is in decimal and <address> is in hex.",
                                                       "_regexp-break [<filename>:<linenum>]\n_regexp-break [<linenum>]\n_regexp-break [<address>]\n_regexp-break <...>", 2));
+
     if (break_regex_cmd_ap.get())
     {
-        if (break_regex_cmd_ap->AddRegexCommand("^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$", "breakpoint set --file '%1' --line %2") &&
-            break_regex_cmd_ap->AddRegexCommand("^([[:digit:]]+)[[:space:]]*$", "breakpoint set --line %1") &&
-            break_regex_cmd_ap->AddRegexCommand("^(0x[[:xdigit:]]+)[[:space:]]*$", "breakpoint set --address %1") &&
-            break_regex_cmd_ap->AddRegexCommand("^[\"']?([-+]\\[.*\\])[\"']?[[:space:]]*$", "breakpoint set --name '%1'") &&
-            break_regex_cmd_ap->AddRegexCommand("^$", "breakpoint list --full") &&
-            break_regex_cmd_ap->AddRegexCommand("^(-.*)$", "breakpoint set %1") &&
-            break_regex_cmd_ap->AddRegexCommand("^(.*[^[:space:]])`(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%2' --shlib '%1'") &&
-            break_regex_cmd_ap->AddRegexCommand("^(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%1'"))
+        bool success = true;
+        for (size_t i = 0; i < num_regexes; i++)
+        {
+            success = break_regex_cmd_ap->AddRegexCommand (break_regexes[i][0], break_regexes[i][1]);
+            if (!success)
+                break;
+        }
+        success = break_regex_cmd_ap->AddRegexCommand("^$", "breakpoint list --full");
+
+        if (success)
         {
             CommandObjectSP break_regex_cmd_sp(break_regex_cmd_ap.release());
             m_command_dict[break_regex_cmd_sp->GetCommandName ()] = break_regex_cmd_sp;
@@ -388,6 +415,34 @@
     }
 
     std::auto_ptr<CommandObjectRegexCommand>
+    tbreak_regex_cmd_ap(new CommandObjectRegexCommand (*this,
+                                                      "_regexp-tbreak",
+                                                      "Set a one shot breakpoint using a regular expression to specify the location, where <linenum> is in decimal and <address> is in hex.",
+                                                      "_regexp-tbreak [<filename>:<linenum>]\n_regexp-break [<linenum>]\n_regexp-break [<address>]\n_regexp-break <...>", 2));
+
+    if (tbreak_regex_cmd_ap.get())
+    {
+        bool success = true;
+        for (size_t i = 0; i < num_regexes; i++)
+        {
+            // If you add a resultant command string longer than 1024 characters be sure to increase the size of this buffer.
+            char buffer[1024];
+            int num_printed = snprintf(buffer, 1024, "%s %s", break_regexes[i][1], "-o");
+            assert (num_printed < 1024);
+            success = tbreak_regex_cmd_ap->AddRegexCommand (break_regexes[i][0], buffer);
+            if (!success)
+                break;
+        }
+        success = tbreak_regex_cmd_ap->AddRegexCommand("^$", "breakpoint list --full");
+
+        if (success)
+        {
+            CommandObjectSP tbreak_regex_cmd_sp(tbreak_regex_cmd_ap.release());
+            m_command_dict[tbreak_regex_cmd_sp->GetCommandName ()] = tbreak_regex_cmd_sp;
+        }
+    }
+
+    std::auto_ptr<CommandObjectRegexCommand>
     attach_regex_cmd_ap(new CommandObjectRegexCommand (*this,
                                                        "_regexp-attach",
                                                        "Attach to a process id if in decimal, otherwise treat the argument as a process name to attach to.",

Modified: lldb/trunk/source/Target/StopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StopInfo.cpp?rev=165328&r1=165327&r2=165328&view=diff
==============================================================================
--- lldb/trunk/source/Target/StopInfo.cpp (original)
+++ lldb/trunk/source/Target/StopInfo.cpp Fri Oct  5 14:16:31 2012
@@ -99,13 +99,11 @@
         m_should_stop (false),
         m_should_stop_is_valid (false),
         m_should_perform_action (true),
-        m_address (LLDB_INVALID_ADDRESS)
+        m_address (LLDB_INVALID_ADDRESS),
+        m_break_id(LLDB_INVALID_BREAK_ID),
+        m_was_one_shot (false)
     {
-        BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (m_value));
-        if (bp_site_sp)
-        {
-          m_address = bp_site_sp->GetLoadAddress();
-        }
+        StoreBPInfo();
     }
     
     StopInfoBreakpoint (Thread &thread, break_id_t break_id, bool should_stop) :
@@ -114,12 +112,28 @@
         m_should_stop (should_stop),
         m_should_stop_is_valid (true),
         m_should_perform_action (true),
-        m_address (LLDB_INVALID_ADDRESS)
+        m_address (LLDB_INVALID_ADDRESS),
+        m_break_id(LLDB_INVALID_BREAK_ID),
+        m_was_one_shot (false)
+    {
+        StoreBPInfo();
+    }
+
+    void StoreBPInfo ()
     {
         BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByID (m_value));
         if (bp_site_sp)
         {
-          m_address = bp_site_sp->GetLoadAddress();
+            if (bp_site_sp->GetNumberOfOwners() == 1)
+            {
+                BreakpointLocationSP bp_loc_sp = bp_site_sp->GetOwnerAtIndex(0);
+                if (bp_loc_sp)
+                {
+                    m_break_id = bp_loc_sp->GetBreakpoint().GetID();
+                    m_was_one_shot = bp_loc_sp->GetBreakpoint().IsOneShot();
+                }
+            }
+            m_address = bp_site_sp->GetLoadAddress();
         }
     }
 
@@ -298,6 +312,12 @@
                     
                     if (callback_says_stop)
                         m_should_stop = true;
+                    
+                    // If we are going to stop for this breakpoint, then remove the breakpoint.
+                    if (callback_says_stop && bp_loc_sp && bp_loc_sp->GetBreakpoint().IsOneShot())
+                    {
+                        m_thread.GetProcess()->GetTarget().RemoveBreakpointByID (bp_loc_sp->GetBreakpoint().GetID());
+                    }
                         
                     // Also make sure that the callback hasn't continued the target.  
                     // If it did, when we'll set m_should_start to false and get out of here.
@@ -362,10 +382,18 @@
             else
             {
                 StreamString strm;
-                if (m_address == LLDB_INVALID_ADDRESS)
+                if (m_break_id != LLDB_INVALID_BREAK_ID)
+                {
+                    if (m_was_one_shot)
+                        strm.Printf ("one-shot breakpoint %d", m_break_id);
+                    else
+                        strm.Printf ("breakpoint %d which has been deleted.", m_break_id);
+                }
+                else if (m_address == LLDB_INVALID_ADDRESS)
                     strm.Printf("breakpoint site %lli which has been deleted - unknown address", m_value);
                 else
                     strm.Printf("breakpoint site %lli which has been deleted - was at 0x%llx", m_value, m_address);
+                
                 m_description.swap (strm.GetString());
             }
         }
@@ -381,6 +409,8 @@
     lldb::addr_t m_address;       // We use this to capture the breakpoint site address when we create the StopInfo,
                                   // in case somebody deletes it between the time the StopInfo is made and the
                                   // description is asked for.
+    lldb::break_id_t m_break_id;
+    bool m_was_one_shot;
 };
 
 

Modified: lldb/trunk/test/functionalities/abbreviation/TestAbbreviations.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/abbreviation/TestAbbreviations.py?rev=165328&r1=165327&r2=165328&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/abbreviation/TestAbbreviations.py (original)
+++ lldb/trunk/test/functionalities/abbreviation/TestAbbreviations.py Fri Oct  5 14:16:31 2012
@@ -36,6 +36,7 @@
                     startstr = "The following is a list of built-in, permanent debugger commands:")
 
         # Several matching commands: list them and error out.
+        self.runCmd("command unalias t")
         self.expect("t",
                     COMMAND_FAILED_AS_EXPECTED, error = True,
                     substrs = ["Ambiguous command 't'. Possible matches:",





More information about the lldb-commits mailing list