2010-06-09 00:52:24 +08:00
//===-- CommandObjectSource.cpp ---------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
2012-12-05 08:20:57 +08:00
# include "lldb/lldb-python.h"
2010-06-09 00:52:24 +08:00
# include "CommandObjectSource.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
2010-06-16 03:49:27 +08:00
# include "lldb/Interpreter/Args.h"
2010-06-23 09:19:29 +08:00
# include "lldb/Core/Debugger.h"
Added a new option to the "source list" command that allows us to see where
line tables specify breakpoints can be set in the source. When dumping the
source, the number of breakpoints that can be set on a source line are shown
as a prefix:
(lldb) source list -f test.c -l1 -c222 -b
1 #include <stdio.h>
2 #include <sys/fcntl.h>
3 #include <unistd.h>
4 int
5 sleep_loop (const int num_secs)
[2] 6 {
7 int i;
[1] 8 for (i=0; i<num_secs; ++i)
9 {
[1] 10 printf("%d of %i - sleep(1);\n", i, num_secs);
[1] 11 sleep(1);
12 }
13 return 0;
[1] 14 }
15
16 int
17 main (int argc, char const* argv[])
[1] 18 {
[1] 19 printf("Process: %i\n\n", getpid());
[1] 20 puts("Press any key to continue..."); getchar();
[1] 21 sleep_loop (20);
22 return 12;
[1] 23 }
Above we can see there are two breakpoints for line 6 and one breakpoint for
lines 8, 10, 11, 14, 18, 19, 20, 21 and 23. All other lines have no line table
entries for them. This helps visualize the data provided in the debug
information without having to manually dump all line tables. It also includes
all inline breakpoint that may result for a given file which can also be very
handy to see.
llvm-svn: 129747
2011-04-19 12:19:37 +08:00
# include "lldb/Core/FileLineResolver.h"
2012-12-07 08:19:47 +08:00
# include "lldb/Core/Module.h"
<rdar://problem/11757916>
Make breakpoint setting by file and line much more efficient by only looking for inlined breakpoint locations if we are setting a breakpoint in anything but a source implementation file. Implementing this complex for a many reasons. Turns out that parsing compile units lazily had some issues with respect to how we need to do things with DWARF in .o files. So the fixes in the checkin for this makes these changes:
- Add a new setting called "target.inline-breakpoint-strategy" which can be set to "never", "always", or "headers". "never" will never try and set any inlined breakpoints (fastest). "always" always looks for inlined breakpoint locations (slowest, but most accurate). "headers", which is the default setting, will only look for inlined breakpoint locations if the breakpoint is set in what are consudered to be header files, which is realy defined as "not in an implementation source file".
- modify the breakpoint setting by file and line to check the current "target.inline-breakpoint-strategy" setting and act accordingly
- Modify compile units to be able to get their language and other info lazily. This allows us to create compile units from the debug map and not have to fill all of the details in, and then lazily discover this information as we go on debuggging. This is needed to avoid parsing all .o files when setting breakpoints in implementation only files (no inlines). Otherwise we would need to parse the .o file, the object file (mach-o in our case) and the symbol file (DWARF in the object file) just to see what the compile unit was.
- modify the "SymbolFileDWARFDebugMap" to subclass lldb_private::Module so that the virtual "GetObjectFile()" and "GetSymbolVendor()" functions can be intercepted when the .o file contenst are later lazilly needed. Prior to this fix, when we first instantiated the "SymbolFileDWARFDebugMap" class, we would also make modules, object files and symbol files for every .o file in the debug map because we needed to fix up the sections in the .o files with information that is in the executable debug map. Now we lazily do this in the DebugMapModule::GetObjectFile()
Cleaned up header includes a bit as well.
llvm-svn: 162860
2012-08-30 05:13:06 +08:00
# include "lldb/Core/ModuleSpec.h"
Added a new option to the "source list" command that allows us to see where
line tables specify breakpoints can be set in the source. When dumping the
source, the number of breakpoints that can be set on a source line are shown
as a prefix:
(lldb) source list -f test.c -l1 -c222 -b
1 #include <stdio.h>
2 #include <sys/fcntl.h>
3 #include <unistd.h>
4 int
5 sleep_loop (const int num_secs)
[2] 6 {
7 int i;
[1] 8 for (i=0; i<num_secs; ++i)
9 {
[1] 10 printf("%d of %i - sleep(1);\n", i, num_secs);
[1] 11 sleep(1);
12 }
13 return 0;
[1] 14 }
15
16 int
17 main (int argc, char const* argv[])
[1] 18 {
[1] 19 printf("Process: %i\n\n", getpid());
[1] 20 puts("Press any key to continue..."); getchar();
[1] 21 sleep_loop (20);
22 return 12;
[1] 23 }
Above we can see there are two breakpoints for line 6 and one breakpoint for
lines 8, 10, 11, 14, 18, 19, 20, 21 and 23. All other lines have no line table
entries for them. This helps visualize the data provided in the debug
information without having to manually dump all line tables. It also includes
all inline breakpoint that may result for a given file which can also be very
handy to see.
llvm-svn: 129747
2011-04-19 12:19:37 +08:00
# include "lldb/Core/SourceManager.h"
2010-06-09 00:52:24 +08:00
# include "lldb/Interpreter/CommandInterpreter.h"
# include "lldb/Interpreter/CommandReturnObject.h"
2011-02-08 13:05:52 +08:00
# include "lldb/Host/FileSpec.h"
<rdar://problem/11757916>
Make breakpoint setting by file and line much more efficient by only looking for inlined breakpoint locations if we are setting a breakpoint in anything but a source implementation file. Implementing this complex for a many reasons. Turns out that parsing compile units lazily had some issues with respect to how we need to do things with DWARF in .o files. So the fixes in the checkin for this makes these changes:
- Add a new setting called "target.inline-breakpoint-strategy" which can be set to "never", "always", or "headers". "never" will never try and set any inlined breakpoints (fastest). "always" always looks for inlined breakpoint locations (slowest, but most accurate). "headers", which is the default setting, will only look for inlined breakpoint locations if the breakpoint is set in what are consudered to be header files, which is realy defined as "not in an implementation source file".
- modify the breakpoint setting by file and line to check the current "target.inline-breakpoint-strategy" setting and act accordingly
- Modify compile units to be able to get their language and other info lazily. This allows us to create compile units from the debug map and not have to fill all of the details in, and then lazily discover this information as we go on debuggging. This is needed to avoid parsing all .o files when setting breakpoints in implementation only files (no inlines). Otherwise we would need to parse the .o file, the object file (mach-o in our case) and the symbol file (DWARF in the object file) just to see what the compile unit was.
- modify the "SymbolFileDWARFDebugMap" to subclass lldb_private::Module so that the virtual "GetObjectFile()" and "GetSymbolVendor()" functions can be intercepted when the .o file contenst are later lazilly needed. Prior to this fix, when we first instantiated the "SymbolFileDWARFDebugMap" class, we would also make modules, object files and symbol files for every .o file in the debug map because we needed to fix up the sections in the .o files with information that is in the executable debug map. Now we lazily do this in the DebugMapModule::GetObjectFile()
Cleaned up header includes a bit as well.
llvm-svn: 162860
2012-08-30 05:13:06 +08:00
# include "lldb/Symbol/CompileUnit.h"
# include "lldb/Symbol/Function.h"
2010-06-09 00:52:24 +08:00
# include "lldb/Target/Process.h"
# include "lldb/Target/TargetList.h"
2010-07-07 11:36:20 +08:00
# include "lldb/Interpreter/CommandCompletions.h"
# include "lldb/Interpreter/Options.h"
2010-06-09 00:52:24 +08:00
using namespace lldb ;
using namespace lldb_private ;
//-------------------------------------------------------------------------
Added a new option to the "source list" command that allows us to see where
line tables specify breakpoints can be set in the source. When dumping the
source, the number of breakpoints that can be set on a source line are shown
as a prefix:
(lldb) source list -f test.c -l1 -c222 -b
1 #include <stdio.h>
2 #include <sys/fcntl.h>
3 #include <unistd.h>
4 int
5 sleep_loop (const int num_secs)
[2] 6 {
7 int i;
[1] 8 for (i=0; i<num_secs; ++i)
9 {
[1] 10 printf("%d of %i - sleep(1);\n", i, num_secs);
[1] 11 sleep(1);
12 }
13 return 0;
[1] 14 }
15
16 int
17 main (int argc, char const* argv[])
[1] 18 {
[1] 19 printf("Process: %i\n\n", getpid());
[1] 20 puts("Press any key to continue..."); getchar();
[1] 21 sleep_loop (20);
22 return 12;
[1] 23 }
Above we can see there are two breakpoints for line 6 and one breakpoint for
lines 8, 10, 11, 14, 18, 19, 20, 21 and 23. All other lines have no line table
entries for them. This helps visualize the data provided in the debug
information without having to manually dump all line tables. It also includes
all inline breakpoint that may result for a given file which can also be very
handy to see.
llvm-svn: 129747
2011-04-19 12:19:37 +08:00
// CommandObjectSourceInfo
2010-06-09 00:52:24 +08:00
//-------------------------------------------------------------------------
2012-06-09 05:56:10 +08:00
class CommandObjectSourceInfo : public CommandObjectParsed
2010-06-09 00:52:24 +08:00
{
2010-07-07 11:36:20 +08:00
class CommandOptions : public Options
{
public :
2011-04-08 06:46:35 +08:00
CommandOptions ( CommandInterpreter & interpreter ) :
Options ( interpreter )
2010-07-07 11:36:20 +08:00
{
}
~ CommandOptions ( )
{
}
Error
2011-04-13 08:18:08 +08:00
SetOptionValue ( uint32_t option_idx , const char * option_arg )
2010-07-07 11:36:20 +08:00
{
Error error ;
2012-12-04 08:32:51 +08:00
const int short_option = g_option_table [ option_idx ] . short_option ;
2010-07-07 11:36:20 +08:00
switch ( short_option )
{
case ' l ' :
start_line = Args : : StringToUInt32 ( option_arg , 0 ) ;
if ( start_line = = 0 )
2011-10-26 08:56:27 +08:00
error . SetErrorStringWithFormat ( " invalid line number: '%s' " , option_arg ) ;
2010-07-07 11:36:20 +08:00
break ;
case ' f ' :
file_name = option_arg ;
break ;
default :
2011-10-26 08:56:27 +08:00
error . SetErrorStringWithFormat ( " unrecognized short option '%c' " , short_option ) ;
2010-07-07 11:36:20 +08:00
break ;
}
return error ;
}
void
2011-04-13 08:18:08 +08:00
OptionParsingStarting ( )
2010-07-07 11:36:20 +08:00
{
file_spec . Clear ( ) ;
file_name . clear ( ) ;
start_line = 0 ;
}
2011-03-25 05:19:54 +08:00
const OptionDefinition *
2010-07-07 11:36:20 +08:00
GetDefinitions ( )
{
return g_option_table ;
}
2011-03-25 05:19:54 +08:00
static OptionDefinition g_option_table [ ] ;
2010-07-07 11:36:20 +08:00
// Instance variables to hold the values for command options.
FileSpec file_spec ;
std : : string file_name ;
uint32_t start_line ;
} ;
public :
2010-09-18 09:14:36 +08:00
CommandObjectSourceInfo ( CommandInterpreter & interpreter ) :
2012-06-09 05:56:10 +08:00
CommandObjectParsed ( interpreter ,
" source info " ,
" Display information about the source lines from the current executable's debug info. " ,
" source info [<cmd-options>] " ) ,
2011-04-08 06:46:35 +08:00
m_options ( interpreter )
2010-07-07 11:36:20 +08:00
{
}
~ CommandObjectSourceInfo ( )
{
}
Options *
GetOptions ( )
{
return & m_options ;
}
2012-06-09 05:56:10 +08:00
protected :
2010-07-07 11:36:20 +08:00
bool
2012-06-09 05:56:10 +08:00
DoExecute ( Args & command , CommandReturnObject & result )
2010-07-07 11:36:20 +08:00
{
result . AppendError ( " Not yet implemented " ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2012-06-09 05:56:10 +08:00
2010-07-07 11:36:20 +08:00
CommandOptions m_options ;
} ;
2011-03-25 05:19:54 +08:00
OptionDefinition
2010-07-07 11:36:20 +08:00
CommandObjectSourceInfo : : CommandOptions : : g_option_table [ ] =
2010-06-09 00:52:24 +08:00
{
2010-10-02 03:59:14 +08:00
{ LLDB_OPT_SET_1 , false , " line " , ' l ' , required_argument , NULL , 0 , eArgTypeLineNum , " The line number at which to start the display source. " } ,
{ LLDB_OPT_SET_1 , false , " file " , ' f ' , required_argument , NULL , CommandCompletions : : eSourceFileCompletion , eArgTypeFilename , " The file from which to display source. " } ,
{ 0 , false , NULL , 0 , 0 , NULL , 0 , eArgTypeNone , NULL }
2010-07-07 11:36:20 +08:00
} ;
# pragma mark CommandObjectSourceList
//-------------------------------------------------------------------------
// CommandObjectSourceList
//-------------------------------------------------------------------------
2010-06-09 00:52:24 +08:00
2012-06-09 05:56:10 +08:00
class CommandObjectSourceList : public CommandObjectParsed
2010-06-09 00:52:24 +08:00
{
2010-07-07 11:36:20 +08:00
class CommandOptions : public Options
2010-06-09 00:52:24 +08:00
{
2010-07-07 11:36:20 +08:00
public :
2011-04-08 06:46:35 +08:00
CommandOptions ( CommandInterpreter & interpreter ) :
Options ( interpreter )
2010-07-07 11:36:20 +08:00
{
}
2010-06-09 00:52:24 +08:00
2010-07-07 11:36:20 +08:00
~ CommandOptions ( )
{
}
2010-06-09 00:52:24 +08:00
2010-07-07 11:36:20 +08:00
Error
2011-04-13 08:18:08 +08:00
SetOptionValue ( uint32_t option_idx , const char * option_arg )
2010-06-09 00:52:24 +08:00
{
2010-07-07 11:36:20 +08:00
Error error ;
2012-12-04 08:32:51 +08:00
const int short_option = g_option_table [ option_idx ] . short_option ;
2010-07-07 11:36:20 +08:00
switch ( short_option )
{
case ' l ' :
start_line = Args : : StringToUInt32 ( option_arg , 0 ) ;
if ( start_line = = 0 )
2011-10-26 08:56:27 +08:00
error . SetErrorStringWithFormat ( " invalid line number: '%s' " , option_arg ) ;
2010-07-07 11:36:20 +08:00
break ;
2010-06-09 00:52:24 +08:00
2010-08-20 09:17:07 +08:00
case ' c ' :
2010-07-07 11:36:20 +08:00
num_lines = Args : : StringToUInt32 ( option_arg , 0 ) ;
if ( num_lines = = 0 )
2011-10-26 08:56:27 +08:00
error . SetErrorStringWithFormat ( " invalid line count: '%s' " , option_arg ) ;
2010-07-07 11:36:20 +08:00
break ;
2010-06-09 00:52:24 +08:00
Added a new option to the "source list" command that allows us to see where
line tables specify breakpoints can be set in the source. When dumping the
source, the number of breakpoints that can be set on a source line are shown
as a prefix:
(lldb) source list -f test.c -l1 -c222 -b
1 #include <stdio.h>
2 #include <sys/fcntl.h>
3 #include <unistd.h>
4 int
5 sleep_loop (const int num_secs)
[2] 6 {
7 int i;
[1] 8 for (i=0; i<num_secs; ++i)
9 {
[1] 10 printf("%d of %i - sleep(1);\n", i, num_secs);
[1] 11 sleep(1);
12 }
13 return 0;
[1] 14 }
15
16 int
17 main (int argc, char const* argv[])
[1] 18 {
[1] 19 printf("Process: %i\n\n", getpid());
[1] 20 puts("Press any key to continue..."); getchar();
[1] 21 sleep_loop (20);
22 return 12;
[1] 23 }
Above we can see there are two breakpoints for line 6 and one breakpoint for
lines 8, 10, 11, 14, 18, 19, 20, 21 and 23. All other lines have no line table
entries for them. This helps visualize the data provided in the debug
information without having to manually dump all line tables. It also includes
all inline breakpoint that may result for a given file which can also be very
handy to see.
llvm-svn: 129747
2011-04-19 12:19:37 +08:00
case ' f ' :
2010-07-07 11:36:20 +08:00
file_name = option_arg ;
break ;
2010-08-20 09:17:07 +08:00
case ' n ' :
symbol_name = option_arg ;
break ;
2010-07-07 11:36:20 +08:00
2012-12-07 08:19:47 +08:00
case ' a ' :
{
ExecutionContext exe_ctx ( m_interpreter . GetExecutionContext ( ) ) ;
address = Args : : StringToAddress ( & exe_ctx , option_arg , LLDB_INVALID_ADDRESS , & error ) ;
}
break ;
2010-08-20 09:17:07 +08:00
case ' s ' :
Added a new option to the "source list" command that allows us to see where
line tables specify breakpoints can be set in the source. When dumping the
source, the number of breakpoints that can be set on a source line are shown
as a prefix:
(lldb) source list -f test.c -l1 -c222 -b
1 #include <stdio.h>
2 #include <sys/fcntl.h>
3 #include <unistd.h>
4 int
5 sleep_loop (const int num_secs)
[2] 6 {
7 int i;
[1] 8 for (i=0; i<num_secs; ++i)
9 {
[1] 10 printf("%d of %i - sleep(1);\n", i, num_secs);
[1] 11 sleep(1);
12 }
13 return 0;
[1] 14 }
15
16 int
17 main (int argc, char const* argv[])
[1] 18 {
[1] 19 printf("Process: %i\n\n", getpid());
[1] 20 puts("Press any key to continue..."); getchar();
[1] 21 sleep_loop (20);
22 return 12;
[1] 23 }
Above we can see there are two breakpoints for line 6 and one breakpoint for
lines 8, 10, 11, 14, 18, 19, 20, 21 and 23. All other lines have no line table
entries for them. This helps visualize the data provided in the debug
information without having to manually dump all line tables. It also includes
all inline breakpoint that may result for a given file which can also be very
handy to see.
llvm-svn: 129747
2011-04-19 12:19:37 +08:00
modules . push_back ( std : : string ( option_arg ) ) ;
break ;
case ' b ' :
show_bp_locs = true ;
2010-08-20 09:17:07 +08:00
break ;
2013-01-09 11:27:33 +08:00
case ' r ' :
reverse = true ;
break ;
2010-07-07 11:36:20 +08:00
default :
2011-10-26 08:56:27 +08:00
error . SetErrorStringWithFormat ( " unrecognized short option '%c' " , short_option ) ;
2010-07-07 11:36:20 +08:00
break ;
2010-06-09 00:52:24 +08:00
}
2010-07-07 11:36:20 +08:00
return error ;
}
2010-06-09 00:52:24 +08:00
2010-07-07 11:36:20 +08:00
void
2011-04-13 08:18:08 +08:00
OptionParsingStarting ( )
2010-07-07 11:36:20 +08:00
{
file_spec . Clear ( ) ;
file_name . clear ( ) ;
2010-08-20 09:17:07 +08:00
symbol_name . clear ( ) ;
2012-12-07 08:19:47 +08:00
address = LLDB_INVALID_ADDRESS ;
2010-07-07 11:36:20 +08:00
start_line = 0 ;
2013-03-14 02:25:49 +08:00
num_lines = 0 ;
Added a new option to the "source list" command that allows us to see where
line tables specify breakpoints can be set in the source. When dumping the
source, the number of breakpoints that can be set on a source line are shown
as a prefix:
(lldb) source list -f test.c -l1 -c222 -b
1 #include <stdio.h>
2 #include <sys/fcntl.h>
3 #include <unistd.h>
4 int
5 sleep_loop (const int num_secs)
[2] 6 {
7 int i;
[1] 8 for (i=0; i<num_secs; ++i)
9 {
[1] 10 printf("%d of %i - sleep(1);\n", i, num_secs);
[1] 11 sleep(1);
12 }
13 return 0;
[1] 14 }
15
16 int
17 main (int argc, char const* argv[])
[1] 18 {
[1] 19 printf("Process: %i\n\n", getpid());
[1] 20 puts("Press any key to continue..."); getchar();
[1] 21 sleep_loop (20);
22 return 12;
[1] 23 }
Above we can see there are two breakpoints for line 6 and one breakpoint for
lines 8, 10, 11, 14, 18, 19, 20, 21 and 23. All other lines have no line table
entries for them. This helps visualize the data provided in the debug
information without having to manually dump all line tables. It also includes
all inline breakpoint that may result for a given file which can also be very
handy to see.
llvm-svn: 129747
2011-04-19 12:19:37 +08:00
show_bp_locs = false ;
2013-01-09 11:27:33 +08:00
reverse = false ;
Added a new option to the "source list" command that allows us to see where
line tables specify breakpoints can be set in the source. When dumping the
source, the number of breakpoints that can be set on a source line are shown
as a prefix:
(lldb) source list -f test.c -l1 -c222 -b
1 #include <stdio.h>
2 #include <sys/fcntl.h>
3 #include <unistd.h>
4 int
5 sleep_loop (const int num_secs)
[2] 6 {
7 int i;
[1] 8 for (i=0; i<num_secs; ++i)
9 {
[1] 10 printf("%d of %i - sleep(1);\n", i, num_secs);
[1] 11 sleep(1);
12 }
13 return 0;
[1] 14 }
15
16 int
17 main (int argc, char const* argv[])
[1] 18 {
[1] 19 printf("Process: %i\n\n", getpid());
[1] 20 puts("Press any key to continue..."); getchar();
[1] 21 sleep_loop (20);
22 return 12;
[1] 23 }
Above we can see there are two breakpoints for line 6 and one breakpoint for
lines 8, 10, 11, 14, 18, 19, 20, 21 and 23. All other lines have no line table
entries for them. This helps visualize the data provided in the debug
information without having to manually dump all line tables. It also includes
all inline breakpoint that may result for a given file which can also be very
handy to see.
llvm-svn: 129747
2011-04-19 12:19:37 +08:00
modules . clear ( ) ;
2010-07-07 11:36:20 +08:00
}
2011-03-25 05:19:54 +08:00
const OptionDefinition *
2010-07-07 11:36:20 +08:00
GetDefinitions ( )
{
return g_option_table ;
}
2011-03-25 05:19:54 +08:00
static OptionDefinition g_option_table [ ] ;
2010-07-07 11:36:20 +08:00
// Instance variables to hold the values for command options.
FileSpec file_spec ;
std : : string file_name ;
2010-08-20 09:17:07 +08:00
std : : string symbol_name ;
2012-12-07 08:19:47 +08:00
lldb : : addr_t address ;
2010-07-07 11:36:20 +08:00
uint32_t start_line ;
uint32_t num_lines ;
Added a new option to the "source list" command that allows us to see where
line tables specify breakpoints can be set in the source. When dumping the
source, the number of breakpoints that can be set on a source line are shown
as a prefix:
(lldb) source list -f test.c -l1 -c222 -b
1 #include <stdio.h>
2 #include <sys/fcntl.h>
3 #include <unistd.h>
4 int
5 sleep_loop (const int num_secs)
[2] 6 {
7 int i;
[1] 8 for (i=0; i<num_secs; ++i)
9 {
[1] 10 printf("%d of %i - sleep(1);\n", i, num_secs);
[1] 11 sleep(1);
12 }
13 return 0;
[1] 14 }
15
16 int
17 main (int argc, char const* argv[])
[1] 18 {
[1] 19 printf("Process: %i\n\n", getpid());
[1] 20 puts("Press any key to continue..."); getchar();
[1] 21 sleep_loop (20);
22 return 12;
[1] 23 }
Above we can see there are two breakpoints for line 6 and one breakpoint for
lines 8, 10, 11, 14, 18, 19, 20, 21 and 23. All other lines have no line table
entries for them. This helps visualize the data provided in the debug
information without having to manually dump all line tables. It also includes
all inline breakpoint that may result for a given file which can also be very
handy to see.
llvm-svn: 129747
2011-04-19 12:19:37 +08:00
STLStringArray modules ;
bool show_bp_locs ;
2013-01-09 11:27:33 +08:00
bool reverse ;
2010-07-07 11:36:20 +08:00
} ;
public :
2010-09-18 09:14:36 +08:00
CommandObjectSourceList ( CommandInterpreter & interpreter ) :
2012-06-09 05:56:10 +08:00
CommandObjectParsed ( interpreter ,
" source list " ,
" Display source code (as specified) based on the current executable's debug info. " ,
Expanded the flags that can be set for a command object in lldb_private::CommandObject. This list of available flags are:
enum
{
//----------------------------------------------------------------------
// eFlagRequiresTarget
//
// Ensures a valid target is contained in m_exe_ctx prior to executing
// the command. If a target doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidTargetDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidTargetDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresTarget = (1u << 0),
//----------------------------------------------------------------------
// eFlagRequiresProcess
//
// Ensures a valid process is contained in m_exe_ctx prior to executing
// the command. If a process doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidProcessDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidProcessDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresProcess = (1u << 1),
//----------------------------------------------------------------------
// eFlagRequiresThread
//
// Ensures a valid thread is contained in m_exe_ctx prior to executing
// the command. If a thread doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidThreadDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidThreadDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresThread = (1u << 2),
//----------------------------------------------------------------------
// eFlagRequiresFrame
//
// Ensures a valid frame is contained in m_exe_ctx prior to executing
// the command. If a frame doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidFrameDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidFrameDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresFrame = (1u << 3),
//----------------------------------------------------------------------
// eFlagRequiresRegContext
//
// Ensures a valid register context (from the selected frame if there
// is a frame in m_exe_ctx, or from the selected thread from m_exe_ctx)
// is availble from m_exe_ctx prior to executing the command. If a
// target doesn't exist or is invalid, the command will fail and
// CommandObject::GetInvalidRegContextDescription() will be returned as
// the error. CommandObject subclasses can override the virtual function
// for GetInvalidRegContextDescription() to provide custom strings when
// needed.
//----------------------------------------------------------------------
eFlagRequiresRegContext = (1u << 4),
//----------------------------------------------------------------------
// eFlagTryTargetAPILock
//
// Attempts to acquire the target lock if a target is selected in the
// command interpreter. If the command object fails to acquire the API
// lock, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagTryTargetAPILock = (1u << 5),
//----------------------------------------------------------------------
// eFlagProcessMustBeLaunched
//
// Verifies that there is a launched process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBeLaunched = (1u << 6),
//----------------------------------------------------------------------
// eFlagProcessMustBePaused
//
// Verifies that there is a paused process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBePaused = (1u << 7)
};
Now each command object contains a "ExecutionContext m_exe_ctx;" member variable that gets initialized prior to running the command. The validity of the target objects in m_exe_ctx are checked to ensure that any target/process/thread/frame/reg context that are required are valid prior to executing the command. Each command object also contains a Mutex::Locker m_api_locker which gets used if eFlagTryTargetAPILock is set. This centralizes a lot of checking code that was previously and inconsistently implemented across many commands.
llvm-svn: 171990
2013-01-10 03:44:40 +08:00
NULL ,
eFlagRequiresTarget ) ,
2011-04-08 06:46:35 +08:00
m_options ( interpreter )
2010-07-07 11:36:20 +08:00
{
}
~ CommandObjectSourceList ( )
{
}
Options *
GetOptions ( )
{
return & m_options ;
}
2012-06-09 05:56:10 +08:00
virtual const char *
GetRepeatCommand ( Args & current_command_args , uint32_t index )
{
2013-01-09 11:27:33 +08:00
// This is kind of gross, but the command hasn't been parsed yet so we can't look at the option
// values for this invocation... I have to scan the arguments directly.
size_t num_args = current_command_args . GetArgumentCount ( ) ;
bool is_reverse = false ;
for ( size_t i = 0 ; i < num_args ; i + + )
{
const char * arg = current_command_args . GetArgumentAtIndex ( i ) ;
if ( arg & & ( strcmp ( arg , " -r " ) = = 0 | | strcmp ( arg , " --reverse " ) = = 0 ) )
{
is_reverse = true ;
}
}
if ( is_reverse )
{
if ( m_reverse_name . empty ( ) )
{
m_reverse_name = m_cmd_name ;
m_reverse_name . append ( " -r " ) ;
}
return m_reverse_name . c_str ( ) ;
}
else
return m_cmd_name . c_str ( ) ;
2012-06-09 05:56:10 +08:00
}
2010-07-07 11:36:20 +08:00
2012-06-09 05:56:10 +08:00
protected :
2013-05-17 08:56:10 +08:00
struct SourceInfo
{
ConstString function ;
LineEntry line_entry ;
SourceInfo ( const ConstString & name , const LineEntry & line_entry ) :
function ( name ) ,
line_entry ( line_entry )
{
}
SourceInfo ( ) :
function ( ) ,
line_entry ( )
{
}
bool
IsValid ( ) const
{
return ( bool ) function & & line_entry . IsValid ( ) ;
}
bool
operator = = ( const SourceInfo & rhs ) const
{
return function = = rhs . function & &
line_entry . file = = rhs . line_entry . file & &
line_entry . line = = rhs . line_entry . line ;
}
bool
operator ! = ( const SourceInfo & rhs ) const
{
return function ! = rhs . function | |
line_entry . file ! = rhs . line_entry . file | |
line_entry . line ! = rhs . line_entry . line ;
}
bool
operator < ( const SourceInfo & rhs ) const
{
if ( function . GetCString ( ) < rhs . function . GetCString ( ) )
return true ;
if ( line_entry . file . GetDirectory ( ) . GetCString ( ) < rhs . line_entry . file . GetDirectory ( ) . GetCString ( ) )
return true ;
if ( line_entry . file . GetFilename ( ) . GetCString ( ) < rhs . line_entry . file . GetFilename ( ) . GetCString ( ) )
return true ;
if ( line_entry . line < rhs . line_entry . line )
return true ;
return false ;
}
} ;
size_t
DisplayFunctionSource ( const SymbolContext & sc ,
SourceInfo & source_info ,
CommandReturnObject & result )
{
if ( ! source_info . IsValid ( ) )
{
source_info . function = sc . GetFunctionName ( ) ;
source_info . line_entry = sc . GetFunctionStartLineEntry ( ) ;
}
if ( sc . function )
{
Target * target = m_exe_ctx . GetTargetPtr ( ) ;
FileSpec start_file ;
uint32_t start_line ;
uint32_t end_line ;
FileSpec end_file ;
if ( sc . block = = NULL )
{
// Not an inlined function
sc . function - > GetStartLineSourceInfo ( start_file , start_line ) ;
if ( start_line = = 0 )
{
result . AppendErrorWithFormat ( " Could not find line information for start of function: \" %s \" . \n " , source_info . function . GetCString ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return 0 ;
}
sc . function - > GetEndLineSourceInfo ( end_file , end_line ) ;
}
else
{
// We have an inlined function
start_file = source_info . line_entry . file ;
start_line = source_info . line_entry . line ;
end_line = start_line + m_options . num_lines ;
}
// This is a little hacky, but the first line table entry for a function points to the "{" that
// starts the function block. It would be nice to actually get the function
// declaration in there too. So back up a bit, but not further than what you're going to display.
uint32_t extra_lines ;
if ( m_options . num_lines > = 10 )
extra_lines = 5 ;
else
extra_lines = m_options . num_lines / 2 ;
uint32_t line_no ;
if ( start_line < = extra_lines )
line_no = 1 ;
else
line_no = start_line - extra_lines ;
// For fun, if the function is shorter than the number of lines we're supposed to display,
// only display the function...
if ( end_line ! = 0 )
{
if ( m_options . num_lines > end_line - line_no )
m_options . num_lines = end_line - line_no + extra_lines ;
}
m_breakpoint_locations . Clear ( ) ;
if ( m_options . show_bp_locs )
{
const bool show_inlines = true ;
m_breakpoint_locations . Reset ( start_file , 0 , show_inlines ) ;
SearchFilter target_search_filter ( m_exe_ctx . GetTargetSP ( ) ) ;
target_search_filter . Search ( m_breakpoint_locations ) ;
}
result . AppendMessageWithFormat ( " File: %s \n " , start_file . GetPath ( ) . c_str ( ) ) ;
return target - > GetSourceManager ( ) . DisplaySourceLinesWithLineNumbers ( start_file ,
line_no ,
0 ,
m_options . num_lines ,
" " ,
& result . GetOutputStream ( ) ,
GetBreakpointLocations ( ) ) ;
}
else
{
result . AppendErrorWithFormat ( " Could not find function info for: \" %s \" . \n " , m_options . symbol_name . c_str ( ) ) ;
}
return 0 ;
}
2010-07-07 11:36:20 +08:00
bool
2012-06-09 05:56:10 +08:00
DoExecute ( Args & command , CommandReturnObject & result )
2010-07-07 11:36:20 +08:00
{
2013-01-26 02:06:21 +08:00
const size_t argc = command . GetArgumentCount ( ) ;
2010-07-07 11:36:20 +08:00
if ( argc ! = 0 )
{
result . AppendErrorWithFormat ( " '%s' takes no arguments, only flags. \n " , GetCommandName ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
2011-11-30 05:21:26 +08:00
return false ;
2010-07-07 11:36:20 +08:00
}
Expanded the flags that can be set for a command object in lldb_private::CommandObject. This list of available flags are:
enum
{
//----------------------------------------------------------------------
// eFlagRequiresTarget
//
// Ensures a valid target is contained in m_exe_ctx prior to executing
// the command. If a target doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidTargetDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidTargetDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresTarget = (1u << 0),
//----------------------------------------------------------------------
// eFlagRequiresProcess
//
// Ensures a valid process is contained in m_exe_ctx prior to executing
// the command. If a process doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidProcessDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidProcessDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresProcess = (1u << 1),
//----------------------------------------------------------------------
// eFlagRequiresThread
//
// Ensures a valid thread is contained in m_exe_ctx prior to executing
// the command. If a thread doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidThreadDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidThreadDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresThread = (1u << 2),
//----------------------------------------------------------------------
// eFlagRequiresFrame
//
// Ensures a valid frame is contained in m_exe_ctx prior to executing
// the command. If a frame doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidFrameDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidFrameDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresFrame = (1u << 3),
//----------------------------------------------------------------------
// eFlagRequiresRegContext
//
// Ensures a valid register context (from the selected frame if there
// is a frame in m_exe_ctx, or from the selected thread from m_exe_ctx)
// is availble from m_exe_ctx prior to executing the command. If a
// target doesn't exist or is invalid, the command will fail and
// CommandObject::GetInvalidRegContextDescription() will be returned as
// the error. CommandObject subclasses can override the virtual function
// for GetInvalidRegContextDescription() to provide custom strings when
// needed.
//----------------------------------------------------------------------
eFlagRequiresRegContext = (1u << 4),
//----------------------------------------------------------------------
// eFlagTryTargetAPILock
//
// Attempts to acquire the target lock if a target is selected in the
// command interpreter. If the command object fails to acquire the API
// lock, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagTryTargetAPILock = (1u << 5),
//----------------------------------------------------------------------
// eFlagProcessMustBeLaunched
//
// Verifies that there is a launched process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBeLaunched = (1u << 6),
//----------------------------------------------------------------------
// eFlagProcessMustBePaused
//
// Verifies that there is a paused process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBePaused = (1u << 7)
};
Now each command object contains a "ExecutionContext m_exe_ctx;" member variable that gets initialized prior to running the command. The validity of the target objects in m_exe_ctx are checked to ensure that any target/process/thread/frame/reg context that are required are valid prior to executing the command. Each command object also contains a Mutex::Locker m_api_locker which gets used if eFlagTryTargetAPILock is set. This centralizes a lot of checking code that was previously and inconsistently implemented across many commands.
llvm-svn: 171990
2013-01-10 03:44:40 +08:00
Target * target = m_exe_ctx . GetTargetPtr ( ) ;
2011-09-09 06:13:49 +08:00
2012-12-07 08:19:47 +08:00
SymbolContextList sc_list ;
2010-08-20 09:17:07 +08:00
if ( ! m_options . symbol_name . empty ( ) )
{
// Displaying the source for a symbol:
ConstString name ( m_options . symbol_name . c_str ( ) ) ;
2011-01-27 14:44:37 +08:00
bool include_symbols = false ;
2012-02-11 06:52:19 +08:00
bool include_inlines = true ;
2010-08-20 09:17:07 +08:00
bool append = true ;
size_t num_matches = 0 ;
2013-03-14 02:25:49 +08:00
if ( m_options . num_lines = = 0 )
m_options . num_lines = 10 ;
2013-01-26 02:06:21 +08:00
const size_t num_modules = m_options . modules . size ( ) ;
if ( num_modules > 0 )
2010-08-20 09:17:07 +08:00
{
ModuleList matching_modules ;
2013-01-26 02:06:21 +08:00
for ( size_t i = 0 ; i < num_modules ; + + i )
2010-08-20 09:17:07 +08:00
{
2012-02-26 13:51:37 +08:00
FileSpec module_file_spec ( m_options . modules [ i ] . c_str ( ) , false ) ;
if ( module_file_spec )
2010-08-20 09:17:07 +08:00
{
2012-02-26 13:51:37 +08:00
ModuleSpec module_spec ( module_file_spec ) ;
2010-08-20 09:17:07 +08:00
matching_modules . Clear ( ) ;
2012-02-26 13:51:37 +08:00
target - > GetImages ( ) . FindModules ( module_spec , matching_modules ) ;
2012-02-11 06:52:19 +08:00
num_matches + = matching_modules . FindFunctions ( name , eFunctionNameTypeAuto , include_symbols , include_inlines , append , sc_list ) ;
2010-08-20 09:17:07 +08:00
}
}
}
else
{
2012-02-11 06:52:19 +08:00
num_matches = target - > GetImages ( ) . FindFunctions ( name , eFunctionNameTypeAuto , include_symbols , include_inlines , append , sc_list ) ;
2010-08-20 09:17:07 +08:00
}
SymbolContext sc ;
if ( num_matches = = 0 )
{
result . AppendErrorWithFormat ( " Could not find function named: \" %s \" . \n " , m_options . symbol_name . c_str ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
if ( num_matches > 1 )
{
2013-05-17 08:56:10 +08:00
std : : set < SourceInfo > source_match_set ;
2010-08-20 09:17:07 +08:00
2013-05-17 08:56:10 +08:00
bool displayed_something = false ;
for ( size_t i = 0 ; i < num_matches ; i + + )
2010-08-20 09:17:07 +08:00
{
2013-05-17 08:56:10 +08:00
sc_list . GetContextAtIndex ( i , sc ) ;
SourceInfo source_info ( sc . GetFunctionName ( ) ,
sc . GetFunctionStartLineEntry ( ) ) ;
if ( source_info . IsValid ( ) )
2010-08-20 09:17:07 +08:00
{
2013-05-17 08:56:10 +08:00
if ( source_match_set . find ( source_info ) = = source_match_set . end ( ) )
2010-08-20 09:17:07 +08:00
{
2013-05-17 08:56:10 +08:00
source_match_set . insert ( source_info ) ;
if ( DisplayFunctionSource ( sc , source_info , result ) )
displayed_something = true ;
2010-08-20 09:17:07 +08:00
}
}
}
2013-05-17 08:56:10 +08:00
if ( displayed_something )
result . SetStatus ( eReturnStatusSuccessFinishResult ) ;
else
2010-08-20 09:17:07 +08:00
result . SetStatus ( eReturnStatusFailed ) ;
}
else
{
2013-05-17 08:56:10 +08:00
sc_list . GetContextAtIndex ( 0 , sc ) ;
SourceInfo source_info ;
if ( DisplayFunctionSource ( sc , source_info , result ) )
{
result . SetStatus ( eReturnStatusSuccessFinishResult ) ;
}
else
{
result . SetStatus ( eReturnStatusFailed ) ;
}
2011-04-21 02:52:45 +08:00
}
2013-05-17 08:56:10 +08:00
return result . Succeeded ( ) ;
2010-08-20 09:17:07 +08:00
}
2012-12-07 08:19:47 +08:00
else if ( m_options . address ! = LLDB_INVALID_ADDRESS )
{
SymbolContext sc ;
Address so_addr ;
StreamString error_strm ;
if ( target - > GetSectionLoadList ( ) . IsEmpty ( ) )
{
// The target isn't loaded yet, we need to lookup the file address
// in all modules
const ModuleList & module_list = target - > GetImages ( ) ;
2013-01-26 02:06:21 +08:00
const size_t num_modules = module_list . GetSize ( ) ;
for ( size_t i = 0 ; i < num_modules ; + + i )
2012-12-07 08:19:47 +08:00
{
ModuleSP module_sp ( module_list . GetModuleAtIndex ( i ) ) ;
if ( module_sp & & module_sp - > ResolveFileAddress ( m_options . address , so_addr ) )
{
2013-02-23 12:12:47 +08:00
sc . Clear ( true ) ;
2012-12-07 08:19:47 +08:00
if ( module_sp - > ResolveSymbolContextForAddress ( so_addr , eSymbolContextEverything , sc ) & eSymbolContextLineEntry )
sc_list . Append ( sc ) ;
}
}
if ( sc_list . GetSize ( ) = = 0 )
{
result . AppendErrorWithFormat ( " no modules have source information for file address 0x% " PRIx64 " . \n " ,
m_options . address ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
}
else
{
// The target has some things loaded, resolve this address to a
// compile unit + file + line and display
if ( target - > GetSectionLoadList ( ) . ResolveLoadAddress ( m_options . address , so_addr ) )
{
ModuleSP module_sp ( so_addr . GetModule ( ) ) ;
if ( module_sp )
{
2013-02-23 12:12:47 +08:00
sc . Clear ( true ) ;
2012-12-07 08:19:47 +08:00
if ( module_sp - > ResolveSymbolContextForAddress ( so_addr , eSymbolContextEverything , sc ) & eSymbolContextLineEntry )
{
sc_list . Append ( sc ) ;
}
else
{
so_addr . Dump ( & error_strm , NULL , Address : : DumpStyleModuleWithFileAddress ) ;
result . AppendErrorWithFormat ( " address resolves to %s, but there is no line table information available for this address. \n " ,
error_strm . GetData ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
}
}
if ( sc_list . GetSize ( ) = = 0 )
{
result . AppendErrorWithFormat ( " no modules contain load address 0x% " PRIx64 " . \n " , m_options . address ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
}
uint32_t num_matches = sc_list . GetSize ( ) ;
for ( uint32_t i = 0 ; i < num_matches ; + + i )
{
sc_list . GetContextAtIndex ( i , sc ) ;
if ( sc . comp_unit )
{
if ( m_options . show_bp_locs )
{
m_breakpoint_locations . Clear ( ) ;
const bool show_inlines = true ;
m_breakpoint_locations . Reset ( * sc . comp_unit , 0 , show_inlines ) ;
SearchFilter target_search_filter ( target - > shared_from_this ( ) ) ;
target_search_filter . Search ( m_breakpoint_locations ) ;
}
bool show_fullpaths = true ;
bool show_module = true ;
bool show_inlined_frames = true ;
sc . DumpStopContext ( & result . GetOutputStream ( ) ,
Expanded the flags that can be set for a command object in lldb_private::CommandObject. This list of available flags are:
enum
{
//----------------------------------------------------------------------
// eFlagRequiresTarget
//
// Ensures a valid target is contained in m_exe_ctx prior to executing
// the command. If a target doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidTargetDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidTargetDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresTarget = (1u << 0),
//----------------------------------------------------------------------
// eFlagRequiresProcess
//
// Ensures a valid process is contained in m_exe_ctx prior to executing
// the command. If a process doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidProcessDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidProcessDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresProcess = (1u << 1),
//----------------------------------------------------------------------
// eFlagRequiresThread
//
// Ensures a valid thread is contained in m_exe_ctx prior to executing
// the command. If a thread doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidThreadDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidThreadDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresThread = (1u << 2),
//----------------------------------------------------------------------
// eFlagRequiresFrame
//
// Ensures a valid frame is contained in m_exe_ctx prior to executing
// the command. If a frame doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidFrameDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidFrameDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresFrame = (1u << 3),
//----------------------------------------------------------------------
// eFlagRequiresRegContext
//
// Ensures a valid register context (from the selected frame if there
// is a frame in m_exe_ctx, or from the selected thread from m_exe_ctx)
// is availble from m_exe_ctx prior to executing the command. If a
// target doesn't exist or is invalid, the command will fail and
// CommandObject::GetInvalidRegContextDescription() will be returned as
// the error. CommandObject subclasses can override the virtual function
// for GetInvalidRegContextDescription() to provide custom strings when
// needed.
//----------------------------------------------------------------------
eFlagRequiresRegContext = (1u << 4),
//----------------------------------------------------------------------
// eFlagTryTargetAPILock
//
// Attempts to acquire the target lock if a target is selected in the
// command interpreter. If the command object fails to acquire the API
// lock, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagTryTargetAPILock = (1u << 5),
//----------------------------------------------------------------------
// eFlagProcessMustBeLaunched
//
// Verifies that there is a launched process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBeLaunched = (1u << 6),
//----------------------------------------------------------------------
// eFlagProcessMustBePaused
//
// Verifies that there is a paused process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBePaused = (1u << 7)
};
Now each command object contains a "ExecutionContext m_exe_ctx;" member variable that gets initialized prior to running the command. The validity of the target objects in m_exe_ctx are checked to ensure that any target/process/thread/frame/reg context that are required are valid prior to executing the command. Each command object also contains a Mutex::Locker m_api_locker which gets used if eFlagTryTargetAPILock is set. This centralizes a lot of checking code that was previously and inconsistently implemented across many commands.
llvm-svn: 171990
2013-01-10 03:44:40 +08:00
m_exe_ctx . GetBestExecutionContextScope ( ) ,
2012-12-07 08:19:47 +08:00
sc . line_entry . range . GetBaseAddress ( ) ,
show_fullpaths ,
show_module ,
show_inlined_frames ) ;
result . GetOutputStream ( ) . EOL ( ) ;
2013-03-14 02:25:49 +08:00
if ( m_options . num_lines = = 0 )
m_options . num_lines = 10 ;
2012-12-07 08:19:47 +08:00
size_t lines_to_back_up = m_options . num_lines > = 10 ? 5 : m_options . num_lines / 2 ;
target - > GetSourceManager ( ) . DisplaySourceLinesWithLineNumbers ( sc . comp_unit ,
sc . line_entry . line ,
lines_to_back_up ,
m_options . num_lines - lines_to_back_up ,
" -> " ,
& result . GetOutputStream ( ) ,
GetBreakpointLocations ( ) ) ;
result . SetStatus ( eReturnStatusSuccessFinishResult ) ;
}
}
}
2010-08-20 09:17:07 +08:00
else if ( m_options . file_name . empty ( ) )
2010-07-07 11:36:20 +08:00
{
// Last valid source manager context, or the current frame if no
// valid last context in source manager.
// One little trick here, if you type the exact same list command twice in a row, it is
// more likely because you typed it once, then typed it again
if ( m_options . start_line = = 0 )
{
2011-09-30 04:22:33 +08:00
if ( target - > GetSourceManager ( ) . DisplayMoreWithLineNumbers ( & result . GetOutputStream ( ) ,
2013-03-14 02:25:49 +08:00
m_options . num_lines ,
m_options . reverse ,
GetBreakpointLocations ( ) ) )
2010-06-09 00:52:24 +08:00
{
result . SetStatus ( eReturnStatusSuccessFinishResult ) ;
}
2010-07-07 11:36:20 +08:00
}
else
{
2013-03-14 02:25:49 +08:00
if ( m_options . num_lines = = 0 )
m_options . num_lines = 10 ;
2011-09-09 06:13:49 +08:00
if ( m_options . show_bp_locs )
2011-04-21 02:52:45 +08:00
{
2011-09-09 06:13:49 +08:00
SourceManager : : FileSP last_file_sp ( target - > GetSourceManager ( ) . GetLastFile ( ) ) ;
2011-04-21 02:52:45 +08:00
if ( last_file_sp )
{
const bool show_inlines = true ;
m_breakpoint_locations . Reset ( last_file_sp - > GetFileSpec ( ) , 0 , show_inlines ) ;
2012-01-30 04:56:30 +08:00
SearchFilter target_search_filter ( target - > shared_from_this ( ) ) ;
2011-04-21 02:52:45 +08:00
target_search_filter . Search ( m_breakpoint_locations ) ;
}
}
else
m_breakpoint_locations . Clear ( ) ;
2011-09-09 06:13:49 +08:00
if ( target - > GetSourceManager ( ) . DisplaySourceLinesWithLineNumbersUsingLastFile (
2010-07-07 11:36:20 +08:00
m_options . start_line , // Line to display
2013-03-14 02:25:49 +08:00
m_options . num_lines , // Lines after line to
UINT32_MAX , // Don't mark "line"
2010-07-07 11:36:20 +08:00
" " , // Don't mark "line"
Added a new option to the "source list" command that allows us to see where
line tables specify breakpoints can be set in the source. When dumping the
source, the number of breakpoints that can be set on a source line are shown
as a prefix:
(lldb) source list -f test.c -l1 -c222 -b
1 #include <stdio.h>
2 #include <sys/fcntl.h>
3 #include <unistd.h>
4 int
5 sleep_loop (const int num_secs)
[2] 6 {
7 int i;
[1] 8 for (i=0; i<num_secs; ++i)
9 {
[1] 10 printf("%d of %i - sleep(1);\n", i, num_secs);
[1] 11 sleep(1);
12 }
13 return 0;
[1] 14 }
15
16 int
17 main (int argc, char const* argv[])
[1] 18 {
[1] 19 printf("Process: %i\n\n", getpid());
[1] 20 puts("Press any key to continue..."); getchar();
[1] 21 sleep_loop (20);
22 return 12;
[1] 23 }
Above we can see there are two breakpoints for line 6 and one breakpoint for
lines 8, 10, 11, 14, 18, 19, 20, 21 and 23. All other lines have no line table
entries for them. This helps visualize the data provided in the debug
information without having to manually dump all line tables. It also includes
all inline breakpoint that may result for a given file which can also be very
handy to see.
llvm-svn: 129747
2011-04-19 12:19:37 +08:00
& result . GetOutputStream ( ) ,
GetBreakpointLocations ( ) ) )
2010-06-09 00:52:24 +08:00
{
2010-07-07 11:36:20 +08:00
result . SetStatus ( eReturnStatusSuccessFinishResult ) ;
2010-06-09 00:52:24 +08:00
}
2010-07-07 11:36:20 +08:00
2010-06-09 00:52:24 +08:00
}
}
else
{
2010-07-07 11:36:20 +08:00
const char * filename = m_options . file_name . c_str ( ) ;
bool check_inlines = false ;
SymbolContextList sc_list ;
2010-08-20 09:17:07 +08:00
size_t num_matches = 0 ;
Added a new option to the "source list" command that allows us to see where
line tables specify breakpoints can be set in the source. When dumping the
source, the number of breakpoints that can be set on a source line are shown
as a prefix:
(lldb) source list -f test.c -l1 -c222 -b
1 #include <stdio.h>
2 #include <sys/fcntl.h>
3 #include <unistd.h>
4 int
5 sleep_loop (const int num_secs)
[2] 6 {
7 int i;
[1] 8 for (i=0; i<num_secs; ++i)
9 {
[1] 10 printf("%d of %i - sleep(1);\n", i, num_secs);
[1] 11 sleep(1);
12 }
13 return 0;
[1] 14 }
15
16 int
17 main (int argc, char const* argv[])
[1] 18 {
[1] 19 printf("Process: %i\n\n", getpid());
[1] 20 puts("Press any key to continue..."); getchar();
[1] 21 sleep_loop (20);
22 return 12;
[1] 23 }
Above we can see there are two breakpoints for line 6 and one breakpoint for
lines 8, 10, 11, 14, 18, 19, 20, 21 and 23. All other lines have no line table
entries for them. This helps visualize the data provided in the debug
information without having to manually dump all line tables. It also includes
all inline breakpoint that may result for a given file which can also be very
handy to see.
llvm-svn: 129747
2011-04-19 12:19:37 +08:00
if ( m_options . modules . size ( ) > 0 )
2010-08-20 09:17:07 +08:00
{
ModuleList matching_modules ;
2013-01-26 02:06:21 +08:00
for ( size_t i = 0 , e = m_options . modules . size ( ) ; i < e ; + + i )
2010-08-20 09:17:07 +08:00
{
2012-02-26 13:51:37 +08:00
FileSpec module_file_spec ( m_options . modules [ i ] . c_str ( ) , false ) ;
if ( module_file_spec )
2010-08-20 09:17:07 +08:00
{
2012-02-26 13:51:37 +08:00
ModuleSpec module_spec ( module_file_spec ) ;
2010-08-20 09:17:07 +08:00
matching_modules . Clear ( ) ;
2012-02-26 13:51:37 +08:00
target - > GetImages ( ) . FindModules ( module_spec , matching_modules ) ;
2010-08-20 09:17:07 +08:00
num_matches + = matching_modules . ResolveSymbolContextForFilePath ( filename ,
Added a new option to the "source list" command that allows us to see where
line tables specify breakpoints can be set in the source. When dumping the
source, the number of breakpoints that can be set on a source line are shown
as a prefix:
(lldb) source list -f test.c -l1 -c222 -b
1 #include <stdio.h>
2 #include <sys/fcntl.h>
3 #include <unistd.h>
4 int
5 sleep_loop (const int num_secs)
[2] 6 {
7 int i;
[1] 8 for (i=0; i<num_secs; ++i)
9 {
[1] 10 printf("%d of %i - sleep(1);\n", i, num_secs);
[1] 11 sleep(1);
12 }
13 return 0;
[1] 14 }
15
16 int
17 main (int argc, char const* argv[])
[1] 18 {
[1] 19 printf("Process: %i\n\n", getpid());
[1] 20 puts("Press any key to continue..."); getchar();
[1] 21 sleep_loop (20);
22 return 12;
[1] 23 }
Above we can see there are two breakpoints for line 6 and one breakpoint for
lines 8, 10, 11, 14, 18, 19, 20, 21 and 23. All other lines have no line table
entries for them. This helps visualize the data provided in the debug
information without having to manually dump all line tables. It also includes
all inline breakpoint that may result for a given file which can also be very
handy to see.
llvm-svn: 129747
2011-04-19 12:19:37 +08:00
0 ,
check_inlines ,
eSymbolContextModule | eSymbolContextCompUnit ,
sc_list ) ;
2010-08-20 09:17:07 +08:00
}
}
}
else
{
num_matches = target - > GetImages ( ) . ResolveSymbolContextForFilePath ( filename ,
0 ,
check_inlines ,
eSymbolContextModule | eSymbolContextCompUnit ,
sc_list ) ;
}
if ( num_matches = = 0 )
{
result . AppendErrorWithFormat ( " Could not find source file \" %s \" . \n " ,
m_options . file_name . c_str ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
if ( num_matches > 1 )
2010-07-07 11:36:20 +08:00
{
SymbolContext sc ;
2010-08-20 09:17:07 +08:00
bool got_multiple = false ;
FileSpec * test_cu_spec = NULL ;
2010-09-09 06:55:31 +08:00
for ( unsigned i = 0 ; i < num_matches ; i + + )
2010-07-07 11:36:20 +08:00
{
2010-08-20 09:17:07 +08:00
sc_list . GetContextAtIndex ( i , sc ) ;
2010-07-07 11:36:20 +08:00
if ( sc . comp_unit )
{
2010-08-20 09:17:07 +08:00
if ( test_cu_spec )
{
if ( test_cu_spec ! = static_cast < FileSpec * > ( sc . comp_unit ) )
got_multiple = true ;
break ;
}
else
test_cu_spec = sc . comp_unit ;
2010-07-07 11:36:20 +08:00
}
}
2010-08-20 09:17:07 +08:00
if ( got_multiple )
{
result . AppendErrorWithFormat ( " Multiple source files found matching: \" %s. \" \n " ,
m_options . file_name . c_str ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
}
SymbolContext sc ;
if ( sc_list . GetContextAtIndex ( 0 , sc ) )
{
if ( sc . comp_unit )
{
2011-09-09 06:13:49 +08:00
if ( m_options . show_bp_locs )
Added a new option to the "source list" command that allows us to see where
line tables specify breakpoints can be set in the source. When dumping the
source, the number of breakpoints that can be set on a source line are shown
as a prefix:
(lldb) source list -f test.c -l1 -c222 -b
1 #include <stdio.h>
2 #include <sys/fcntl.h>
3 #include <unistd.h>
4 int
5 sleep_loop (const int num_secs)
[2] 6 {
7 int i;
[1] 8 for (i=0; i<num_secs; ++i)
9 {
[1] 10 printf("%d of %i - sleep(1);\n", i, num_secs);
[1] 11 sleep(1);
12 }
13 return 0;
[1] 14 }
15
16 int
17 main (int argc, char const* argv[])
[1] 18 {
[1] 19 printf("Process: %i\n\n", getpid());
[1] 20 puts("Press any key to continue..."); getchar();
[1] 21 sleep_loop (20);
22 return 12;
[1] 23 }
Above we can see there are two breakpoints for line 6 and one breakpoint for
lines 8, 10, 11, 14, 18, 19, 20, 21 and 23. All other lines have no line table
entries for them. This helps visualize the data provided in the debug
information without having to manually dump all line tables. It also includes
all inline breakpoint that may result for a given file which can also be very
handy to see.
llvm-svn: 129747
2011-04-19 12:19:37 +08:00
{
const bool show_inlines = true ;
m_breakpoint_locations . Reset ( * sc . comp_unit , 0 , show_inlines ) ;
2012-01-30 04:56:30 +08:00
SearchFilter target_search_filter ( target - > shared_from_this ( ) ) ;
Added a new option to the "source list" command that allows us to see where
line tables specify breakpoints can be set in the source. When dumping the
source, the number of breakpoints that can be set on a source line are shown
as a prefix:
(lldb) source list -f test.c -l1 -c222 -b
1 #include <stdio.h>
2 #include <sys/fcntl.h>
3 #include <unistd.h>
4 int
5 sleep_loop (const int num_secs)
[2] 6 {
7 int i;
[1] 8 for (i=0; i<num_secs; ++i)
9 {
[1] 10 printf("%d of %i - sleep(1);\n", i, num_secs);
[1] 11 sleep(1);
12 }
13 return 0;
[1] 14 }
15
16 int
17 main (int argc, char const* argv[])
[1] 18 {
[1] 19 printf("Process: %i\n\n", getpid());
[1] 20 puts("Press any key to continue..."); getchar();
[1] 21 sleep_loop (20);
22 return 12;
[1] 23 }
Above we can see there are two breakpoints for line 6 and one breakpoint for
lines 8, 10, 11, 14, 18, 19, 20, 21 and 23. All other lines have no line table
entries for them. This helps visualize the data provided in the debug
information without having to manually dump all line tables. It also includes
all inline breakpoint that may result for a given file which can also be very
handy to see.
llvm-svn: 129747
2011-04-19 12:19:37 +08:00
target_search_filter . Search ( m_breakpoint_locations ) ;
}
else
m_breakpoint_locations . Clear ( ) ;
2013-03-14 02:25:49 +08:00
if ( m_options . num_lines = = 0 )
m_options . num_lines = 10 ;
2011-09-09 06:13:49 +08:00
target - > GetSourceManager ( ) . DisplaySourceLinesWithLineNumbers ( sc . comp_unit ,
m_options . start_line ,
0 ,
m_options . num_lines ,
" " ,
& result . GetOutputStream ( ) ,
GetBreakpointLocations ( ) ) ;
Added a new option to the "source list" command that allows us to see where
line tables specify breakpoints can be set in the source. When dumping the
source, the number of breakpoints that can be set on a source line are shown
as a prefix:
(lldb) source list -f test.c -l1 -c222 -b
1 #include <stdio.h>
2 #include <sys/fcntl.h>
3 #include <unistd.h>
4 int
5 sleep_loop (const int num_secs)
[2] 6 {
7 int i;
[1] 8 for (i=0; i<num_secs; ++i)
9 {
[1] 10 printf("%d of %i - sleep(1);\n", i, num_secs);
[1] 11 sleep(1);
12 }
13 return 0;
[1] 14 }
15
16 int
17 main (int argc, char const* argv[])
[1] 18 {
[1] 19 printf("Process: %i\n\n", getpid());
[1] 20 puts("Press any key to continue..."); getchar();
[1] 21 sleep_loop (20);
22 return 12;
[1] 23 }
Above we can see there are two breakpoints for line 6 and one breakpoint for
lines 8, 10, 11, 14, 18, 19, 20, 21 and 23. All other lines have no line table
entries for them. This helps visualize the data provided in the debug
information without having to manually dump all line tables. It also includes
all inline breakpoint that may result for a given file which can also be very
handy to see.
llvm-svn: 129747
2011-04-19 12:19:37 +08:00
2010-08-20 09:17:07 +08:00
result . SetStatus ( eReturnStatusSuccessFinishResult ) ;
}
else
{
result . AppendErrorWithFormat ( " No comp unit found for: \" %s. \" \n " ,
m_options . file_name . c_str ( ) ) ;
result . SetStatus ( eReturnStatusFailed ) ;
return false ;
}
2010-07-07 11:36:20 +08:00
}
2010-06-09 00:52:24 +08:00
}
2010-07-07 11:36:20 +08:00
return result . Succeeded ( ) ;
2010-06-09 00:52:24 +08:00
}
2010-07-07 11:36:20 +08:00
Added a new option to the "source list" command that allows us to see where
line tables specify breakpoints can be set in the source. When dumping the
source, the number of breakpoints that can be set on a source line are shown
as a prefix:
(lldb) source list -f test.c -l1 -c222 -b
1 #include <stdio.h>
2 #include <sys/fcntl.h>
3 #include <unistd.h>
4 int
5 sleep_loop (const int num_secs)
[2] 6 {
7 int i;
[1] 8 for (i=0; i<num_secs; ++i)
9 {
[1] 10 printf("%d of %i - sleep(1);\n", i, num_secs);
[1] 11 sleep(1);
12 }
13 return 0;
[1] 14 }
15
16 int
17 main (int argc, char const* argv[])
[1] 18 {
[1] 19 printf("Process: %i\n\n", getpid());
[1] 20 puts("Press any key to continue..."); getchar();
[1] 21 sleep_loop (20);
22 return 12;
[1] 23 }
Above we can see there are two breakpoints for line 6 and one breakpoint for
lines 8, 10, 11, 14, 18, 19, 20, 21 and 23. All other lines have no line table
entries for them. This helps visualize the data provided in the debug
information without having to manually dump all line tables. It also includes
all inline breakpoint that may result for a given file which can also be very
handy to see.
llvm-svn: 129747
2011-04-19 12:19:37 +08:00
const SymbolContextList *
GetBreakpointLocations ( )
{
if ( m_breakpoint_locations . GetFileLineMatches ( ) . GetSize ( ) > 0 )
return & m_breakpoint_locations . GetFileLineMatches ( ) ;
return NULL ;
}
2010-07-07 11:36:20 +08:00
CommandOptions m_options ;
Added a new option to the "source list" command that allows us to see where
line tables specify breakpoints can be set in the source. When dumping the
source, the number of breakpoints that can be set on a source line are shown
as a prefix:
(lldb) source list -f test.c -l1 -c222 -b
1 #include <stdio.h>
2 #include <sys/fcntl.h>
3 #include <unistd.h>
4 int
5 sleep_loop (const int num_secs)
[2] 6 {
7 int i;
[1] 8 for (i=0; i<num_secs; ++i)
9 {
[1] 10 printf("%d of %i - sleep(1);\n", i, num_secs);
[1] 11 sleep(1);
12 }
13 return 0;
[1] 14 }
15
16 int
17 main (int argc, char const* argv[])
[1] 18 {
[1] 19 printf("Process: %i\n\n", getpid());
[1] 20 puts("Press any key to continue..."); getchar();
[1] 21 sleep_loop (20);
22 return 12;
[1] 23 }
Above we can see there are two breakpoints for line 6 and one breakpoint for
lines 8, 10, 11, 14, 18, 19, 20, 21 and 23. All other lines have no line table
entries for them. This helps visualize the data provided in the debug
information without having to manually dump all line tables. It also includes
all inline breakpoint that may result for a given file which can also be very
handy to see.
llvm-svn: 129747
2011-04-19 12:19:37 +08:00
FileLineResolver m_breakpoint_locations ;
2013-01-09 11:27:33 +08:00
std : : string m_reverse_name ;
2010-07-07 11:36:20 +08:00
} ;
2011-03-25 05:19:54 +08:00
OptionDefinition
2010-07-07 11:36:20 +08:00
CommandObjectSourceList : : CommandOptions : : g_option_table [ ] =
{
2012-12-07 08:19:47 +08:00
{ LLDB_OPT_SET_ALL , false , " count " , ' c ' , required_argument , NULL , 0 , eArgTypeCount , " The number of source lines to display. " } ,
{ LLDB_OPT_SET_1 |
LLDB_OPT_SET_2 , false , " shlib " , ' s ' , required_argument , NULL , CommandCompletions : : eModuleCompletion , eArgTypeShlibName , " Look up the source file in the given shared library. " } ,
Added a new option to the "source list" command that allows us to see where
line tables specify breakpoints can be set in the source. When dumping the
source, the number of breakpoints that can be set on a source line are shown
as a prefix:
(lldb) source list -f test.c -l1 -c222 -b
1 #include <stdio.h>
2 #include <sys/fcntl.h>
3 #include <unistd.h>
4 int
5 sleep_loop (const int num_secs)
[2] 6 {
7 int i;
[1] 8 for (i=0; i<num_secs; ++i)
9 {
[1] 10 printf("%d of %i - sleep(1);\n", i, num_secs);
[1] 11 sleep(1);
12 }
13 return 0;
[1] 14 }
15
16 int
17 main (int argc, char const* argv[])
[1] 18 {
[1] 19 printf("Process: %i\n\n", getpid());
[1] 20 puts("Press any key to continue..."); getchar();
[1] 21 sleep_loop (20);
22 return 12;
[1] 23 }
Above we can see there are two breakpoints for line 6 and one breakpoint for
lines 8, 10, 11, 14, 18, 19, 20, 21 and 23. All other lines have no line table
entries for them. This helps visualize the data provided in the debug
information without having to manually dump all line tables. It also includes
all inline breakpoint that may result for a given file which can also be very
handy to see.
llvm-svn: 129747
2011-04-19 12:19:37 +08:00
{ LLDB_OPT_SET_ALL , false , " show-breakpoints " , ' b ' , no_argument , NULL , 0 , eArgTypeNone , " Show the line table locations from the debug information that indicate valid places to set source level breakpoints. " } ,
2012-12-07 08:19:47 +08:00
{ LLDB_OPT_SET_1 , false , " file " , ' f ' , required_argument , NULL , CommandCompletions : : eSourceFileCompletion , eArgTypeFilename , " The file from which to display source. " } ,
{ LLDB_OPT_SET_1 , false , " line " , ' l ' , required_argument , NULL , 0 , eArgTypeLineNum , " The line number at which to start the display source. " } ,
{ LLDB_OPT_SET_2 , false , " name " , ' n ' , required_argument , NULL , CommandCompletions : : eSymbolCompletion , eArgTypeSymbol , " The name of a function whose source to display. " } ,
2013-01-29 09:48:30 +08:00
{ LLDB_OPT_SET_3 , false , " address " , ' a ' , required_argument , NULL , 0 , eArgTypeAddressOrExpression , " Lookup the address and display the source information for the corresponding file and line. " } ,
2013-01-09 11:27:33 +08:00
{ LLDB_OPT_SET_4 , false , " reverse " , ' r ' , no_argument , NULL , 0 , eArgTypeNone , " Reverse the listing to look backwards from the last displayed block of source. " } ,
2010-10-02 03:59:14 +08:00
{ 0 , false , NULL , 0 , 0 , NULL , 0 , eArgTypeNone , NULL }
2010-07-07 11:36:20 +08:00
} ;
# pragma mark CommandObjectMultiwordSource
//-------------------------------------------------------------------------
// CommandObjectMultiwordSource
//-------------------------------------------------------------------------
CommandObjectMultiwordSource : : CommandObjectMultiwordSource ( CommandInterpreter & interpreter ) :
2010-09-18 09:14:36 +08:00
CommandObjectMultiword ( interpreter ,
" source " ,
2010-09-08 06:38:08 +08:00
" A set of commands for accessing source file information " ,
2010-07-07 11:36:20 +08:00
" source <subcommand> [<subcommand-options>] " )
{
2013-04-19 03:58:52 +08:00
// "source info" isn't implemented yet...
//LoadSubCommand ("info", CommandObjectSP (new CommandObjectSourceInfo (interpreter)));
2010-09-18 09:14:36 +08:00
LoadSubCommand ( " list " , CommandObjectSP ( new CommandObjectSourceList ( interpreter ) ) ) ;
2010-07-07 11:36:20 +08:00
}
CommandObjectMultiwordSource : : ~ CommandObjectMultiwordSource ( )
{
2010-06-09 00:52:24 +08:00
}
2010-07-07 11:36:20 +08:00