[Lldb-commits] [lldb] r112502 - in /lldb/trunk: include/lldb/API/SBDebugger.h include/lldb/Core/Debugger.h include/lldb/Host/Host.h lldb.xcodeproj/project.pbxproj source/API/SBDebugger.cpp source/Commands/CommandObjectFrame.cpp source/Commands/CommandObjectThread.cpp source/Core/Debugger.cpp source/Host/macosx/Host.mm source/Host/macosx/cfcpp/CFCReleaser.h tools/driver/Driver.cpp tools/driver/Driver.h

Jim Ingham jingham at apple.com
Mon Aug 30 12:44:40 PDT 2010


Author: jingham
Date: Mon Aug 30 14:44:40 2010
New Revision: 112502

URL: http://llvm.org/viewvc/llvm-project?rev=112502&view=rev
Log:
Added a way to open the current source file & line in an external editor, and you can turn this on with:

lldb -e

Modified:
    lldb/trunk/include/lldb/API/SBDebugger.h
    lldb/trunk/include/lldb/Core/Debugger.h
    lldb/trunk/include/lldb/Host/Host.h
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/source/API/SBDebugger.cpp
    lldb/trunk/source/Commands/CommandObjectFrame.cpp
    lldb/trunk/source/Commands/CommandObjectThread.cpp
    lldb/trunk/source/Core/Debugger.cpp
    lldb/trunk/source/Host/macosx/Host.mm
    lldb/trunk/source/Host/macosx/cfcpp/CFCReleaser.h
    lldb/trunk/tools/driver/Driver.cpp
    lldb/trunk/tools/driver/Driver.h

Modified: lldb/trunk/include/lldb/API/SBDebugger.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBDebugger.h?rev=112502&r1=112501&r2=112502&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBDebugger.h (original)
+++ lldb/trunk/include/lldb/API/SBDebugger.h Mon Aug 30 14:44:40 2010
@@ -106,6 +106,14 @@
 
     lldb::SBSourceManager &
     GetSourceManager ();
+    
+    // FIXME: Once we get the set show stuff in place, the driver won't need
+    // an interface to the Set/Get UseExternalEditor.
+    bool
+    SetUseExternalEditor (bool input);
+    
+    bool 
+    UseExternalEditor ();
 
     bool
     GetDefaultArchitecture (char *arch_name, size_t arch_name_len);

Modified: lldb/trunk/include/lldb/Core/Debugger.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Debugger.h?rev=112502&r1=112501&r2=112502&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Debugger.h (original)
+++ lldb/trunk/include/lldb/Core/Debugger.h Mon Aug 30 14:44:40 2010
@@ -143,6 +143,20 @@
 
     static lldb::DebuggerSP
     FindDebuggerWithID (lldb::user_id_t id);
+    
+    bool
+    SetUseExternalEditor (bool value)
+    {
+        bool old_value = m_use_external_editor;
+        m_use_external_editor = value;
+        return old_value;
+    }
+    
+    bool
+    UseExternalEditor ()
+    {
+        return m_use_external_editor;
+    }
 
 protected:
 
@@ -170,6 +184,7 @@
 
     std::stack<lldb::InputReaderSP> m_input_readers;
     std::string m_input_reader_data;
+    bool m_use_external_editor;   // FIXME: Convert this to a set/show variable on the debugger.
 
 private:
 

Modified: lldb/trunk/include/lldb/Host/Host.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/Host.h?rev=112502&r1=112501&r2=112502&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/Host.h (original)
+++ lldb/trunk/include/lldb/Host/Host.h Mon Aug 30 14:44:40 2010
@@ -267,6 +267,9 @@
     
     static ArchSpec
     GetArchSpecForExistingProcess (const char *process_name);
+    
+    static bool
+    OpenFileInExternalEditor (FileSpec &file_spec, uint32_t line_no);
 
 };
 

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=112502&r1=112501&r2=112502&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Mon Aug 30 14:44:40 2010
@@ -356,6 +356,7 @@
 		4C08CDEC11C81F1E001610A8 /* ThreadSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C08CDEB11C81F1E001610A8 /* ThreadSpec.h */; };
 		4C5DBBC811E3FEC60035160F /* CommandObjectCommands.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C5DBBC611E3FEC60035160F /* CommandObjectCommands.cpp */; };
 		4C5DBBC911E3FEC60035160F /* CommandObjectCommands.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C5DBBC711E3FEC60035160F /* CommandObjectCommands.h */; };
+		4C74CB6312288704006A8171 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C74CB6212288704006A8171 /* Carbon.framework */; };
 		4CA9637B11B6E99A00780E28 /* CommandObjectApropos.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CA9637911B6E99A00780E28 /* CommandObjectApropos.cpp */; };
 		9A19A6AF1163BBB200E0D453 /* SBValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A19A6A51163BB7E00E0D453 /* SBValue.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		9A19A6B01163BBB300E0D453 /* SBValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A19A6AD1163BB9800E0D453 /* SBValue.cpp */; };
@@ -960,6 +961,7 @@
 		4C51FF1611A4C486007C962F /* ObjCTrampolineHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ObjCTrampolineHandler.cpp; sourceTree = "<group>"; };
 		4C5DBBC611E3FEC60035160F /* CommandObjectCommands.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectCommands.cpp; path = source/Commands/CommandObjectCommands.cpp; sourceTree = "<group>"; };
 		4C5DBBC711E3FEC60035160F /* CommandObjectCommands.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectCommands.h; path = source/Commands/CommandObjectCommands.h; sourceTree = "<group>"; };
+		4C74CB6212288704006A8171 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
 		4C98D3DA118FB96F00E575D0 /* ClangFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangFunction.cpp; path = source/Expression/ClangFunction.cpp; sourceTree = "<group>"; };
 		4C98D3DB118FB96F00E575D0 /* RecordingMemoryManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RecordingMemoryManager.cpp; path = source/Expression/RecordingMemoryManager.cpp; sourceTree = "<group>"; };
 		4C98D3E0118FB98F00E575D0 /* ClangFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangFunction.h; path = include/lldb/Expression/ClangFunction.h; sourceTree = "<group>"; };
@@ -1075,6 +1077,7 @@
 				26680231115FD1A0008E1FE4 /* Foundation.framework in Frameworks */,
 				26680232115FD1A4008E1FE4 /* libpython2.6.dylib in Frameworks */,
 				26680233115FD1A7008E1FE4 /* libobjc.dylib in Frameworks */,
+				4C74CB6312288704006A8171 /* Carbon.framework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -1105,6 +1108,7 @@
 				08FB7795FE84155DC02AAC07 /* Source */,
 				26F5C22410F3D950009D5894 /* Tools */,
 				1AB674ADFE9D54B511CA2CBB /* Products */,
+				4C74CB6212288704006A8171 /* Carbon.framework */,
 			);
 			name = lldb;
 			sourceTree = "<group>";

Modified: lldb/trunk/source/API/SBDebugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBDebugger.cpp?rev=112502&r1=112501&r2=112502&view=diff
==============================================================================
--- lldb/trunk/source/API/SBDebugger.cpp (original)
+++ lldb/trunk/source/API/SBDebugger.cpp Mon Aug 30 14:44:40 2010
@@ -563,3 +563,23 @@
         sb_debugger.reset (debugger_sp);
     return sb_debugger;
 }
+
+bool
+SBDebugger::SetUseExternalEditor (bool value)
+{
+    if (m_opaque_sp)
+        return m_opaque_sp->SetUseExternalEditor (value);
+    else
+        return false;
+}
+
+bool
+SBDebugger::UseExternalEditor ()
+{
+    if (m_opaque_sp)
+        return m_opaque_sp->UseExternalEditor ();
+    else
+        return false;
+}
+
+

Modified: lldb/trunk/source/Commands/CommandObjectFrame.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectFrame.cpp?rev=112502&r1=112501&r2=112502&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectFrame.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectFrame.cpp Mon Aug 30 14:44:40 2010
@@ -114,12 +114,19 @@
 
                     if (exe_ctx.frame)
                     {
+                        bool already_shown = false;
+                        SymbolContext frame_sc(exe_ctx.frame->GetSymbolContext(eSymbolContextLineEntry));
+                        if (interpreter.GetDebugger().UseExternalEditor() && frame_sc.line_entry.file && frame_sc.line_entry.line != 0)
+                        {
+                            already_shown = Host::OpenFileInExternalEditor (frame_sc.line_entry.file, frame_sc.line_entry.line);
+                        }
+
                         if (DisplayFrameForExecutionContext (exe_ctx.thread,
                                                              exe_ctx.frame,
                                                              interpreter,
                                                              result.GetOutputStream(),
                                                              true,
-                                                             true,
+                                                             !already_shown,
                                                              3,
                                                              3))
                         {

Modified: lldb/trunk/source/Commands/CommandObjectThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectThread.cpp?rev=112502&r1=112501&r2=112502&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectThread.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectThread.cpp Mon Aug 30 14:44:40 2010
@@ -60,13 +60,21 @@
         // Show one frame with only the first showing source
         if (show_source)
         {
+            bool already_shown = false;
+            StackFrameSP frame_sp = thread->GetStackFrameAtIndex(0);
+            SymbolContext frame_sc(frame_sp->GetSymbolContext (eSymbolContextLineEntry));
+            if (interpreter.GetDebugger().UseExternalEditor() && frame_sc.line_entry.file && frame_sc.line_entry.line != 0)
+            {
+                already_shown = Host::OpenFileInExternalEditor (frame_sc.line_entry.file, frame_sc.line_entry.line);
+            }
+            
             DisplayFramesForExecutionContext (thread,
                                               interpreter,
                                               strm,
                                               0,    // Start at first frame
                                               1,    // Number of frames to show
                                               false,// Don't show the frame info since we already displayed most of it above...
-                                              1,    // Show source for the first frame
+                                              !already_shown,    // Show source for the first frame
                                               3,    // lines of source context before
                                               3);   // lines of source context after
         }

Modified: lldb/trunk/source/Core/Debugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=112502&r1=112501&r2=112502&view=diff
==============================================================================
--- lldb/trunk/source/Core/Debugger.cpp (original)
+++ lldb/trunk/source/Core/Debugger.cpp Mon Aug 30 14:44:40 2010
@@ -128,7 +128,8 @@
     m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)),
     m_exe_ctx (),
     m_input_readers (),
-    m_input_reader_data ()
+    m_input_reader_data (),
+    m_use_external_editor(false)
 {
     m_command_interpreter_ap->Initialize ();
 }

Modified: lldb/trunk/source/Host/macosx/Host.mm
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/Host.mm?rev=112502&r1=112501&r2=112502&view=diff
==============================================================================
--- lldb/trunk/source/Host/macosx/Host.mm (original)
+++ lldb/trunk/source/Host/macosx/Host.mm Mon Aug 30 14:44:40 2010
@@ -24,6 +24,8 @@
 #include <objc/objc-auto.h>
 
 #include <Foundation/Foundation.h>
+#include <CoreServices/CoreServices.h>
+#include <Carbon/Carbon.h>
 
 #include "cfcpp/CFCBundle.h"
 #include "cfcpp/CFCReleaser.h"
@@ -779,3 +781,116 @@
     }
     return returnSpec;
 }
+
+bool
+Host::OpenFileInExternalEditor (FileSpec &file_spec, uint32_t line_no)
+{
+    // We attach this to an 'odoc' event to specify a particular selection
+    typedef struct {
+      int16_t      reserved0;      // must be zero
+      int16_t      fLineNumber;
+      int32_t      fSelStart;
+      int32_t      fSelEnd;
+      uint32_t      reserved1;      // must be zero
+      uint32_t      reserved2;      // must be zero
+    } BabelAESelInfo;
+    
+    char file_path[PATH_MAX];
+    file_spec.GetPath(file_path, PATH_MAX);
+    CFCString file_cfstr (file_path, kCFStringEncodingUTF8);
+    CFCReleaser<CFURLRef> file_URL(::CFURLCreateWithFileSystemPath(NULL, file_cfstr.get(), kCFURLPOSIXPathStyle, false));
+
+    OSStatus error;	
+    BabelAESelInfo file_and_line_info;
+
+    AEKeyDesc file_and_line_desc;
+    
+    bzero(&file_and_line_info, sizeof (file_and_line_info));
+    file_and_line_info.fSelStart = 1;
+    file_and_line_info.fSelEnd = 1;
+    file_and_line_info.fLineNumber = line_no - 1;
+    
+    error = AECreateDesc(typeChar, &file_and_line_info, sizeof (file_and_line_info), &(file_and_line_desc.descContent));
+    if (error != noErr)
+    {
+        return false;
+    }
+    
+    file_and_line_desc.descKey = keyAEPosition;
+    
+    LSApplicationParameters app_params;
+    bzero (&app_params, sizeof (app_params));
+    app_params.flags = kLSLaunchDefaults | kLSLaunchDontSwitch;
+
+    ProcessSerialNumber psn;
+    CFCReleaser<CFArrayRef> file_array(CFArrayCreate (NULL, (const void **) file_URL.ptr_address(false), 1, NULL));
+    error = LSOpenURLsWithRole(file_array.get(), kLSRolesAll, &file_and_line_desc, &app_params, &psn, 1);
+
+    AEDisposeDesc (&(file_and_line_desc.descContent));
+
+    if (error != noErr)
+    {
+        return false;
+    }
+    
+    ProcessInfoRec which_process;
+    bzero(&which_process, sizeof(which_process));
+    unsigned char ap_name[PATH_MAX];
+    which_process.processName = ap_name;
+    error = GetProcessInformation (&psn, &which_process);
+    
+    bool using_xcode = strncmp((char *) ap_name+1, "Xcode", 5) == 0;
+    
+    // Xcode doesn't obey the line number in the Open Apple Event.  So I have to send
+    // it an AppleScript to focus on the right line.
+    
+    if (using_xcode)
+    {
+        static ComponentInstance osa_component = NULL;
+        static const char *as_template = "tell application \"Xcode\"\n"
+                                   "set doc to the first document whose path is \"%s\"\n"
+                                   "set the selection to paragraph %d of doc\n"
+                                   "--- set the selected paragraph range to {%d, %d} of doc\n"
+                                   "end tell\n";
+        const int chars_for_int = 32;
+        static int as_template_len = strlen (as_template);
+
+      
+        char *as_str;
+        AEDesc as_desc;
+      
+        if (osa_component == NULL)
+        {
+            osa_component = OpenDefaultComponent (kOSAComponentType, 
+                        kAppleScriptSubtype);
+        }
+        
+        if (osa_component == NULL)
+        {
+            return false;
+        }
+
+        uint32_t as_str_size = as_template_len + strlen (file_path) + 3 * chars_for_int + 1;     
+        as_str = (char *) malloc (as_str_size);
+        snprintf (as_str, as_str_size - 1, as_template, file_path, line_no, line_no, line_no);
+        error = AECreateDesc (typeChar, as_str, strlen (as_str), &as_desc);
+
+        free (as_str);
+
+        if (error != noErr)
+            return false;
+            
+        OSAID ret_OSAID;
+        error = OSACompileExecute (osa_component, &as_desc, kOSANullScript, 
+                   kOSAModeNeverInteract, &ret_OSAID);
+
+        OSADispose (osa_component, ret_OSAID);
+
+        AEDisposeDesc (&as_desc);
+
+        if (error != noErr)
+            return false;
+    }
+      
+    return true;
+}

Modified: lldb/trunk/source/Host/macosx/cfcpp/CFCReleaser.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/cfcpp/CFCReleaser.h?rev=112502&r1=112501&r2=112502&view=diff
==============================================================================
--- lldb/trunk/source/Host/macosx/cfcpp/CFCReleaser.h (original)
+++ lldb/trunk/source/Host/macosx/cfcpp/CFCReleaser.h Mon Aug 30 14:44:40 2010
@@ -96,11 +96,14 @@
     // assertion fires, check the offending code, or call
     // reset() prior to using the "ptr_address()" member to make
     // sure any owned objects has CFRelease called on it.
+    // I had to add the "enforce_null" bool here because some
+    // API's require the pointer address even though they don't change it.
     //----------------------------------------------------------
     T*
-    ptr_address()
+    ptr_address(bool enforce_null = true)
     {
-        assert (_ptr == NULL);
+        if (enforce_null)
+            assert (_ptr == NULL);
         return &_ptr;
     }
 

Modified: lldb/trunk/tools/driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/Driver.cpp?rev=112502&r1=112501&r2=112502&view=diff
==============================================================================
--- lldb/trunk/tools/driver/Driver.cpp (original)
+++ lldb/trunk/tools/driver/Driver.cpp Mon Aug 30 14:44:40 2010
@@ -70,6 +70,9 @@
     { LLDB_OPT_SET_3,  true,  "file",           'f',  required_argument,  NULL,  NULL,  "<filename>",
         "Tells the debugger to use the file <filename> as the program to be debugged." },
 
+    { LLDB_OPT_SET_ALL,  false,  "editor",           'e',  no_argument,  NULL,  NULL,  "<external-editor>",
+        "Tells the debugger to open source files using the host's \"external editor\" mechanism." },
+
 //    { LLDB_OPT_SET_4,  true,  "crash-log",      'c',  required_argument,  NULL,  NULL,  "<file>",
 //        "Load executable images from a crash log for symbolication." },
 
@@ -324,7 +327,8 @@
     m_debug_mode (false),
     m_print_version (false),
     m_print_help (false),
-    m_seen_options()
+    m_seen_options(),
+    m_use_external_editor(false)
 {
 }
 
@@ -341,6 +345,7 @@
     m_debug_mode = false;
     m_print_help = false;
     m_print_version = false;
+    m_use_external_editor = false;
 }
 
 void
@@ -508,7 +513,10 @@
                     case 'c':
                         m_option_data.m_crash_log = optarg;
                         break;
-
+                    case 'e':
+                        m_option_data.m_use_external_editor = true;
+                        break;
+                        
                     case 'f':
                         {
                             SBFileSpec file(optarg);
@@ -1042,6 +1050,8 @@
     m_debugger.SetErrorFileHandle (stderr, false);
     m_debugger.SetOutputFileHandle (stdout, false);
     m_debugger.SetInputFileHandle (stdin, true);
+    
+    m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor);
 
     // You have to drain anything that comes to the master side of the PTY.  master_out_comm is
     // for that purpose.  The reason you need to do this is a curious reason...  editline will echo

Modified: lldb/trunk/tools/driver/Driver.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/Driver.h?rev=112502&r1=112501&r2=112502&view=diff
==============================================================================
--- lldb/trunk/tools/driver/Driver.h (original)
+++ lldb/trunk/tools/driver/Driver.h Mon Aug 30 14:44:40 2010
@@ -103,6 +103,7 @@
         bool m_debug_mode;
         bool m_print_version;
         bool m_print_help;
+        bool m_use_external_editor;  // FIXME: When we have set/show variables we can remove this from here.
         typedef std::set<char> OptionSet;
         OptionSet m_seen_options;
     };





More information about the lldb-commits mailing list