2010-06-09 00:52:24 +08:00
//===-- Target.cpp ----------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
# include "lldb/Target/Target.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
# include "lldb/Breakpoint/BreakpointResolver.h"
# include "lldb/Breakpoint/BreakpointResolverAddress.h"
# include "lldb/Breakpoint/BreakpointResolverFileLine.h"
2011-09-21 09:17:13 +08:00
# include "lldb/Breakpoint/BreakpointResolverFileRegex.h"
2010-06-09 00:52:24 +08:00
# include "lldb/Breakpoint/BreakpointResolverName.h"
2011-10-14 08:42:25 +08:00
# include "lldb/Breakpoint/Watchpoint.h"
2010-12-14 10:59:59 +08:00
# include "lldb/Core/Debugger.h"
2010-06-09 00:52:24 +08:00
# include "lldb/Core/Event.h"
# include "lldb/Core/Log.h"
# include "lldb/Core/StreamString.h"
2010-12-14 10:59:59 +08:00
# include "lldb/Core/Timer.h"
# include "lldb/Core/ValueObject.h"
2011-11-16 06:27:19 +08:00
# include "lldb/Expression/ClangASTSource.h"
2011-04-08 06:46:35 +08:00
# include "lldb/Expression/ClangUserExpression.h"
2010-06-09 00:52:24 +08:00
# include "lldb/Host/Host.h"
Add a first pass at a "stop hook" mechanism. This allows you to add commands that get run every time the debugger stops, whether due to a breakpoint, the end of a step, interrupt, etc. You can also specify in which context you want the stop hook to run, for instance only on a particular thread, or only in a particular shared library, function, file, line range within a file.
Still need to add "in methods of a class" to the specifiers, and the ability to write the stop hooks in the Scripting language as well as in the Command Language.
llvm-svn: 127457
2011-03-11 11:53:59 +08:00
# include "lldb/Interpreter/CommandInterpreter.h"
# include "lldb/Interpreter/CommandReturnObject.h"
2010-06-09 00:52:24 +08:00
# include "lldb/lldb-private-log.h"
# include "lldb/Symbol/ObjectFile.h"
# include "lldb/Target/Process.h"
2010-12-14 10:59:59 +08:00
# include "lldb/Target/StackFrame.h"
Add a first pass at a "stop hook" mechanism. This allows you to add commands that get run every time the debugger stops, whether due to a breakpoint, the end of a step, interrupt, etc. You can also specify in which context you want the stop hook to run, for instance only on a particular thread, or only in a particular shared library, function, file, line range within a file.
Still need to add "in methods of a class" to the specifiers, and the ability to write the stop hooks in the Scripting language as well as in the Command Language.
llvm-svn: 127457
2011-03-11 11:53:59 +08:00
# include "lldb/Target/Thread.h"
# include "lldb/Target/ThreadSpec.h"
2010-06-09 00:52:24 +08:00
using namespace lldb ;
using namespace lldb_private ;
2012-02-16 14:50:00 +08:00
ConstString &
Target : : GetStaticBroadcasterClass ( )
{
static ConstString class_name ( " lldb.target " ) ;
return class_name ;
}
2010-06-09 00:52:24 +08:00
//----------------------------------------------------------------------
// Target constructor
//----------------------------------------------------------------------
Many improvements to the Platform base class and subclasses. The base Platform
class now implements the Host functionality for a lot of things that make
sense by default so that subclasses can check:
int
PlatformSubclass::Foo ()
{
if (IsHost())
return Platform::Foo (); // Let the platform base class do the host specific stuff
// Platform subclass specific code...
int result = ...
return result;
}
Added new functions to the platform:
virtual const char *Platform::GetUserName (uint32_t uid);
virtual const char *Platform::GetGroupName (uint32_t gid);
The user and group names are cached locally so that remote platforms can avoid
sending packets multiple times to resolve this information.
Added the parent process ID to the ProcessInfo class.
Added a new ProcessInfoMatch class which helps us to match processes up
and changed the Host layer over to using this new class. The new class allows
us to search for processs:
1 - by name (equal to, starts with, ends with, contains, and regex)
2 - by pid
3 - And further check for parent pid == value, uid == value, gid == value,
euid == value, egid == value, arch == value, parent == value.
This is all hookup up to the "platform process list" command which required
adding dumping routines to dump process information. If the Host class
implements the process lookup routines, you can now lists processes on
your local machine:
machine1.foo.com % lldb
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
94727 244 username usergroup username usergroup x86_64-apple-darwin Xcode
92742 92710 username usergroup username usergroup i386-apple-darwin debugserver
This of course also works remotely with the lldb-platform:
machine1.foo.com % lldb-platform --listen 1234
machine2.foo.com % lldb
(lldb) platform create remote-macosx
Platform: remote-macosx
Connected: no
(lldb) platform connect connect://localhost:1444
Platform: remote-macosx
Triple: x86_64-apple-darwin
OS Version: 10.6.7 (10J869)
Kernel: Darwin Kernel Version 10.7.0: Sat Jan 29 15:17:16 PST 2011; root:xnu-1504.9.37~1/RELEASE_I386
Hostname: machine1.foo.com
Connected: yes
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99556 244 username usergroup username usergroup x86_64-apple-darwin trustevaluation
99548 65539 username usergroup username usergroup x86_64-apple-darwin lldb
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
The lldb-platform implements everything with the Host:: layer, so this should
"just work" for linux. I will probably be adding more stuff to the Host layer
for launching processes and attaching to processes so that this support should
eventually just work as well.
Modified the target to be able to be created with an architecture that differs
from the main executable. This is needed for iOS debugging since we can have
an "armv6" binary which can run on an "armv7" machine, so we want to be able
to do:
% lldb
(lldb) platform create remote-ios
(lldb) file --arch armv7 a.out
Where "a.out" is an armv6 executable. The platform then can correctly decide
to open all "armv7" images for all dependent shared libraries.
Modified the disassembly to show the current PC value. Example output:
(lldb) disassemble --frame
a.out`main:
0x1eb7: pushl %ebp
0x1eb8: movl %esp, %ebp
0x1eba: pushl %ebx
0x1ebb: subl $20, %esp
0x1ebe: calll 0x1ec3 ; main + 12 at test.c:18
0x1ec3: popl %ebx
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
0x1edb: leal 213(%ebx), %eax
0x1ee1: movl %eax, (%esp)
0x1ee4: calll 0x1f1e ; puts
0x1ee9: calll 0x1f0c ; getchar
0x1eee: movl $20, (%esp)
0x1ef5: calll 0x1e6a ; sleep_loop at test.c:6
0x1efa: movl $12, %eax
0x1eff: addl $20, %esp
0x1f02: popl %ebx
0x1f03: leave
0x1f04: ret
This can be handy when dealing with the new --line options that was recently
added:
(lldb) disassemble --line
a.out`main + 13 at test.c:19
18 {
-> 19 printf("Process: %i\n\n", getpid());
20 puts("Press any key to continue..."); getchar();
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
Modified the ModuleList to have a lookup based solely on a UUID. Since the
UUID is typically the MD5 checksum of a binary image, there is no need
to give the path and architecture when searching for a pre-existing
image in an image list.
Now that we support remote debugging a bit better, our lldb_private::Module
needs to be able to track what the original path for file was as the platform
knows it, as well as where the file is locally. The module has the two
following functions to retrieve both paths:
const FileSpec &Module::GetFileSpec () const;
const FileSpec &Module::GetPlatformFileSpec () const;
llvm-svn: 128563
2011-03-31 02:16:51 +08:00
Target : : Target ( Debugger & debugger , const ArchSpec & target_arch , const lldb : : PlatformSP & platform_sp ) :
2012-02-16 14:50:00 +08:00
Broadcaster ( & debugger , " lldb.target " ) ,
Many improvements to the Platform base class and subclasses. The base Platform
class now implements the Host functionality for a lot of things that make
sense by default so that subclasses can check:
int
PlatformSubclass::Foo ()
{
if (IsHost())
return Platform::Foo (); // Let the platform base class do the host specific stuff
// Platform subclass specific code...
int result = ...
return result;
}
Added new functions to the platform:
virtual const char *Platform::GetUserName (uint32_t uid);
virtual const char *Platform::GetGroupName (uint32_t gid);
The user and group names are cached locally so that remote platforms can avoid
sending packets multiple times to resolve this information.
Added the parent process ID to the ProcessInfo class.
Added a new ProcessInfoMatch class which helps us to match processes up
and changed the Host layer over to using this new class. The new class allows
us to search for processs:
1 - by name (equal to, starts with, ends with, contains, and regex)
2 - by pid
3 - And further check for parent pid == value, uid == value, gid == value,
euid == value, egid == value, arch == value, parent == value.
This is all hookup up to the "platform process list" command which required
adding dumping routines to dump process information. If the Host class
implements the process lookup routines, you can now lists processes on
your local machine:
machine1.foo.com % lldb
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
94727 244 username usergroup username usergroup x86_64-apple-darwin Xcode
92742 92710 username usergroup username usergroup i386-apple-darwin debugserver
This of course also works remotely with the lldb-platform:
machine1.foo.com % lldb-platform --listen 1234
machine2.foo.com % lldb
(lldb) platform create remote-macosx
Platform: remote-macosx
Connected: no
(lldb) platform connect connect://localhost:1444
Platform: remote-macosx
Triple: x86_64-apple-darwin
OS Version: 10.6.7 (10J869)
Kernel: Darwin Kernel Version 10.7.0: Sat Jan 29 15:17:16 PST 2011; root:xnu-1504.9.37~1/RELEASE_I386
Hostname: machine1.foo.com
Connected: yes
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99556 244 username usergroup username usergroup x86_64-apple-darwin trustevaluation
99548 65539 username usergroup username usergroup x86_64-apple-darwin lldb
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
The lldb-platform implements everything with the Host:: layer, so this should
"just work" for linux. I will probably be adding more stuff to the Host layer
for launching processes and attaching to processes so that this support should
eventually just work as well.
Modified the target to be able to be created with an architecture that differs
from the main executable. This is needed for iOS debugging since we can have
an "armv6" binary which can run on an "armv7" machine, so we want to be able
to do:
% lldb
(lldb) platform create remote-ios
(lldb) file --arch armv7 a.out
Where "a.out" is an armv6 executable. The platform then can correctly decide
to open all "armv7" images for all dependent shared libraries.
Modified the disassembly to show the current PC value. Example output:
(lldb) disassemble --frame
a.out`main:
0x1eb7: pushl %ebp
0x1eb8: movl %esp, %ebp
0x1eba: pushl %ebx
0x1ebb: subl $20, %esp
0x1ebe: calll 0x1ec3 ; main + 12 at test.c:18
0x1ec3: popl %ebx
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
0x1edb: leal 213(%ebx), %eax
0x1ee1: movl %eax, (%esp)
0x1ee4: calll 0x1f1e ; puts
0x1ee9: calll 0x1f0c ; getchar
0x1eee: movl $20, (%esp)
0x1ef5: calll 0x1e6a ; sleep_loop at test.c:6
0x1efa: movl $12, %eax
0x1eff: addl $20, %esp
0x1f02: popl %ebx
0x1f03: leave
0x1f04: ret
This can be handy when dealing with the new --line options that was recently
added:
(lldb) disassemble --line
a.out`main + 13 at test.c:19
18 {
-> 19 printf("Process: %i\n\n", getpid());
20 puts("Press any key to continue..."); getchar();
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
Modified the ModuleList to have a lookup based solely on a UUID. Since the
UUID is typically the MD5 checksum of a binary image, there is no need
to give the path and architecture when searching for a pre-existing
image in an image list.
Now that we support remote debugging a bit better, our lldb_private::Module
needs to be able to track what the original path for file was as the platform
knows it, as well as where the file is locally. The module has the two
following functions to retrieve both paths:
const FileSpec &Module::GetFileSpec () const;
const FileSpec &Module::GetPlatformFileSpec () const;
llvm-svn: 128563
2011-03-31 02:16:51 +08:00
ExecutionContextScope ( ) ,
2012-01-30 15:41:31 +08:00
TargetInstanceSettings ( GetSettingsController ( ) ) ,
2010-06-23 09:19:29 +08:00
m_debugger ( debugger ) ,
Many improvements to the Platform base class and subclasses. The base Platform
class now implements the Host functionality for a lot of things that make
sense by default so that subclasses can check:
int
PlatformSubclass::Foo ()
{
if (IsHost())
return Platform::Foo (); // Let the platform base class do the host specific stuff
// Platform subclass specific code...
int result = ...
return result;
}
Added new functions to the platform:
virtual const char *Platform::GetUserName (uint32_t uid);
virtual const char *Platform::GetGroupName (uint32_t gid);
The user and group names are cached locally so that remote platforms can avoid
sending packets multiple times to resolve this information.
Added the parent process ID to the ProcessInfo class.
Added a new ProcessInfoMatch class which helps us to match processes up
and changed the Host layer over to using this new class. The new class allows
us to search for processs:
1 - by name (equal to, starts with, ends with, contains, and regex)
2 - by pid
3 - And further check for parent pid == value, uid == value, gid == value,
euid == value, egid == value, arch == value, parent == value.
This is all hookup up to the "platform process list" command which required
adding dumping routines to dump process information. If the Host class
implements the process lookup routines, you can now lists processes on
your local machine:
machine1.foo.com % lldb
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
94727 244 username usergroup username usergroup x86_64-apple-darwin Xcode
92742 92710 username usergroup username usergroup i386-apple-darwin debugserver
This of course also works remotely with the lldb-platform:
machine1.foo.com % lldb-platform --listen 1234
machine2.foo.com % lldb
(lldb) platform create remote-macosx
Platform: remote-macosx
Connected: no
(lldb) platform connect connect://localhost:1444
Platform: remote-macosx
Triple: x86_64-apple-darwin
OS Version: 10.6.7 (10J869)
Kernel: Darwin Kernel Version 10.7.0: Sat Jan 29 15:17:16 PST 2011; root:xnu-1504.9.37~1/RELEASE_I386
Hostname: machine1.foo.com
Connected: yes
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99556 244 username usergroup username usergroup x86_64-apple-darwin trustevaluation
99548 65539 username usergroup username usergroup x86_64-apple-darwin lldb
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
The lldb-platform implements everything with the Host:: layer, so this should
"just work" for linux. I will probably be adding more stuff to the Host layer
for launching processes and attaching to processes so that this support should
eventually just work as well.
Modified the target to be able to be created with an architecture that differs
from the main executable. This is needed for iOS debugging since we can have
an "armv6" binary which can run on an "armv7" machine, so we want to be able
to do:
% lldb
(lldb) platform create remote-ios
(lldb) file --arch armv7 a.out
Where "a.out" is an armv6 executable. The platform then can correctly decide
to open all "armv7" images for all dependent shared libraries.
Modified the disassembly to show the current PC value. Example output:
(lldb) disassemble --frame
a.out`main:
0x1eb7: pushl %ebp
0x1eb8: movl %esp, %ebp
0x1eba: pushl %ebx
0x1ebb: subl $20, %esp
0x1ebe: calll 0x1ec3 ; main + 12 at test.c:18
0x1ec3: popl %ebx
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
0x1edb: leal 213(%ebx), %eax
0x1ee1: movl %eax, (%esp)
0x1ee4: calll 0x1f1e ; puts
0x1ee9: calll 0x1f0c ; getchar
0x1eee: movl $20, (%esp)
0x1ef5: calll 0x1e6a ; sleep_loop at test.c:6
0x1efa: movl $12, %eax
0x1eff: addl $20, %esp
0x1f02: popl %ebx
0x1f03: leave
0x1f04: ret
This can be handy when dealing with the new --line options that was recently
added:
(lldb) disassemble --line
a.out`main + 13 at test.c:19
18 {
-> 19 printf("Process: %i\n\n", getpid());
20 puts("Press any key to continue..."); getchar();
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
Modified the ModuleList to have a lookup based solely on a UUID. Since the
UUID is typically the MD5 checksum of a binary image, there is no need
to give the path and architecture when searching for a pre-existing
image in an image list.
Now that we support remote debugging a bit better, our lldb_private::Module
needs to be able to track what the original path for file was as the platform
knows it, as well as where the file is locally. The module has the two
following functions to retrieve both paths:
const FileSpec &Module::GetFileSpec () const;
const FileSpec &Module::GetPlatformFileSpec () const;
llvm-svn: 128563
2011-03-31 02:16:51 +08:00
m_platform_sp ( platform_sp ) ,
2010-12-21 04:49:23 +08:00
m_mutex ( Mutex : : eMutexTypeRecursive ) ,
Many improvements to the Platform base class and subclasses. The base Platform
class now implements the Host functionality for a lot of things that make
sense by default so that subclasses can check:
int
PlatformSubclass::Foo ()
{
if (IsHost())
return Platform::Foo (); // Let the platform base class do the host specific stuff
// Platform subclass specific code...
int result = ...
return result;
}
Added new functions to the platform:
virtual const char *Platform::GetUserName (uint32_t uid);
virtual const char *Platform::GetGroupName (uint32_t gid);
The user and group names are cached locally so that remote platforms can avoid
sending packets multiple times to resolve this information.
Added the parent process ID to the ProcessInfo class.
Added a new ProcessInfoMatch class which helps us to match processes up
and changed the Host layer over to using this new class. The new class allows
us to search for processs:
1 - by name (equal to, starts with, ends with, contains, and regex)
2 - by pid
3 - And further check for parent pid == value, uid == value, gid == value,
euid == value, egid == value, arch == value, parent == value.
This is all hookup up to the "platform process list" command which required
adding dumping routines to dump process information. If the Host class
implements the process lookup routines, you can now lists processes on
your local machine:
machine1.foo.com % lldb
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
94727 244 username usergroup username usergroup x86_64-apple-darwin Xcode
92742 92710 username usergroup username usergroup i386-apple-darwin debugserver
This of course also works remotely with the lldb-platform:
machine1.foo.com % lldb-platform --listen 1234
machine2.foo.com % lldb
(lldb) platform create remote-macosx
Platform: remote-macosx
Connected: no
(lldb) platform connect connect://localhost:1444
Platform: remote-macosx
Triple: x86_64-apple-darwin
OS Version: 10.6.7 (10J869)
Kernel: Darwin Kernel Version 10.7.0: Sat Jan 29 15:17:16 PST 2011; root:xnu-1504.9.37~1/RELEASE_I386
Hostname: machine1.foo.com
Connected: yes
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99556 244 username usergroup username usergroup x86_64-apple-darwin trustevaluation
99548 65539 username usergroup username usergroup x86_64-apple-darwin lldb
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
The lldb-platform implements everything with the Host:: layer, so this should
"just work" for linux. I will probably be adding more stuff to the Host layer
for launching processes and attaching to processes so that this support should
eventually just work as well.
Modified the target to be able to be created with an architecture that differs
from the main executable. This is needed for iOS debugging since we can have
an "armv6" binary which can run on an "armv7" machine, so we want to be able
to do:
% lldb
(lldb) platform create remote-ios
(lldb) file --arch armv7 a.out
Where "a.out" is an armv6 executable. The platform then can correctly decide
to open all "armv7" images for all dependent shared libraries.
Modified the disassembly to show the current PC value. Example output:
(lldb) disassemble --frame
a.out`main:
0x1eb7: pushl %ebp
0x1eb8: movl %esp, %ebp
0x1eba: pushl %ebx
0x1ebb: subl $20, %esp
0x1ebe: calll 0x1ec3 ; main + 12 at test.c:18
0x1ec3: popl %ebx
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
0x1edb: leal 213(%ebx), %eax
0x1ee1: movl %eax, (%esp)
0x1ee4: calll 0x1f1e ; puts
0x1ee9: calll 0x1f0c ; getchar
0x1eee: movl $20, (%esp)
0x1ef5: calll 0x1e6a ; sleep_loop at test.c:6
0x1efa: movl $12, %eax
0x1eff: addl $20, %esp
0x1f02: popl %ebx
0x1f03: leave
0x1f04: ret
This can be handy when dealing with the new --line options that was recently
added:
(lldb) disassemble --line
a.out`main + 13 at test.c:19
18 {
-> 19 printf("Process: %i\n\n", getpid());
20 puts("Press any key to continue..."); getchar();
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
Modified the ModuleList to have a lookup based solely on a UUID. Since the
UUID is typically the MD5 checksum of a binary image, there is no need
to give the path and architecture when searching for a pre-existing
image in an image list.
Now that we support remote debugging a bit better, our lldb_private::Module
needs to be able to track what the original path for file was as the platform
knows it, as well as where the file is locally. The module has the two
following functions to retrieve both paths:
const FileSpec &Module::GetFileSpec () const;
const FileSpec &Module::GetPlatformFileSpec () const;
llvm-svn: 128563
2011-03-31 02:16:51 +08:00
m_arch ( target_arch ) ,
m_images ( ) ,
2010-09-15 07:36:40 +08:00
m_section_load_list ( ) ,
2010-06-09 00:52:24 +08:00
m_breakpoint_list ( false ) ,
m_internal_breakpoint_list ( true ) ,
2011-10-14 08:42:25 +08:00
m_watchpoint_list ( ) ,
Many improvements to the Platform base class and subclasses. The base Platform
class now implements the Host functionality for a lot of things that make
sense by default so that subclasses can check:
int
PlatformSubclass::Foo ()
{
if (IsHost())
return Platform::Foo (); // Let the platform base class do the host specific stuff
// Platform subclass specific code...
int result = ...
return result;
}
Added new functions to the platform:
virtual const char *Platform::GetUserName (uint32_t uid);
virtual const char *Platform::GetGroupName (uint32_t gid);
The user and group names are cached locally so that remote platforms can avoid
sending packets multiple times to resolve this information.
Added the parent process ID to the ProcessInfo class.
Added a new ProcessInfoMatch class which helps us to match processes up
and changed the Host layer over to using this new class. The new class allows
us to search for processs:
1 - by name (equal to, starts with, ends with, contains, and regex)
2 - by pid
3 - And further check for parent pid == value, uid == value, gid == value,
euid == value, egid == value, arch == value, parent == value.
This is all hookup up to the "platform process list" command which required
adding dumping routines to dump process information. If the Host class
implements the process lookup routines, you can now lists processes on
your local machine:
machine1.foo.com % lldb
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
94727 244 username usergroup username usergroup x86_64-apple-darwin Xcode
92742 92710 username usergroup username usergroup i386-apple-darwin debugserver
This of course also works remotely with the lldb-platform:
machine1.foo.com % lldb-platform --listen 1234
machine2.foo.com % lldb
(lldb) platform create remote-macosx
Platform: remote-macosx
Connected: no
(lldb) platform connect connect://localhost:1444
Platform: remote-macosx
Triple: x86_64-apple-darwin
OS Version: 10.6.7 (10J869)
Kernel: Darwin Kernel Version 10.7.0: Sat Jan 29 15:17:16 PST 2011; root:xnu-1504.9.37~1/RELEASE_I386
Hostname: machine1.foo.com
Connected: yes
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99556 244 username usergroup username usergroup x86_64-apple-darwin trustevaluation
99548 65539 username usergroup username usergroup x86_64-apple-darwin lldb
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
The lldb-platform implements everything with the Host:: layer, so this should
"just work" for linux. I will probably be adding more stuff to the Host layer
for launching processes and attaching to processes so that this support should
eventually just work as well.
Modified the target to be able to be created with an architecture that differs
from the main executable. This is needed for iOS debugging since we can have
an "armv6" binary which can run on an "armv7" machine, so we want to be able
to do:
% lldb
(lldb) platform create remote-ios
(lldb) file --arch armv7 a.out
Where "a.out" is an armv6 executable. The platform then can correctly decide
to open all "armv7" images for all dependent shared libraries.
Modified the disassembly to show the current PC value. Example output:
(lldb) disassemble --frame
a.out`main:
0x1eb7: pushl %ebp
0x1eb8: movl %esp, %ebp
0x1eba: pushl %ebx
0x1ebb: subl $20, %esp
0x1ebe: calll 0x1ec3 ; main + 12 at test.c:18
0x1ec3: popl %ebx
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
0x1edb: leal 213(%ebx), %eax
0x1ee1: movl %eax, (%esp)
0x1ee4: calll 0x1f1e ; puts
0x1ee9: calll 0x1f0c ; getchar
0x1eee: movl $20, (%esp)
0x1ef5: calll 0x1e6a ; sleep_loop at test.c:6
0x1efa: movl $12, %eax
0x1eff: addl $20, %esp
0x1f02: popl %ebx
0x1f03: leave
0x1f04: ret
This can be handy when dealing with the new --line options that was recently
added:
(lldb) disassemble --line
a.out`main + 13 at test.c:19
18 {
-> 19 printf("Process: %i\n\n", getpid());
20 puts("Press any key to continue..."); getchar();
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
Modified the ModuleList to have a lookup based solely on a UUID. Since the
UUID is typically the MD5 checksum of a binary image, there is no need
to give the path and architecture when searching for a pre-existing
image in an image list.
Now that we support remote debugging a bit better, our lldb_private::Module
needs to be able to track what the original path for file was as the platform
knows it, as well as where the file is locally. The module has the two
following functions to retrieve both paths:
const FileSpec &Module::GetFileSpec () const;
const FileSpec &Module::GetPlatformFileSpec () const;
llvm-svn: 128563
2011-03-31 02:16:51 +08:00
m_process_sp ( ) ,
m_search_filter_sp ( ) ,
2010-06-09 00:52:24 +08:00
m_image_search_paths ( ImageSearchPathsChanged , this ) ,
2010-12-14 10:59:59 +08:00
m_scratch_ast_context_ap ( NULL ) ,
2011-11-17 02:20:47 +08:00
m_scratch_ast_source_ap ( NULL ) ,
m_ast_importer_ap ( NULL ) ,
Add a first pass at a "stop hook" mechanism. This allows you to add commands that get run every time the debugger stops, whether due to a breakpoint, the end of a step, interrupt, etc. You can also specify in which context you want the stop hook to run, for instance only on a particular thread, or only in a particular shared library, function, file, line range within a file.
Still need to add "in methods of a class" to the specifiers, and the ability to write the stop hooks in the Scripting language as well as in the Command Language.
llvm-svn: 127457
2011-03-11 11:53:59 +08:00
m_persistent_variables ( ) ,
2011-09-13 08:29:56 +08:00
m_source_manager ( * this ) ,
Many improvements to the Platform base class and subclasses. The base Platform
class now implements the Host functionality for a lot of things that make
sense by default so that subclasses can check:
int
PlatformSubclass::Foo ()
{
if (IsHost())
return Platform::Foo (); // Let the platform base class do the host specific stuff
// Platform subclass specific code...
int result = ...
return result;
}
Added new functions to the platform:
virtual const char *Platform::GetUserName (uint32_t uid);
virtual const char *Platform::GetGroupName (uint32_t gid);
The user and group names are cached locally so that remote platforms can avoid
sending packets multiple times to resolve this information.
Added the parent process ID to the ProcessInfo class.
Added a new ProcessInfoMatch class which helps us to match processes up
and changed the Host layer over to using this new class. The new class allows
us to search for processs:
1 - by name (equal to, starts with, ends with, contains, and regex)
2 - by pid
3 - And further check for parent pid == value, uid == value, gid == value,
euid == value, egid == value, arch == value, parent == value.
This is all hookup up to the "platform process list" command which required
adding dumping routines to dump process information. If the Host class
implements the process lookup routines, you can now lists processes on
your local machine:
machine1.foo.com % lldb
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
94727 244 username usergroup username usergroup x86_64-apple-darwin Xcode
92742 92710 username usergroup username usergroup i386-apple-darwin debugserver
This of course also works remotely with the lldb-platform:
machine1.foo.com % lldb-platform --listen 1234
machine2.foo.com % lldb
(lldb) platform create remote-macosx
Platform: remote-macosx
Connected: no
(lldb) platform connect connect://localhost:1444
Platform: remote-macosx
Triple: x86_64-apple-darwin
OS Version: 10.6.7 (10J869)
Kernel: Darwin Kernel Version 10.7.0: Sat Jan 29 15:17:16 PST 2011; root:xnu-1504.9.37~1/RELEASE_I386
Hostname: machine1.foo.com
Connected: yes
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99556 244 username usergroup username usergroup x86_64-apple-darwin trustevaluation
99548 65539 username usergroup username usergroup x86_64-apple-darwin lldb
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
The lldb-platform implements everything with the Host:: layer, so this should
"just work" for linux. I will probably be adding more stuff to the Host layer
for launching processes and attaching to processes so that this support should
eventually just work as well.
Modified the target to be able to be created with an architecture that differs
from the main executable. This is needed for iOS debugging since we can have
an "armv6" binary which can run on an "armv7" machine, so we want to be able
to do:
% lldb
(lldb) platform create remote-ios
(lldb) file --arch armv7 a.out
Where "a.out" is an armv6 executable. The platform then can correctly decide
to open all "armv7" images for all dependent shared libraries.
Modified the disassembly to show the current PC value. Example output:
(lldb) disassemble --frame
a.out`main:
0x1eb7: pushl %ebp
0x1eb8: movl %esp, %ebp
0x1eba: pushl %ebx
0x1ebb: subl $20, %esp
0x1ebe: calll 0x1ec3 ; main + 12 at test.c:18
0x1ec3: popl %ebx
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
0x1edb: leal 213(%ebx), %eax
0x1ee1: movl %eax, (%esp)
0x1ee4: calll 0x1f1e ; puts
0x1ee9: calll 0x1f0c ; getchar
0x1eee: movl $20, (%esp)
0x1ef5: calll 0x1e6a ; sleep_loop at test.c:6
0x1efa: movl $12, %eax
0x1eff: addl $20, %esp
0x1f02: popl %ebx
0x1f03: leave
0x1f04: ret
This can be handy when dealing with the new --line options that was recently
added:
(lldb) disassemble --line
a.out`main + 13 at test.c:19
18 {
-> 19 printf("Process: %i\n\n", getpid());
20 puts("Press any key to continue..."); getchar();
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
Modified the ModuleList to have a lookup based solely on a UUID. Since the
UUID is typically the MD5 checksum of a binary image, there is no need
to give the path and architecture when searching for a pre-existing
image in an image list.
Now that we support remote debugging a bit better, our lldb_private::Module
needs to be able to track what the original path for file was as the platform
knows it, as well as where the file is locally. The module has the two
following functions to retrieve both paths:
const FileSpec &Module::GetFileSpec () const;
const FileSpec &Module::GetPlatformFileSpec () const;
llvm-svn: 128563
2011-03-31 02:16:51 +08:00
m_stop_hooks ( ) ,
2011-05-12 10:06:14 +08:00
m_stop_hook_next_id ( 0 ) ,
m_suppress_stop_hooks ( false )
2010-06-09 00:52:24 +08:00
{
2010-10-31 11:01:06 +08:00
SetEventName ( eBroadcastBitBreakpointChanged , " breakpoint-changed " ) ;
SetEventName ( eBroadcastBitModulesLoaded , " modules-loaded " ) ;
SetEventName ( eBroadcastBitModulesUnloaded , " modules-unloaded " ) ;
2012-02-16 14:50:00 +08:00
CheckInWithManager ( ) ;
2010-10-31 11:01:06 +08:00
2010-11-06 09:53:30 +08:00
LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_OBJECT ) ) ;
2010-06-09 00:52:24 +08:00
if ( log )
log - > Printf ( " %p Target::Target() " , this ) ;
}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
Target : : ~ Target ( )
{
2010-11-06 09:53:30 +08:00
LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_OBJECT ) ) ;
2010-06-09 00:52:24 +08:00
if ( log )
log - > Printf ( " %p Target::~Target() " , this ) ;
DeleteCurrentProcess ( ) ;
}
void
2010-10-26 11:11:13 +08:00
Target : : Dump ( Stream * s , lldb : : DescriptionLevel description_level )
2010-06-09 00:52:24 +08:00
{
2010-10-08 08:21:05 +08:00
// s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
2010-10-26 11:11:13 +08:00
if ( description_level ! = lldb : : eDescriptionLevelBrief )
{
s - > Indent ( ) ;
s - > PutCString ( " Target \n " ) ;
s - > IndentMore ( ) ;
2010-10-29 12:59:35 +08:00
m_images . Dump ( s ) ;
m_breakpoint_list . Dump ( s ) ;
m_internal_breakpoint_list . Dump ( s ) ;
s - > IndentLess ( ) ;
2010-10-26 11:11:13 +08:00
}
else
{
2011-08-11 10:48:45 +08:00
Module * exe_module = GetExecutableModulePointer ( ) ;
if ( exe_module )
s - > PutCString ( exe_module - > GetFileSpec ( ) . GetFilename ( ) . GetCString ( ) ) ;
2011-05-12 09:12:28 +08:00
else
s - > PutCString ( " No executable module. " ) ;
2010-10-26 11:11:13 +08:00
}
2010-06-09 00:52:24 +08:00
}
void
Target : : DeleteCurrentProcess ( )
{
if ( m_process_sp . get ( ) )
{
2010-09-15 07:52:43 +08:00
m_section_load_list . Clear ( ) ;
2010-06-09 00:52:24 +08:00
if ( m_process_sp - > IsAlive ( ) )
m_process_sp - > Destroy ( ) ;
2011-02-17 01:54:55 +08:00
m_process_sp - > Finalize ( ) ;
2010-06-09 00:52:24 +08:00
// Do any cleanup of the target we need to do between process instances.
// NB It is better to do this before destroying the process in case the
// clean up needs some help from the process.
m_breakpoint_list . ClearAllBreakpointSites ( ) ;
m_internal_breakpoint_list . ClearAllBreakpointSites ( ) ;
2011-10-14 08:42:25 +08:00
// Disable watchpoints just on the debugger side.
2012-02-25 14:44:30 +08:00
Mutex : : Locker locker ;
this - > GetWatchpointList ( ) . GetListMutex ( locker ) ;
2011-10-14 08:42:25 +08:00
DisableAllWatchpoints ( false ) ;
2012-02-25 14:44:30 +08:00
ClearAllWatchpointHitCounts ( ) ;
2010-06-09 00:52:24 +08:00
m_process_sp . reset ( ) ;
}
}
const lldb : : ProcessSP &
2012-02-09 14:16:32 +08:00
Target : : CreateProcess ( Listener & listener , const char * plugin_name , const FileSpec * crash_file )
2010-06-09 00:52:24 +08:00
{
DeleteCurrentProcess ( ) ;
2012-02-09 14:16:32 +08:00
m_process_sp = Process : : FindPlugin ( * this , plugin_name , listener , crash_file ) ;
2010-06-09 00:52:24 +08:00
return m_process_sp ;
}
const lldb : : ProcessSP &
Target : : GetProcessSP ( ) const
{
return m_process_sp ;
}
2011-08-10 10:10:13 +08:00
void
Target : : Destroy ( )
{
Mutex : : Locker locker ( m_mutex ) ;
DeleteCurrentProcess ( ) ;
m_platform_sp . reset ( ) ;
m_arch . Clear ( ) ;
m_images . Clear ( ) ;
m_section_load_list . Clear ( ) ;
const bool notify = false ;
m_breakpoint_list . RemoveAll ( notify ) ;
m_internal_breakpoint_list . RemoveAll ( notify ) ;
m_last_created_breakpoint . reset ( ) ;
2011-10-14 08:42:25 +08:00
m_last_created_watchpoint . reset ( ) ;
2011-08-10 10:10:13 +08:00
m_search_filter_sp . reset ( ) ;
m_image_search_paths . Clear ( notify ) ;
m_scratch_ast_context_ap . reset ( ) ;
2011-11-16 06:27:19 +08:00
m_scratch_ast_source_ap . reset ( ) ;
2011-11-17 02:20:47 +08:00
m_ast_importer_ap . reset ( ) ;
2011-08-10 10:10:13 +08:00
m_persistent_variables . Clear ( ) ;
m_stop_hooks . clear ( ) ;
m_stop_hook_next_id = 0 ;
m_suppress_stop_hooks = false ;
}
2010-06-09 00:52:24 +08:00
BreakpointList &
Target : : GetBreakpointList ( bool internal )
{
if ( internal )
return m_internal_breakpoint_list ;
else
return m_breakpoint_list ;
}
const BreakpointList &
Target : : GetBreakpointList ( bool internal ) const
{
if ( internal )
return m_internal_breakpoint_list ;
else
return m_breakpoint_list ;
}
BreakpointSP
Target : : GetBreakpointByID ( break_id_t break_id )
{
BreakpointSP bp_sp ;
if ( LLDB_BREAK_ID_IS_INTERNAL ( break_id ) )
bp_sp = m_internal_breakpoint_list . FindBreakpointByID ( break_id ) ;
else
bp_sp = m_breakpoint_list . FindBreakpointByID ( break_id ) ;
return bp_sp ;
}
BreakpointSP
2011-09-23 08:54:11 +08:00
Target : : CreateSourceRegexBreakpoint ( const FileSpecList * containingModules ,
const FileSpecList * source_file_spec_list ,
2011-09-21 09:17:13 +08:00
RegularExpression & source_regex ,
bool internal )
2010-06-09 00:52:24 +08:00
{
2011-09-23 08:54:11 +08:00
SearchFilterSP filter_sp ( GetSearchFilterForModuleAndCUList ( containingModules , source_file_spec_list ) ) ;
BreakpointResolverSP resolver_sp ( new BreakpointResolverFileRegex ( NULL , source_regex ) ) ;
2011-09-21 09:17:13 +08:00
return CreateBreakpoint ( filter_sp , resolver_sp , internal ) ;
}
BreakpointSP
Target : : CreateBreakpoint ( const FileSpecList * containingModules , const FileSpec & file , uint32_t line_no , bool check_inlines , bool internal )
{
SearchFilterSP filter_sp ( GetSearchFilterForModuleList ( containingModules ) ) ;
2010-06-09 00:52:24 +08:00
BreakpointResolverSP resolver_sp ( new BreakpointResolverFileLine ( NULL , file , line_no , check_inlines ) ) ;
return CreateBreakpoint ( filter_sp , resolver_sp , internal ) ;
}
BreakpointSP
Added support for inlined stack frames being represented as real stack frames
which is now on by default. Frames are gotten from the unwinder as concrete
frames, then if inline frames are to be shown, extra information to track
and reconstruct these frames is cached with each Thread and exanded as needed.
I added an inline height as part of the lldb_private::StackID class, the class
that helps us uniquely identify stack frames. This allows for two frames to
shared the same call frame address, yet differ only in inline height.
Fixed setting breakpoint by address to not require addresses to resolve.
A quick example:
% cat main.cpp
% ./build/Debug/lldb test/stl/a.out
Current executable set to 'test/stl/a.out' (x86_64).
(lldb) breakpoint set --address 0x0000000100000d31
Breakpoint created: 1: address = 0x0000000100000d31, locations = 1
(lldb) r
Launching 'a.out' (x86_64)
(lldb) Process 38031 Stopped
* thread #1: tid = 0x2e03, pc = 0x0000000100000d31, where = a.out`main [inlined] std::string::_M_data() const at /usr/include/c++/4.2.1/bits/basic_string.h:280, stop reason = breakpoint 1.1, queue = com.apple.main-thread
277
278 _CharT*
279 _M_data() const
280 -> { return _M_dataplus._M_p; }
281
282 _CharT*
283 _M_data(_CharT* __p)
(lldb) bt
thread #1: tid = 0x2e03, stop reason = breakpoint 1.1, queue = com.apple.main-thread
frame #0: pc = 0x0000000100000d31, where = a.out`main [inlined] std::string::_M_data() const at /usr/include/c++/4.2.1/bits/basic_string.h:280
frame #1: pc = 0x0000000100000d31, where = a.out`main [inlined] std::string::_M_rep() const at /usr/include/c++/4.2.1/bits/basic_string.h:288
frame #2: pc = 0x0000000100000d31, where = a.out`main [inlined] std::string::size() const at /usr/include/c++/4.2.1/bits/basic_string.h:606
frame #3: pc = 0x0000000100000d31, where = a.out`main [inlined] operator<< <char, std::char_traits<char>, std::allocator<char> > at /usr/include/c++/4.2.1/bits/basic_string.h:2414
frame #4: pc = 0x0000000100000d31, where = a.out`main + 33 at /Volumes/work/gclayton/Documents/src/lldb/test/stl/main.cpp:14
frame #5: pc = 0x0000000100000d08, where = a.out`start + 52
Each inline frame contains only the variables that they contain and each inlined
stack frame is treated as a single entity.
llvm-svn: 111877
2010-08-24 08:45:41 +08:00
Target : : CreateBreakpoint ( lldb : : addr_t addr , bool internal )
2010-06-09 00:52:24 +08:00
{
Address so_addr ;
// Attempt to resolve our load address if possible, though it is ok if
// it doesn't resolve to section/offset.
Added support for inlined stack frames being represented as real stack frames
which is now on by default. Frames are gotten from the unwinder as concrete
frames, then if inline frames are to be shown, extra information to track
and reconstruct these frames is cached with each Thread and exanded as needed.
I added an inline height as part of the lldb_private::StackID class, the class
that helps us uniquely identify stack frames. This allows for two frames to
shared the same call frame address, yet differ only in inline height.
Fixed setting breakpoint by address to not require addresses to resolve.
A quick example:
% cat main.cpp
% ./build/Debug/lldb test/stl/a.out
Current executable set to 'test/stl/a.out' (x86_64).
(lldb) breakpoint set --address 0x0000000100000d31
Breakpoint created: 1: address = 0x0000000100000d31, locations = 1
(lldb) r
Launching 'a.out' (x86_64)
(lldb) Process 38031 Stopped
* thread #1: tid = 0x2e03, pc = 0x0000000100000d31, where = a.out`main [inlined] std::string::_M_data() const at /usr/include/c++/4.2.1/bits/basic_string.h:280, stop reason = breakpoint 1.1, queue = com.apple.main-thread
277
278 _CharT*
279 _M_data() const
280 -> { return _M_dataplus._M_p; }
281
282 _CharT*
283 _M_data(_CharT* __p)
(lldb) bt
thread #1: tid = 0x2e03, stop reason = breakpoint 1.1, queue = com.apple.main-thread
frame #0: pc = 0x0000000100000d31, where = a.out`main [inlined] std::string::_M_data() const at /usr/include/c++/4.2.1/bits/basic_string.h:280
frame #1: pc = 0x0000000100000d31, where = a.out`main [inlined] std::string::_M_rep() const at /usr/include/c++/4.2.1/bits/basic_string.h:288
frame #2: pc = 0x0000000100000d31, where = a.out`main [inlined] std::string::size() const at /usr/include/c++/4.2.1/bits/basic_string.h:606
frame #3: pc = 0x0000000100000d31, where = a.out`main [inlined] operator<< <char, std::char_traits<char>, std::allocator<char> > at /usr/include/c++/4.2.1/bits/basic_string.h:2414
frame #4: pc = 0x0000000100000d31, where = a.out`main + 33 at /Volumes/work/gclayton/Documents/src/lldb/test/stl/main.cpp:14
frame #5: pc = 0x0000000100000d08, where = a.out`start + 52
Each inline frame contains only the variables that they contain and each inlined
stack frame is treated as a single entity.
llvm-svn: 111877
2010-08-24 08:45:41 +08:00
// Try and resolve as a load address if possible
2010-09-15 07:36:40 +08:00
m_section_load_list . ResolveLoadAddress ( addr , so_addr ) ;
Added support for inlined stack frames being represented as real stack frames
which is now on by default. Frames are gotten from the unwinder as concrete
frames, then if inline frames are to be shown, extra information to track
and reconstruct these frames is cached with each Thread and exanded as needed.
I added an inline height as part of the lldb_private::StackID class, the class
that helps us uniquely identify stack frames. This allows for two frames to
shared the same call frame address, yet differ only in inline height.
Fixed setting breakpoint by address to not require addresses to resolve.
A quick example:
% cat main.cpp
% ./build/Debug/lldb test/stl/a.out
Current executable set to 'test/stl/a.out' (x86_64).
(lldb) breakpoint set --address 0x0000000100000d31
Breakpoint created: 1: address = 0x0000000100000d31, locations = 1
(lldb) r
Launching 'a.out' (x86_64)
(lldb) Process 38031 Stopped
* thread #1: tid = 0x2e03, pc = 0x0000000100000d31, where = a.out`main [inlined] std::string::_M_data() const at /usr/include/c++/4.2.1/bits/basic_string.h:280, stop reason = breakpoint 1.1, queue = com.apple.main-thread
277
278 _CharT*
279 _M_data() const
280 -> { return _M_dataplus._M_p; }
281
282 _CharT*
283 _M_data(_CharT* __p)
(lldb) bt
thread #1: tid = 0x2e03, stop reason = breakpoint 1.1, queue = com.apple.main-thread
frame #0: pc = 0x0000000100000d31, where = a.out`main [inlined] std::string::_M_data() const at /usr/include/c++/4.2.1/bits/basic_string.h:280
frame #1: pc = 0x0000000100000d31, where = a.out`main [inlined] std::string::_M_rep() const at /usr/include/c++/4.2.1/bits/basic_string.h:288
frame #2: pc = 0x0000000100000d31, where = a.out`main [inlined] std::string::size() const at /usr/include/c++/4.2.1/bits/basic_string.h:606
frame #3: pc = 0x0000000100000d31, where = a.out`main [inlined] operator<< <char, std::char_traits<char>, std::allocator<char> > at /usr/include/c++/4.2.1/bits/basic_string.h:2414
frame #4: pc = 0x0000000100000d31, where = a.out`main + 33 at /Volumes/work/gclayton/Documents/src/lldb/test/stl/main.cpp:14
frame #5: pc = 0x0000000100000d08, where = a.out`start + 52
Each inline frame contains only the variables that they contain and each inlined
stack frame is treated as a single entity.
llvm-svn: 111877
2010-08-24 08:45:41 +08:00
if ( ! so_addr . IsValid ( ) )
{
// The address didn't resolve, so just set this as an absolute address
so_addr . SetOffset ( addr ) ;
}
BreakpointSP bp_sp ( CreateBreakpoint ( so_addr , internal ) ) ;
2010-06-09 00:52:24 +08:00
return bp_sp ;
}
BreakpointSP
Target : : CreateBreakpoint ( Address & addr , bool internal )
{
2012-01-30 04:56:30 +08:00
SearchFilterSP filter_sp ( new SearchFilterForNonModuleSpecificSearches ( shared_from_this ( ) ) ) ;
2010-06-09 00:52:24 +08:00
BreakpointResolverSP resolver_sp ( new BreakpointResolverAddress ( NULL , addr ) ) ;
return CreateBreakpoint ( filter_sp , resolver_sp , internal ) ;
}
BreakpointSP
2011-09-23 08:54:11 +08:00
Target : : CreateBreakpoint ( const FileSpecList * containingModules ,
const FileSpecList * containingSourceFiles ,
2011-07-13 01:06:17 +08:00
const char * func_name ,
uint32_t func_name_type_mask ,
bool internal ,
LazyBool skip_prologue )
2010-06-09 00:52:24 +08:00
{
2010-06-29 05:30:43 +08:00
BreakpointSP bp_sp ;
if ( func_name )
{
2011-09-23 08:54:11 +08:00
SearchFilterSP filter_sp ( GetSearchFilterForModuleAndCUList ( containingModules , containingSourceFiles ) ) ;
2011-07-13 01:06:17 +08:00
BreakpointResolverSP resolver_sp ( new BreakpointResolverName ( NULL ,
func_name ,
func_name_type_mask ,
Breakpoint : : Exact ,
skip_prologue = = eLazyBoolCalculate ? GetSkipPrologue ( ) : skip_prologue ) ) ;
2010-06-29 05:30:43 +08:00
bp_sp = CreateBreakpoint ( filter_sp , resolver_sp , internal ) ;
}
return bp_sp ;
2010-06-09 00:52:24 +08:00
}
SearchFilterSP
Target : : GetSearchFilterForModule ( const FileSpec * containingModule )
{
SearchFilterSP filter_sp ;
if ( containingModule ! = NULL )
{
// TODO: We should look into sharing module based search filters
// across many breakpoints like we do for the simple target based one
2012-01-30 04:56:30 +08:00
filter_sp . reset ( new SearchFilterByModule ( shared_from_this ( ) , * containingModule ) ) ;
2010-06-09 00:52:24 +08:00
}
else
{
if ( m_search_filter_sp . get ( ) = = NULL )
2012-01-30 04:56:30 +08:00
m_search_filter_sp . reset ( new SearchFilterForNonModuleSpecificSearches ( shared_from_this ( ) ) ) ;
2010-06-09 00:52:24 +08:00
filter_sp = m_search_filter_sp ;
}
return filter_sp ;
}
2011-09-21 09:17:13 +08:00
SearchFilterSP
Target : : GetSearchFilterForModuleList ( const FileSpecList * containingModules )
{
SearchFilterSP filter_sp ;
if ( containingModules & & containingModules - > GetSize ( ) ! = 0 )
{
// TODO: We should look into sharing module based search filters
// across many breakpoints like we do for the simple target based one
2012-01-30 04:56:30 +08:00
filter_sp . reset ( new SearchFilterByModuleList ( shared_from_this ( ) , * containingModules ) ) ;
2011-09-21 09:17:13 +08:00
}
else
{
if ( m_search_filter_sp . get ( ) = = NULL )
2012-01-30 04:56:30 +08:00
m_search_filter_sp . reset ( new SearchFilterForNonModuleSpecificSearches ( shared_from_this ( ) ) ) ;
2011-09-21 09:17:13 +08:00
filter_sp = m_search_filter_sp ;
}
return filter_sp ;
}
2011-09-23 08:54:11 +08:00
SearchFilterSP
Target : : GetSearchFilterForModuleAndCUList ( const FileSpecList * containingModules , const FileSpecList * containingSourceFiles )
{
if ( containingSourceFiles = = NULL | | containingSourceFiles - > GetSize ( ) = = 0 )
return GetSearchFilterForModuleList ( containingModules ) ;
SearchFilterSP filter_sp ;
if ( containingModules = = NULL )
{
// We could make a special "CU List only SearchFilter". Better yet was if these could be composable,
// but that will take a little reworking.
2012-01-30 04:56:30 +08:00
filter_sp . reset ( new SearchFilterByModuleListAndCU ( shared_from_this ( ) , FileSpecList ( ) , * containingSourceFiles ) ) ;
2011-09-23 08:54:11 +08:00
}
else
{
2012-01-30 04:56:30 +08:00
filter_sp . reset ( new SearchFilterByModuleListAndCU ( shared_from_this ( ) , * containingModules , * containingSourceFiles ) ) ;
2011-09-23 08:54:11 +08:00
}
return filter_sp ;
}
2010-06-09 00:52:24 +08:00
BreakpointSP
2011-09-23 08:54:11 +08:00
Target : : CreateFuncRegexBreakpoint ( const FileSpecList * containingModules ,
const FileSpecList * containingSourceFiles ,
2011-07-13 01:06:17 +08:00
RegularExpression & func_regex ,
bool internal ,
LazyBool skip_prologue )
2010-06-09 00:52:24 +08:00
{
2011-09-23 08:54:11 +08:00
SearchFilterSP filter_sp ( GetSearchFilterForModuleAndCUList ( containingModules , containingSourceFiles ) ) ;
2011-07-13 01:06:17 +08:00
BreakpointResolverSP resolver_sp ( new BreakpointResolverName ( NULL ,
func_regex ,
skip_prologue = = eLazyBoolCalculate ? GetSkipPrologue ( ) : skip_prologue ) ) ;
2010-06-09 00:52:24 +08:00
return CreateBreakpoint ( filter_sp , resolver_sp , internal ) ;
}
BreakpointSP
Target : : CreateBreakpoint ( SearchFilterSP & filter_sp , BreakpointResolverSP & resolver_sp , bool internal )
{
BreakpointSP bp_sp ;
if ( filter_sp & & resolver_sp )
{
bp_sp . reset ( new Breakpoint ( * this , filter_sp , resolver_sp ) ) ;
resolver_sp - > SetBreakpoint ( bp_sp . get ( ) ) ;
if ( internal )
2010-07-24 07:33:17 +08:00
m_internal_breakpoint_list . Add ( bp_sp , false ) ;
2010-06-09 00:52:24 +08:00
else
2010-07-24 07:33:17 +08:00
m_breakpoint_list . Add ( bp_sp , true ) ;
2010-06-09 00:52:24 +08:00
2010-11-06 09:53:30 +08:00
LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_BREAKPOINTS ) ) ;
2010-06-09 00:52:24 +08:00
if ( log )
{
StreamString s ;
bp_sp - > GetDescription ( & s , lldb : : eDescriptionLevelVerbose ) ;
log - > Printf ( " Target::%s (internal = %s) => break_id = %s \n " , __FUNCTION__ , internal ? " yes " : " no " , s . GetData ( ) ) ;
}
bp_sp - > ResolveBreakpoint ( ) ;
}
2010-10-15 07:45:03 +08:00
if ( ! internal & & bp_sp )
{
m_last_created_breakpoint = bp_sp ;
}
2010-06-09 00:52:24 +08:00
return bp_sp ;
}
2011-09-21 07:28:55 +08:00
bool
Target : : ProcessIsValid ( )
{
return ( m_process_sp & & m_process_sp - > IsAlive ( ) ) ;
}
2011-10-14 08:42:25 +08:00
// See also Watchpoint::SetWatchpointType(uint32_t type) and
2011-09-14 08:26:03 +08:00
// the OptionGroupWatchpoint::WatchType enum type.
2011-10-14 08:42:25 +08:00
WatchpointSP
Target : : CreateWatchpoint ( lldb : : addr_t addr , size_t size , uint32_t type )
2011-09-13 07:38:44 +08:00
{
2011-09-15 04:23:45 +08:00
LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_WATCHPOINTS ) ) ;
if ( log )
log - > Printf ( " Target::%s (addr = 0x%8.8llx size = %zu type = %u) \n " ,
__FUNCTION__ , addr , size , type ) ;
2011-10-14 08:42:25 +08:00
WatchpointSP wp_sp ;
2011-09-21 07:28:55 +08:00
if ( ! ProcessIsValid ( ) )
2011-10-14 08:42:25 +08:00
return wp_sp ;
2011-09-15 06:20:15 +08:00
if ( addr = = LLDB_INVALID_ADDRESS | | size = = 0 )
2011-10-14 08:42:25 +08:00
return wp_sp ;
2011-09-13 09:15:36 +08:00
2011-10-14 08:42:25 +08:00
// Currently we only support one watchpoint per address, with total number
// of watchpoints limited by the hardware which the inferior is running on.
WatchpointSP matched_sp = m_watchpoint_list . FindByAddress ( addr ) ;
2011-09-14 07:29:31 +08:00
if ( matched_sp )
{
2011-09-15 04:23:45 +08:00
size_t old_size = matched_sp - > GetByteSize ( ) ;
2011-09-14 07:29:31 +08:00
uint32_t old_type =
2011-09-15 04:23:45 +08:00
( matched_sp - > WatchpointRead ( ) ? LLDB_WATCH_TYPE_READ : 0 ) |
( matched_sp - > WatchpointWrite ( ) ? LLDB_WATCH_TYPE_WRITE : 0 ) ;
2011-10-14 08:42:25 +08:00
// Return the existing watchpoint if both size and type match.
2011-09-15 06:20:15 +08:00
if ( size = = old_size & & type = = old_type ) {
2011-10-14 08:42:25 +08:00
wp_sp = matched_sp ;
wp_sp - > SetEnabled ( false ) ;
2011-09-15 06:20:15 +08:00
} else {
2011-10-14 08:42:25 +08:00
// Nil the matched watchpoint; we will be creating a new one.
2011-09-15 06:20:15 +08:00
m_process_sp - > DisableWatchpoint ( matched_sp . get ( ) ) ;
2011-10-14 08:42:25 +08:00
m_watchpoint_list . Remove ( matched_sp - > GetID ( ) ) ;
2011-09-15 06:20:15 +08:00
}
2011-09-14 07:29:31 +08:00
}
2011-10-14 08:42:25 +08:00
if ( ! wp_sp ) {
Watchpoint * new_wp = new Watchpoint ( addr , size ) ;
if ( ! new_wp ) {
printf ( " Watchpoint ctor failed, out of memory? \n " ) ;
return wp_sp ;
2011-09-15 06:20:15 +08:00
}
2011-10-14 08:42:25 +08:00
new_wp - > SetWatchpointType ( type ) ;
new_wp - > SetTarget ( this ) ;
wp_sp . reset ( new_wp ) ;
m_watchpoint_list . Add ( wp_sp ) ;
2011-09-15 06:20:15 +08:00
}
2011-09-15 04:23:45 +08:00
2011-10-14 08:42:25 +08:00
Error rc = m_process_sp - > EnableWatchpoint ( wp_sp . get ( ) ) ;
2011-09-15 04:23:45 +08:00
if ( log )
log - > Printf ( " Target::%s (creation of watchpoint %s with id = %u) \n " ,
__FUNCTION__ ,
rc . Success ( ) ? " succeeded " : " failed " ,
2011-10-14 08:42:25 +08:00
wp_sp - > GetID ( ) ) ;
2011-09-15 04:23:45 +08:00
2011-09-28 04:29:45 +08:00
if ( rc . Fail ( ) )
2011-10-14 08:42:25 +08:00
wp_sp . reset ( ) ;
2011-09-28 04:29:45 +08:00
else
2011-10-14 08:42:25 +08:00
m_last_created_watchpoint = wp_sp ;
return wp_sp ;
2011-09-13 07:38:44 +08:00
}
2010-06-09 00:52:24 +08:00
void
Target : : RemoveAllBreakpoints ( bool internal_also )
{
2010-11-06 09:53:30 +08:00
LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_BREAKPOINTS ) ) ;
2010-06-09 00:52:24 +08:00
if ( log )
log - > Printf ( " Target::%s (internal_also = %s) \n " , __FUNCTION__ , internal_also ? " yes " : " no " ) ;
2010-07-24 07:33:17 +08:00
m_breakpoint_list . RemoveAll ( true ) ;
2010-06-09 00:52:24 +08:00
if ( internal_also )
2010-07-24 07:33:17 +08:00
m_internal_breakpoint_list . RemoveAll ( false ) ;
2010-10-15 07:45:03 +08:00
m_last_created_breakpoint . reset ( ) ;
2010-06-09 00:52:24 +08:00
}
void
Target : : DisableAllBreakpoints ( bool internal_also )
{
2010-11-06 09:53:30 +08:00
LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_BREAKPOINTS ) ) ;
2010-06-09 00:52:24 +08:00
if ( log )
log - > Printf ( " Target::%s (internal_also = %s) \n " , __FUNCTION__ , internal_also ? " yes " : " no " ) ;
m_breakpoint_list . SetEnabledAll ( false ) ;
if ( internal_also )
m_internal_breakpoint_list . SetEnabledAll ( false ) ;
}
void
Target : : EnableAllBreakpoints ( bool internal_also )
{
2010-11-06 09:53:30 +08:00
LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_BREAKPOINTS ) ) ;
2010-06-09 00:52:24 +08:00
if ( log )
log - > Printf ( " Target::%s (internal_also = %s) \n " , __FUNCTION__ , internal_also ? " yes " : " no " ) ;
m_breakpoint_list . SetEnabledAll ( true ) ;
if ( internal_also )
m_internal_breakpoint_list . SetEnabledAll ( true ) ;
}
bool
Target : : RemoveBreakpointByID ( break_id_t break_id )
{
2010-11-06 09:53:30 +08:00
LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_BREAKPOINTS ) ) ;
2010-06-09 00:52:24 +08:00
if ( log )
log - > Printf ( " Target::%s (break_id = %i, internal = %s) \n " , __FUNCTION__ , break_id , LLDB_BREAK_ID_IS_INTERNAL ( break_id ) ? " yes " : " no " ) ;
if ( DisableBreakpointByID ( break_id ) )
{
if ( LLDB_BREAK_ID_IS_INTERNAL ( break_id ) )
2010-07-24 07:33:17 +08:00
m_internal_breakpoint_list . Remove ( break_id , false ) ;
2010-06-09 00:52:24 +08:00
else
2010-10-15 07:45:03 +08:00
{
2011-01-25 07:35:47 +08:00
if ( m_last_created_breakpoint )
{
if ( m_last_created_breakpoint - > GetID ( ) = = break_id )
m_last_created_breakpoint . reset ( ) ;
}
2010-07-24 07:33:17 +08:00
m_breakpoint_list . Remove ( break_id , true ) ;
2010-10-15 07:45:03 +08:00
}
2010-06-09 00:52:24 +08:00
return true ;
}
return false ;
}
bool
Target : : DisableBreakpointByID ( break_id_t break_id )
{
2010-11-06 09:53:30 +08:00
LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_BREAKPOINTS ) ) ;
2010-06-09 00:52:24 +08:00
if ( log )
log - > Printf ( " Target::%s (break_id = %i, internal = %s) \n " , __FUNCTION__ , break_id , LLDB_BREAK_ID_IS_INTERNAL ( break_id ) ? " yes " : " no " ) ;
BreakpointSP bp_sp ;
if ( LLDB_BREAK_ID_IS_INTERNAL ( break_id ) )
bp_sp = m_internal_breakpoint_list . FindBreakpointByID ( break_id ) ;
else
bp_sp = m_breakpoint_list . FindBreakpointByID ( break_id ) ;
if ( bp_sp )
{
bp_sp - > SetEnabled ( false ) ;
return true ;
}
return false ;
}
bool
Target : : EnableBreakpointByID ( break_id_t break_id )
{
2010-11-06 09:53:30 +08:00
LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_BREAKPOINTS ) ) ;
2010-06-09 00:52:24 +08:00
if ( log )
log - > Printf ( " Target::%s (break_id = %i, internal = %s) \n " ,
__FUNCTION__ ,
break_id ,
LLDB_BREAK_ID_IS_INTERNAL ( break_id ) ? " yes " : " no " ) ;
BreakpointSP bp_sp ;
if ( LLDB_BREAK_ID_IS_INTERNAL ( break_id ) )
bp_sp = m_internal_breakpoint_list . FindBreakpointByID ( break_id ) ;
else
bp_sp = m_breakpoint_list . FindBreakpointByID ( break_id ) ;
if ( bp_sp )
{
bp_sp - > SetEnabled ( true ) ;
return true ;
}
return false ;
}
2011-09-24 05:21:43 +08:00
// The flag 'end_to_end', default to true, signifies that the operation is
// performed end to end, for both the debugger and the debuggee.
2011-10-14 08:42:25 +08:00
// Assumption: Caller holds the list mutex lock for m_watchpoint_list for end
// to end operations.
2011-09-21 07:28:55 +08:00
bool
2011-10-14 08:42:25 +08:00
Target : : RemoveAllWatchpoints ( bool end_to_end )
2011-09-21 07:28:55 +08:00
{
LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_WATCHPOINTS ) ) ;
if ( log )
log - > Printf ( " Target::%s \n " , __FUNCTION__ ) ;
2011-09-24 05:21:43 +08:00
if ( ! end_to_end ) {
2011-10-14 08:42:25 +08:00
m_watchpoint_list . RemoveAll ( ) ;
2011-09-24 05:21:43 +08:00
return true ;
}
// Otherwise, it's an end to end operation.
2011-09-21 07:28:55 +08:00
if ( ! ProcessIsValid ( ) )
return false ;
2011-10-14 08:42:25 +08:00
size_t num_watchpoints = m_watchpoint_list . GetSize ( ) ;
2011-09-21 07:28:55 +08:00
for ( size_t i = 0 ; i < num_watchpoints ; + + i )
{
2011-10-14 08:42:25 +08:00
WatchpointSP wp_sp = m_watchpoint_list . GetByIndex ( i ) ;
if ( ! wp_sp )
2011-09-21 07:28:55 +08:00
return false ;
2011-10-14 08:42:25 +08:00
Error rc = m_process_sp - > DisableWatchpoint ( wp_sp . get ( ) ) ;
2011-09-21 07:28:55 +08:00
if ( rc . Fail ( ) )
return false ;
}
2011-10-14 08:42:25 +08:00
m_watchpoint_list . RemoveAll ( ) ;
2011-09-21 07:28:55 +08:00
return true ; // Success!
}
2011-10-14 08:42:25 +08:00
// Assumption: Caller holds the list mutex lock for m_watchpoint_list for end to
// end operations.
2011-09-21 07:28:55 +08:00
bool
2011-10-14 08:42:25 +08:00
Target : : DisableAllWatchpoints ( bool end_to_end )
2011-09-21 07:28:55 +08:00
{
LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_WATCHPOINTS ) ) ;
if ( log )
log - > Printf ( " Target::%s \n " , __FUNCTION__ ) ;
2011-09-24 05:21:43 +08:00
if ( ! end_to_end ) {
2011-10-14 08:42:25 +08:00
m_watchpoint_list . SetEnabledAll ( false ) ;
2011-09-24 05:21:43 +08:00
return true ;
}
// Otherwise, it's an end to end operation.
2011-09-21 07:28:55 +08:00
if ( ! ProcessIsValid ( ) )
return false ;
2011-10-14 08:42:25 +08:00
size_t num_watchpoints = m_watchpoint_list . GetSize ( ) ;
2011-09-21 07:28:55 +08:00
for ( size_t i = 0 ; i < num_watchpoints ; + + i )
{
2011-10-14 08:42:25 +08:00
WatchpointSP wp_sp = m_watchpoint_list . GetByIndex ( i ) ;
if ( ! wp_sp )
2011-09-21 07:28:55 +08:00
return false ;
2011-10-14 08:42:25 +08:00
Error rc = m_process_sp - > DisableWatchpoint ( wp_sp . get ( ) ) ;
2011-09-21 07:28:55 +08:00
if ( rc . Fail ( ) )
return false ;
}
return true ; // Success!
}
2011-10-14 08:42:25 +08:00
// Assumption: Caller holds the list mutex lock for m_watchpoint_list for end to
// end operations.
2011-09-21 07:28:55 +08:00
bool
2011-10-14 08:42:25 +08:00
Target : : EnableAllWatchpoints ( bool end_to_end )
2011-09-21 07:28:55 +08:00
{
LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_WATCHPOINTS ) ) ;
if ( log )
log - > Printf ( " Target::%s \n " , __FUNCTION__ ) ;
2011-09-24 05:21:43 +08:00
if ( ! end_to_end ) {
2011-10-14 08:42:25 +08:00
m_watchpoint_list . SetEnabledAll ( true ) ;
2011-09-24 05:21:43 +08:00
return true ;
}
// Otherwise, it's an end to end operation.
2011-09-21 07:28:55 +08:00
if ( ! ProcessIsValid ( ) )
return false ;
2011-10-14 08:42:25 +08:00
size_t num_watchpoints = m_watchpoint_list . GetSize ( ) ;
2011-09-21 07:28:55 +08:00
for ( size_t i = 0 ; i < num_watchpoints ; + + i )
{
2011-10-14 08:42:25 +08:00
WatchpointSP wp_sp = m_watchpoint_list . GetByIndex ( i ) ;
if ( ! wp_sp )
2011-09-21 07:28:55 +08:00
return false ;
2011-10-14 08:42:25 +08:00
Error rc = m_process_sp - > EnableWatchpoint ( wp_sp . get ( ) ) ;
2011-09-21 07:28:55 +08:00
if ( rc . Fail ( ) )
return false ;
}
return true ; // Success!
}
2012-02-25 14:44:30 +08:00
// Assumption: Caller holds the list mutex lock for m_watchpoint_list.
bool
Target : : ClearAllWatchpointHitCounts ( )
{
LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_WATCHPOINTS ) ) ;
if ( log )
log - > Printf ( " Target::%s \n " , __FUNCTION__ ) ;
size_t num_watchpoints = m_watchpoint_list . GetSize ( ) ;
for ( size_t i = 0 ; i < num_watchpoints ; + + i )
{
WatchpointSP wp_sp = m_watchpoint_list . GetByIndex ( i ) ;
if ( ! wp_sp )
return false ;
wp_sp - > ResetHitCount ( ) ;
}
return true ; // Success!
}
2011-10-14 08:42:25 +08:00
// Assumption: Caller holds the list mutex lock for m_watchpoint_list
2011-10-06 05:35:46 +08:00
// during these operations.
bool
2011-10-14 08:42:25 +08:00
Target : : IgnoreAllWatchpoints ( uint32_t ignore_count )
2011-10-06 05:35:46 +08:00
{
LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_WATCHPOINTS ) ) ;
if ( log )
log - > Printf ( " Target::%s \n " , __FUNCTION__ ) ;
if ( ! ProcessIsValid ( ) )
return false ;
2011-10-14 08:42:25 +08:00
size_t num_watchpoints = m_watchpoint_list . GetSize ( ) ;
2011-10-06 05:35:46 +08:00
for ( size_t i = 0 ; i < num_watchpoints ; + + i )
{
2011-10-14 08:42:25 +08:00
WatchpointSP wp_sp = m_watchpoint_list . GetByIndex ( i ) ;
if ( ! wp_sp )
2011-10-06 05:35:46 +08:00
return false ;
2011-10-14 08:42:25 +08:00
wp_sp - > SetIgnoreCount ( ignore_count ) ;
2011-10-06 05:35:46 +08:00
}
return true ; // Success!
}
2011-10-14 08:42:25 +08:00
// Assumption: Caller holds the list mutex lock for m_watchpoint_list.
2011-09-21 07:28:55 +08:00
bool
2011-10-14 08:42:25 +08:00
Target : : DisableWatchpointByID ( lldb : : watch_id_t watch_id )
2011-09-21 07:28:55 +08:00
{
LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_WATCHPOINTS ) ) ;
if ( log )
log - > Printf ( " Target::%s (watch_id = %i) \n " , __FUNCTION__ , watch_id ) ;
if ( ! ProcessIsValid ( ) )
return false ;
2011-10-14 08:42:25 +08:00
WatchpointSP wp_sp = m_watchpoint_list . FindByID ( watch_id ) ;
if ( wp_sp )
2011-09-21 07:28:55 +08:00
{
2011-10-14 08:42:25 +08:00
Error rc = m_process_sp - > DisableWatchpoint ( wp_sp . get ( ) ) ;
2011-09-23 02:04:58 +08:00
if ( rc . Success ( ) )
return true ;
2011-09-21 07:28:55 +08:00
2011-09-23 02:04:58 +08:00
// Else, fallthrough.
2011-09-21 07:28:55 +08:00
}
return false ;
}
2011-10-14 08:42:25 +08:00
// Assumption: Caller holds the list mutex lock for m_watchpoint_list.
2011-09-21 07:28:55 +08:00
bool
2011-10-14 08:42:25 +08:00
Target : : EnableWatchpointByID ( lldb : : watch_id_t watch_id )
2011-09-21 07:28:55 +08:00
{
LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_WATCHPOINTS ) ) ;
if ( log )
log - > Printf ( " Target::%s (watch_id = %i) \n " , __FUNCTION__ , watch_id ) ;
if ( ! ProcessIsValid ( ) )
return false ;
2011-10-14 08:42:25 +08:00
WatchpointSP wp_sp = m_watchpoint_list . FindByID ( watch_id ) ;
if ( wp_sp )
2011-09-21 07:28:55 +08:00
{
2011-10-14 08:42:25 +08:00
Error rc = m_process_sp - > EnableWatchpoint ( wp_sp . get ( ) ) ;
2011-09-23 02:04:58 +08:00
if ( rc . Success ( ) )
return true ;
2011-09-21 07:28:55 +08:00
2011-09-23 02:04:58 +08:00
// Else, fallthrough.
2011-09-21 07:28:55 +08:00
}
return false ;
}
2011-10-14 08:42:25 +08:00
// Assumption: Caller holds the list mutex lock for m_watchpoint_list.
2011-09-21 07:28:55 +08:00
bool
2011-10-14 08:42:25 +08:00
Target : : RemoveWatchpointByID ( lldb : : watch_id_t watch_id )
2011-09-21 07:28:55 +08:00
{
LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_WATCHPOINTS ) ) ;
if ( log )
log - > Printf ( " Target::%s (watch_id = %i) \n " , __FUNCTION__ , watch_id ) ;
2011-10-14 08:42:25 +08:00
if ( DisableWatchpointByID ( watch_id ) )
2011-09-21 07:28:55 +08:00
{
2011-10-14 08:42:25 +08:00
m_watchpoint_list . Remove ( watch_id ) ;
2011-09-21 07:28:55 +08:00
return true ;
}
return false ;
}
2011-10-14 08:42:25 +08:00
// Assumption: Caller holds the list mutex lock for m_watchpoint_list.
2011-10-06 05:35:46 +08:00
bool
2011-10-14 08:42:25 +08:00
Target : : IgnoreWatchpointByID ( lldb : : watch_id_t watch_id , uint32_t ignore_count )
2011-10-06 05:35:46 +08:00
{
LogSP log ( lldb_private : : GetLogIfAllCategoriesSet ( LIBLLDB_LOG_WATCHPOINTS ) ) ;
if ( log )
log - > Printf ( " Target::%s (watch_id = %i) \n " , __FUNCTION__ , watch_id ) ;
if ( ! ProcessIsValid ( ) )
return false ;
2011-10-14 08:42:25 +08:00
WatchpointSP wp_sp = m_watchpoint_list . FindByID ( watch_id ) ;
if ( wp_sp )
2011-10-06 05:35:46 +08:00
{
2011-10-14 08:42:25 +08:00
wp_sp - > SetIgnoreCount ( ignore_count ) ;
2011-10-06 05:35:46 +08:00
return true ;
}
return false ;
}
2010-06-09 00:52:24 +08:00
ModuleSP
Target : : GetExecutableModule ( )
{
2011-08-11 10:48:45 +08:00
return m_images . GetModuleAtIndex ( 0 ) ;
}
Module *
Target : : GetExecutableModulePointer ( )
{
return m_images . GetModulePointerAtIndex ( 0 ) ;
2010-06-09 00:52:24 +08:00
}
void
Target : : SetExecutableModule ( ModuleSP & executable_sp , bool get_dependent_files )
{
m_images . Clear ( ) ;
m_scratch_ast_context_ap . reset ( ) ;
2011-11-16 06:27:19 +08:00
m_scratch_ast_source_ap . reset ( ) ;
2011-11-17 02:20:47 +08:00
m_ast_importer_ap . reset ( ) ;
2010-06-09 00:52:24 +08:00
if ( executable_sp . get ( ) )
{
Timer scoped_timer ( __PRETTY_FUNCTION__ ,
" Target::SetExecutableModule (executable = '%s/%s') " ,
executable_sp - > GetFileSpec ( ) . GetDirectory ( ) . AsCString ( ) ,
executable_sp - > GetFileSpec ( ) . GetFilename ( ) . AsCString ( ) ) ;
m_images . Append ( executable_sp ) ; // The first image is our exectuable file
2010-08-10 07:31:02 +08:00
// If we haven't set an architecture yet, reset our architecture based on what we found in the executable module.
Many improvements to the Platform base class and subclasses. The base Platform
class now implements the Host functionality for a lot of things that make
sense by default so that subclasses can check:
int
PlatformSubclass::Foo ()
{
if (IsHost())
return Platform::Foo (); // Let the platform base class do the host specific stuff
// Platform subclass specific code...
int result = ...
return result;
}
Added new functions to the platform:
virtual const char *Platform::GetUserName (uint32_t uid);
virtual const char *Platform::GetGroupName (uint32_t gid);
The user and group names are cached locally so that remote platforms can avoid
sending packets multiple times to resolve this information.
Added the parent process ID to the ProcessInfo class.
Added a new ProcessInfoMatch class which helps us to match processes up
and changed the Host layer over to using this new class. The new class allows
us to search for processs:
1 - by name (equal to, starts with, ends with, contains, and regex)
2 - by pid
3 - And further check for parent pid == value, uid == value, gid == value,
euid == value, egid == value, arch == value, parent == value.
This is all hookup up to the "platform process list" command which required
adding dumping routines to dump process information. If the Host class
implements the process lookup routines, you can now lists processes on
your local machine:
machine1.foo.com % lldb
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
94727 244 username usergroup username usergroup x86_64-apple-darwin Xcode
92742 92710 username usergroup username usergroup i386-apple-darwin debugserver
This of course also works remotely with the lldb-platform:
machine1.foo.com % lldb-platform --listen 1234
machine2.foo.com % lldb
(lldb) platform create remote-macosx
Platform: remote-macosx
Connected: no
(lldb) platform connect connect://localhost:1444
Platform: remote-macosx
Triple: x86_64-apple-darwin
OS Version: 10.6.7 (10J869)
Kernel: Darwin Kernel Version 10.7.0: Sat Jan 29 15:17:16 PST 2011; root:xnu-1504.9.37~1/RELEASE_I386
Hostname: machine1.foo.com
Connected: yes
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99556 244 username usergroup username usergroup x86_64-apple-darwin trustevaluation
99548 65539 username usergroup username usergroup x86_64-apple-darwin lldb
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
The lldb-platform implements everything with the Host:: layer, so this should
"just work" for linux. I will probably be adding more stuff to the Host layer
for launching processes and attaching to processes so that this support should
eventually just work as well.
Modified the target to be able to be created with an architecture that differs
from the main executable. This is needed for iOS debugging since we can have
an "armv6" binary which can run on an "armv7" machine, so we want to be able
to do:
% lldb
(lldb) platform create remote-ios
(lldb) file --arch armv7 a.out
Where "a.out" is an armv6 executable. The platform then can correctly decide
to open all "armv7" images for all dependent shared libraries.
Modified the disassembly to show the current PC value. Example output:
(lldb) disassemble --frame
a.out`main:
0x1eb7: pushl %ebp
0x1eb8: movl %esp, %ebp
0x1eba: pushl %ebx
0x1ebb: subl $20, %esp
0x1ebe: calll 0x1ec3 ; main + 12 at test.c:18
0x1ec3: popl %ebx
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
0x1edb: leal 213(%ebx), %eax
0x1ee1: movl %eax, (%esp)
0x1ee4: calll 0x1f1e ; puts
0x1ee9: calll 0x1f0c ; getchar
0x1eee: movl $20, (%esp)
0x1ef5: calll 0x1e6a ; sleep_loop at test.c:6
0x1efa: movl $12, %eax
0x1eff: addl $20, %esp
0x1f02: popl %ebx
0x1f03: leave
0x1f04: ret
This can be handy when dealing with the new --line options that was recently
added:
(lldb) disassemble --line
a.out`main + 13 at test.c:19
18 {
-> 19 printf("Process: %i\n\n", getpid());
20 puts("Press any key to continue..."); getchar();
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
Modified the ModuleList to have a lookup based solely on a UUID. Since the
UUID is typically the MD5 checksum of a binary image, there is no need
to give the path and architecture when searching for a pre-existing
image in an image list.
Now that we support remote debugging a bit better, our lldb_private::Module
needs to be able to track what the original path for file was as the platform
knows it, as well as where the file is locally. The module has the two
following functions to retrieve both paths:
const FileSpec &Module::GetFileSpec () const;
const FileSpec &Module::GetPlatformFileSpec () const;
llvm-svn: 128563
2011-03-31 02:16:51 +08:00
if ( ! m_arch . IsValid ( ) )
m_arch = executable_sp - > GetArchitecture ( ) ;
2010-08-10 07:31:02 +08:00
2010-06-09 00:52:24 +08:00
FileSpecList dependent_files ;
2011-03-09 06:40:15 +08:00
ObjectFile * executable_objfile = executable_sp - > GetObjectFile ( ) ;
2010-06-09 00:52:24 +08:00
2011-09-24 08:52:29 +08:00
if ( executable_objfile & & get_dependent_files )
2010-06-09 00:52:24 +08:00
{
executable_objfile - > GetDependentModules ( dependent_files ) ;
for ( uint32_t i = 0 ; i < dependent_files . GetSize ( ) ; i + + )
{
2011-03-19 09:12:21 +08:00
FileSpec dependent_file_spec ( dependent_files . GetFileSpecPointerAtIndex ( i ) ) ;
FileSpec platform_dependent_file_spec ;
if ( m_platform_sp )
2011-03-23 08:09:55 +08:00
m_platform_sp - > GetFile ( dependent_file_spec , NULL , platform_dependent_file_spec ) ;
2011-03-19 09:12:21 +08:00
else
platform_dependent_file_spec = dependent_file_spec ;
2012-02-26 13:51:37 +08:00
ModuleSpec module_spec ( platform_dependent_file_spec , m_arch ) ;
ModuleSP image_module_sp ( GetSharedModule ( module_spec ) ) ;
2010-06-09 00:52:24 +08:00
if ( image_module_sp . get ( ) )
{
ObjectFile * objfile = image_module_sp - > GetObjectFile ( ) ;
if ( objfile )
objfile - > GetDependentModules ( dependent_files ) ;
}
}
}
}
2010-09-27 08:30:10 +08:00
UpdateInstanceName ( ) ;
2010-06-09 00:52:24 +08:00
}
2010-08-10 07:31:02 +08:00
bool
Target : : SetArchitecture ( const ArchSpec & arch_spec )
{
Many improvements to the Platform base class and subclasses. The base Platform
class now implements the Host functionality for a lot of things that make
sense by default so that subclasses can check:
int
PlatformSubclass::Foo ()
{
if (IsHost())
return Platform::Foo (); // Let the platform base class do the host specific stuff
// Platform subclass specific code...
int result = ...
return result;
}
Added new functions to the platform:
virtual const char *Platform::GetUserName (uint32_t uid);
virtual const char *Platform::GetGroupName (uint32_t gid);
The user and group names are cached locally so that remote platforms can avoid
sending packets multiple times to resolve this information.
Added the parent process ID to the ProcessInfo class.
Added a new ProcessInfoMatch class which helps us to match processes up
and changed the Host layer over to using this new class. The new class allows
us to search for processs:
1 - by name (equal to, starts with, ends with, contains, and regex)
2 - by pid
3 - And further check for parent pid == value, uid == value, gid == value,
euid == value, egid == value, arch == value, parent == value.
This is all hookup up to the "platform process list" command which required
adding dumping routines to dump process information. If the Host class
implements the process lookup routines, you can now lists processes on
your local machine:
machine1.foo.com % lldb
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
94727 244 username usergroup username usergroup x86_64-apple-darwin Xcode
92742 92710 username usergroup username usergroup i386-apple-darwin debugserver
This of course also works remotely with the lldb-platform:
machine1.foo.com % lldb-platform --listen 1234
machine2.foo.com % lldb
(lldb) platform create remote-macosx
Platform: remote-macosx
Connected: no
(lldb) platform connect connect://localhost:1444
Platform: remote-macosx
Triple: x86_64-apple-darwin
OS Version: 10.6.7 (10J869)
Kernel: Darwin Kernel Version 10.7.0: Sat Jan 29 15:17:16 PST 2011; root:xnu-1504.9.37~1/RELEASE_I386
Hostname: machine1.foo.com
Connected: yes
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99556 244 username usergroup username usergroup x86_64-apple-darwin trustevaluation
99548 65539 username usergroup username usergroup x86_64-apple-darwin lldb
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
The lldb-platform implements everything with the Host:: layer, so this should
"just work" for linux. I will probably be adding more stuff to the Host layer
for launching processes and attaching to processes so that this support should
eventually just work as well.
Modified the target to be able to be created with an architecture that differs
from the main executable. This is needed for iOS debugging since we can have
an "armv6" binary which can run on an "armv7" machine, so we want to be able
to do:
% lldb
(lldb) platform create remote-ios
(lldb) file --arch armv7 a.out
Where "a.out" is an armv6 executable. The platform then can correctly decide
to open all "armv7" images for all dependent shared libraries.
Modified the disassembly to show the current PC value. Example output:
(lldb) disassemble --frame
a.out`main:
0x1eb7: pushl %ebp
0x1eb8: movl %esp, %ebp
0x1eba: pushl %ebx
0x1ebb: subl $20, %esp
0x1ebe: calll 0x1ec3 ; main + 12 at test.c:18
0x1ec3: popl %ebx
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
0x1edb: leal 213(%ebx), %eax
0x1ee1: movl %eax, (%esp)
0x1ee4: calll 0x1f1e ; puts
0x1ee9: calll 0x1f0c ; getchar
0x1eee: movl $20, (%esp)
0x1ef5: calll 0x1e6a ; sleep_loop at test.c:6
0x1efa: movl $12, %eax
0x1eff: addl $20, %esp
0x1f02: popl %ebx
0x1f03: leave
0x1f04: ret
This can be handy when dealing with the new --line options that was recently
added:
(lldb) disassemble --line
a.out`main + 13 at test.c:19
18 {
-> 19 printf("Process: %i\n\n", getpid());
20 puts("Press any key to continue..."); getchar();
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
Modified the ModuleList to have a lookup based solely on a UUID. Since the
UUID is typically the MD5 checksum of a binary image, there is no need
to give the path and architecture when searching for a pre-existing
image in an image list.
Now that we support remote debugging a bit better, our lldb_private::Module
needs to be able to track what the original path for file was as the platform
knows it, as well as where the file is locally. The module has the two
following functions to retrieve both paths:
const FileSpec &Module::GetFileSpec () const;
const FileSpec &Module::GetPlatformFileSpec () const;
llvm-svn: 128563
2011-03-31 02:16:51 +08:00
if ( m_arch = = arch_spec )
2010-06-09 00:52:24 +08:00
{
2010-08-10 07:31:02 +08:00
// If we're setting the architecture to our current architecture, we
// don't need to do anything.
return true ;
}
Many improvements to the Platform base class and subclasses. The base Platform
class now implements the Host functionality for a lot of things that make
sense by default so that subclasses can check:
int
PlatformSubclass::Foo ()
{
if (IsHost())
return Platform::Foo (); // Let the platform base class do the host specific stuff
// Platform subclass specific code...
int result = ...
return result;
}
Added new functions to the platform:
virtual const char *Platform::GetUserName (uint32_t uid);
virtual const char *Platform::GetGroupName (uint32_t gid);
The user and group names are cached locally so that remote platforms can avoid
sending packets multiple times to resolve this information.
Added the parent process ID to the ProcessInfo class.
Added a new ProcessInfoMatch class which helps us to match processes up
and changed the Host layer over to using this new class. The new class allows
us to search for processs:
1 - by name (equal to, starts with, ends with, contains, and regex)
2 - by pid
3 - And further check for parent pid == value, uid == value, gid == value,
euid == value, egid == value, arch == value, parent == value.
This is all hookup up to the "platform process list" command which required
adding dumping routines to dump process information. If the Host class
implements the process lookup routines, you can now lists processes on
your local machine:
machine1.foo.com % lldb
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
94727 244 username usergroup username usergroup x86_64-apple-darwin Xcode
92742 92710 username usergroup username usergroup i386-apple-darwin debugserver
This of course also works remotely with the lldb-platform:
machine1.foo.com % lldb-platform --listen 1234
machine2.foo.com % lldb
(lldb) platform create remote-macosx
Platform: remote-macosx
Connected: no
(lldb) platform connect connect://localhost:1444
Platform: remote-macosx
Triple: x86_64-apple-darwin
OS Version: 10.6.7 (10J869)
Kernel: Darwin Kernel Version 10.7.0: Sat Jan 29 15:17:16 PST 2011; root:xnu-1504.9.37~1/RELEASE_I386
Hostname: machine1.foo.com
Connected: yes
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99556 244 username usergroup username usergroup x86_64-apple-darwin trustevaluation
99548 65539 username usergroup username usergroup x86_64-apple-darwin lldb
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
The lldb-platform implements everything with the Host:: layer, so this should
"just work" for linux. I will probably be adding more stuff to the Host layer
for launching processes and attaching to processes so that this support should
eventually just work as well.
Modified the target to be able to be created with an architecture that differs
from the main executable. This is needed for iOS debugging since we can have
an "armv6" binary which can run on an "armv7" machine, so we want to be able
to do:
% lldb
(lldb) platform create remote-ios
(lldb) file --arch armv7 a.out
Where "a.out" is an armv6 executable. The platform then can correctly decide
to open all "armv7" images for all dependent shared libraries.
Modified the disassembly to show the current PC value. Example output:
(lldb) disassemble --frame
a.out`main:
0x1eb7: pushl %ebp
0x1eb8: movl %esp, %ebp
0x1eba: pushl %ebx
0x1ebb: subl $20, %esp
0x1ebe: calll 0x1ec3 ; main + 12 at test.c:18
0x1ec3: popl %ebx
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
0x1edb: leal 213(%ebx), %eax
0x1ee1: movl %eax, (%esp)
0x1ee4: calll 0x1f1e ; puts
0x1ee9: calll 0x1f0c ; getchar
0x1eee: movl $20, (%esp)
0x1ef5: calll 0x1e6a ; sleep_loop at test.c:6
0x1efa: movl $12, %eax
0x1eff: addl $20, %esp
0x1f02: popl %ebx
0x1f03: leave
0x1f04: ret
This can be handy when dealing with the new --line options that was recently
added:
(lldb) disassemble --line
a.out`main + 13 at test.c:19
18 {
-> 19 printf("Process: %i\n\n", getpid());
20 puts("Press any key to continue..."); getchar();
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
Modified the ModuleList to have a lookup based solely on a UUID. Since the
UUID is typically the MD5 checksum of a binary image, there is no need
to give the path and architecture when searching for a pre-existing
image in an image list.
Now that we support remote debugging a bit better, our lldb_private::Module
needs to be able to track what the original path for file was as the platform
knows it, as well as where the file is locally. The module has the two
following functions to retrieve both paths:
const FileSpec &Module::GetFileSpec () const;
const FileSpec &Module::GetPlatformFileSpec () const;
llvm-svn: 128563
2011-03-31 02:16:51 +08:00
else if ( ! m_arch . IsValid ( ) )
2010-08-10 07:31:02 +08:00
{
// If we haven't got a valid arch spec, then we just need to set it.
Many improvements to the Platform base class and subclasses. The base Platform
class now implements the Host functionality for a lot of things that make
sense by default so that subclasses can check:
int
PlatformSubclass::Foo ()
{
if (IsHost())
return Platform::Foo (); // Let the platform base class do the host specific stuff
// Platform subclass specific code...
int result = ...
return result;
}
Added new functions to the platform:
virtual const char *Platform::GetUserName (uint32_t uid);
virtual const char *Platform::GetGroupName (uint32_t gid);
The user and group names are cached locally so that remote platforms can avoid
sending packets multiple times to resolve this information.
Added the parent process ID to the ProcessInfo class.
Added a new ProcessInfoMatch class which helps us to match processes up
and changed the Host layer over to using this new class. The new class allows
us to search for processs:
1 - by name (equal to, starts with, ends with, contains, and regex)
2 - by pid
3 - And further check for parent pid == value, uid == value, gid == value,
euid == value, egid == value, arch == value, parent == value.
This is all hookup up to the "platform process list" command which required
adding dumping routines to dump process information. If the Host class
implements the process lookup routines, you can now lists processes on
your local machine:
machine1.foo.com % lldb
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
94727 244 username usergroup username usergroup x86_64-apple-darwin Xcode
92742 92710 username usergroup username usergroup i386-apple-darwin debugserver
This of course also works remotely with the lldb-platform:
machine1.foo.com % lldb-platform --listen 1234
machine2.foo.com % lldb
(lldb) platform create remote-macosx
Platform: remote-macosx
Connected: no
(lldb) platform connect connect://localhost:1444
Platform: remote-macosx
Triple: x86_64-apple-darwin
OS Version: 10.6.7 (10J869)
Kernel: Darwin Kernel Version 10.7.0: Sat Jan 29 15:17:16 PST 2011; root:xnu-1504.9.37~1/RELEASE_I386
Hostname: machine1.foo.com
Connected: yes
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99556 244 username usergroup username usergroup x86_64-apple-darwin trustevaluation
99548 65539 username usergroup username usergroup x86_64-apple-darwin lldb
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
The lldb-platform implements everything with the Host:: layer, so this should
"just work" for linux. I will probably be adding more stuff to the Host layer
for launching processes and attaching to processes so that this support should
eventually just work as well.
Modified the target to be able to be created with an architecture that differs
from the main executable. This is needed for iOS debugging since we can have
an "armv6" binary which can run on an "armv7" machine, so we want to be able
to do:
% lldb
(lldb) platform create remote-ios
(lldb) file --arch armv7 a.out
Where "a.out" is an armv6 executable. The platform then can correctly decide
to open all "armv7" images for all dependent shared libraries.
Modified the disassembly to show the current PC value. Example output:
(lldb) disassemble --frame
a.out`main:
0x1eb7: pushl %ebp
0x1eb8: movl %esp, %ebp
0x1eba: pushl %ebx
0x1ebb: subl $20, %esp
0x1ebe: calll 0x1ec3 ; main + 12 at test.c:18
0x1ec3: popl %ebx
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
0x1edb: leal 213(%ebx), %eax
0x1ee1: movl %eax, (%esp)
0x1ee4: calll 0x1f1e ; puts
0x1ee9: calll 0x1f0c ; getchar
0x1eee: movl $20, (%esp)
0x1ef5: calll 0x1e6a ; sleep_loop at test.c:6
0x1efa: movl $12, %eax
0x1eff: addl $20, %esp
0x1f02: popl %ebx
0x1f03: leave
0x1f04: ret
This can be handy when dealing with the new --line options that was recently
added:
(lldb) disassemble --line
a.out`main + 13 at test.c:19
18 {
-> 19 printf("Process: %i\n\n", getpid());
20 puts("Press any key to continue..."); getchar();
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
Modified the ModuleList to have a lookup based solely on a UUID. Since the
UUID is typically the MD5 checksum of a binary image, there is no need
to give the path and architecture when searching for a pre-existing
image in an image list.
Now that we support remote debugging a bit better, our lldb_private::Module
needs to be able to track what the original path for file was as the platform
knows it, as well as where the file is locally. The module has the two
following functions to retrieve both paths:
const FileSpec &Module::GetFileSpec () const;
const FileSpec &Module::GetPlatformFileSpec () const;
llvm-svn: 128563
2011-03-31 02:16:51 +08:00
m_arch = arch_spec ;
2010-08-10 07:31:02 +08:00
return true ;
}
else
{
// If we have an executable file, try to reset the executable to the desired architecture
Many improvements to the Platform base class and subclasses. The base Platform
class now implements the Host functionality for a lot of things that make
sense by default so that subclasses can check:
int
PlatformSubclass::Foo ()
{
if (IsHost())
return Platform::Foo (); // Let the platform base class do the host specific stuff
// Platform subclass specific code...
int result = ...
return result;
}
Added new functions to the platform:
virtual const char *Platform::GetUserName (uint32_t uid);
virtual const char *Platform::GetGroupName (uint32_t gid);
The user and group names are cached locally so that remote platforms can avoid
sending packets multiple times to resolve this information.
Added the parent process ID to the ProcessInfo class.
Added a new ProcessInfoMatch class which helps us to match processes up
and changed the Host layer over to using this new class. The new class allows
us to search for processs:
1 - by name (equal to, starts with, ends with, contains, and regex)
2 - by pid
3 - And further check for parent pid == value, uid == value, gid == value,
euid == value, egid == value, arch == value, parent == value.
This is all hookup up to the "platform process list" command which required
adding dumping routines to dump process information. If the Host class
implements the process lookup routines, you can now lists processes on
your local machine:
machine1.foo.com % lldb
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
94727 244 username usergroup username usergroup x86_64-apple-darwin Xcode
92742 92710 username usergroup username usergroup i386-apple-darwin debugserver
This of course also works remotely with the lldb-platform:
machine1.foo.com % lldb-platform --listen 1234
machine2.foo.com % lldb
(lldb) platform create remote-macosx
Platform: remote-macosx
Connected: no
(lldb) platform connect connect://localhost:1444
Platform: remote-macosx
Triple: x86_64-apple-darwin
OS Version: 10.6.7 (10J869)
Kernel: Darwin Kernel Version 10.7.0: Sat Jan 29 15:17:16 PST 2011; root:xnu-1504.9.37~1/RELEASE_I386
Hostname: machine1.foo.com
Connected: yes
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99556 244 username usergroup username usergroup x86_64-apple-darwin trustevaluation
99548 65539 username usergroup username usergroup x86_64-apple-darwin lldb
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
The lldb-platform implements everything with the Host:: layer, so this should
"just work" for linux. I will probably be adding more stuff to the Host layer
for launching processes and attaching to processes so that this support should
eventually just work as well.
Modified the target to be able to be created with an architecture that differs
from the main executable. This is needed for iOS debugging since we can have
an "armv6" binary which can run on an "armv7" machine, so we want to be able
to do:
% lldb
(lldb) platform create remote-ios
(lldb) file --arch armv7 a.out
Where "a.out" is an armv6 executable. The platform then can correctly decide
to open all "armv7" images for all dependent shared libraries.
Modified the disassembly to show the current PC value. Example output:
(lldb) disassemble --frame
a.out`main:
0x1eb7: pushl %ebp
0x1eb8: movl %esp, %ebp
0x1eba: pushl %ebx
0x1ebb: subl $20, %esp
0x1ebe: calll 0x1ec3 ; main + 12 at test.c:18
0x1ec3: popl %ebx
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
0x1edb: leal 213(%ebx), %eax
0x1ee1: movl %eax, (%esp)
0x1ee4: calll 0x1f1e ; puts
0x1ee9: calll 0x1f0c ; getchar
0x1eee: movl $20, (%esp)
0x1ef5: calll 0x1e6a ; sleep_loop at test.c:6
0x1efa: movl $12, %eax
0x1eff: addl $20, %esp
0x1f02: popl %ebx
0x1f03: leave
0x1f04: ret
This can be handy when dealing with the new --line options that was recently
added:
(lldb) disassemble --line
a.out`main + 13 at test.c:19
18 {
-> 19 printf("Process: %i\n\n", getpid());
20 puts("Press any key to continue..."); getchar();
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
Modified the ModuleList to have a lookup based solely on a UUID. Since the
UUID is typically the MD5 checksum of a binary image, there is no need
to give the path and architecture when searching for a pre-existing
image in an image list.
Now that we support remote debugging a bit better, our lldb_private::Module
needs to be able to track what the original path for file was as the platform
knows it, as well as where the file is locally. The module has the two
following functions to retrieve both paths:
const FileSpec &Module::GetFileSpec () const;
const FileSpec &Module::GetPlatformFileSpec () const;
llvm-svn: 128563
2011-03-31 02:16:51 +08:00
m_arch = arch_spec ;
2010-08-10 07:31:02 +08:00
ModuleSP executable_sp = GetExecutableModule ( ) ;
m_images . Clear ( ) ;
m_scratch_ast_context_ap . reset ( ) ;
2011-11-17 02:20:47 +08:00
m_scratch_ast_source_ap . reset ( ) ;
m_ast_importer_ap . reset ( ) ;
2010-08-10 07:31:02 +08:00
// Need to do something about unsetting breakpoints.
if ( executable_sp )
{
2012-02-26 13:51:37 +08:00
ModuleSpec module_spec ( executable_sp - > GetFileSpec ( ) , arch_spec ) ;
Error error = ModuleList : : GetSharedModule ( module_spec ,
executable_sp ,
& GetExecutableSearchPaths ( ) ,
NULL ,
NULL ) ;
2010-08-10 07:31:02 +08:00
if ( ! error . Fail ( ) & & executable_sp )
{
SetExecutableModule ( executable_sp , true ) ;
return true ;
}
else
{
return false ;
}
}
else
{
return false ;
}
2010-06-09 00:52:24 +08:00
}
}
void
Target : : ModuleAdded ( ModuleSP & module_sp )
{
// A module is being added to this target for the first time
ModuleList module_list ;
module_list . Append ( module_sp ) ;
ModulesDidLoad ( module_list ) ;
}
void
Target : : ModuleUpdated ( ModuleSP & old_module_sp , ModuleSP & new_module_sp )
{
2011-08-03 09:00:06 +08:00
// A module is replacing an already added module
2010-06-09 00:52:24 +08:00
ModuleList module_list ;
module_list . Append ( old_module_sp ) ;
ModulesDidUnload ( module_list ) ;
module_list . Clear ( ) ;
module_list . Append ( new_module_sp ) ;
ModulesDidLoad ( module_list ) ;
}
void
Target : : ModulesDidLoad ( ModuleList & module_list )
{
m_breakpoint_list . UpdateBreakpoints ( module_list , true ) ;
// TODO: make event data that packages up the module_list
BroadcastEvent ( eBroadcastBitModulesLoaded , NULL ) ;
}
void
Target : : ModulesDidUnload ( ModuleList & module_list )
{
m_breakpoint_list . UpdateBreakpoints ( module_list , false ) ;
2010-12-07 07:51:26 +08:00
// Remove the images from the target image list
m_images . Remove ( module_list ) ;
2010-06-09 00:52:24 +08:00
// TODO: make event data that packages up the module_list
BroadcastEvent ( eBroadcastBitModulesUnloaded , NULL ) ;
}
2011-10-29 07:14:11 +08:00
2011-11-01 06:50:37 +08:00
bool
2012-02-26 13:51:37 +08:00
Target : : ModuleIsExcludedForNonModuleSpecificSearches ( const FileSpec & module_file_spec )
2011-10-29 07:14:11 +08:00
{
if ( ! m_breakpoints_use_platform_avoid )
return false ;
else
{
ModuleList matchingModules ;
2012-02-26 13:51:37 +08:00
ModuleSpec module_spec ( module_file_spec ) ;
size_t num_modules = GetImages ( ) . FindModules ( module_spec , matchingModules ) ;
2011-10-29 07:14:11 +08:00
// If there is more than one module for this file spec, only return true if ALL the modules are on the
// black list.
if ( num_modules > 0 )
{
for ( int i = 0 ; i < num_modules ; i + + )
{
if ( ! ModuleIsExcludedForNonModuleSpecificSearches ( matchingModules . GetModuleAtIndex ( i ) ) )
return false ;
}
return true ;
}
else
return false ;
}
}
2011-11-01 06:50:37 +08:00
bool
2011-10-29 07:14:11 +08:00
Target : : ModuleIsExcludedForNonModuleSpecificSearches ( const lldb : : ModuleSP & module_sp )
{
if ( ! m_breakpoints_use_platform_avoid )
return false ;
else if ( GetPlatform ( ) )
{
return GetPlatform ( ) - > ModuleIsExcludedForNonModuleSpecificSearches ( * this , module_sp ) ;
}
else
return false ;
}
2010-06-09 00:52:24 +08:00
size_t
2011-01-07 09:57:07 +08:00
Target : : ReadMemoryFromFileCache ( const Address & addr , void * dst , size_t dst_len , Error & error )
2010-06-09 00:52:24 +08:00
{
2012-02-24 09:59:29 +08:00
SectionSP section_sp ( addr . GetSection ( ) ) ;
if ( section_sp )
2011-01-07 09:57:07 +08:00
{
2012-02-24 09:59:29 +08:00
ModuleSP module_sp ( section_sp - > GetModule ( ) ) ;
if ( module_sp )
2011-01-07 09:57:07 +08:00
{
2012-02-24 09:59:29 +08:00
ObjectFile * objfile = section_sp - > GetModule ( ) - > GetObjectFile ( ) ;
if ( objfile )
{
size_t bytes_read = objfile - > ReadSectionData ( section_sp . get ( ) ,
addr . GetOffset ( ) ,
dst ,
dst_len ) ;
if ( bytes_read > 0 )
return bytes_read ;
else
error . SetErrorStringWithFormat ( " error reading data from section %s " , section_sp - > GetName ( ) . GetCString ( ) ) ;
}
2011-01-07 09:57:07 +08:00
else
2012-02-24 09:59:29 +08:00
error . SetErrorString ( " address isn't from a object file " ) ;
2011-01-07 09:57:07 +08:00
}
else
2012-02-24 09:59:29 +08:00
error . SetErrorString ( " address isn't in a module " ) ;
2011-01-07 09:57:07 +08:00
}
else
error . SetErrorString ( " address doesn't contain a section that points to a section in a object file " ) ;
2012-02-24 09:59:29 +08:00
2011-01-07 09:57:07 +08:00
return 0 ;
}
2010-07-01 07:03:03 +08:00
2011-01-07 09:57:07 +08:00
size_t
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
Target : : ReadMemory ( const Address & addr ,
bool prefer_file_cache ,
void * dst ,
size_t dst_len ,
Error & error ,
lldb : : addr_t * load_addr_ptr )
2011-01-07 09:57:07 +08:00
{
error . Clear ( ) ;
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
// if we end up reading this from process memory, we will fill this
// with the actual load address
if ( load_addr_ptr )
* load_addr_ptr = LLDB_INVALID_ADDRESS ;
2011-01-07 09:57:07 +08:00
size_t bytes_read = 0 ;
2011-07-11 13:12:02 +08:00
addr_t load_addr = LLDB_INVALID_ADDRESS ;
addr_t file_addr = LLDB_INVALID_ADDRESS ;
Added the ability to get the min and max instruction byte size for
an architecture into ArchSpec:
uint32_t
ArchSpec::GetMinimumOpcodeByteSize() const;
uint32_t
ArchSpec::GetMaximumOpcodeByteSize() const;
Added an AddressClass to the Instruction class in Disassembler.h.
This allows decoded instructions to know know if they are code,
code with alternate ISA (thumb), or even data which can be mixed
into code. The instruction does have an address, but it is a good
idea to cache this value so we don't have to look it up more than
once.
Fixed an issue in Opcode::SetOpcodeBytes() where the length wasn't
getting set.
Changed:
bool
SymbolContextList::AppendIfUnique (const SymbolContext& sc);
To:
bool
SymbolContextList::AppendIfUnique (const SymbolContext& sc,
bool merge_symbol_into_function);
This function was typically being used when looking up functions
and symbols. Now if you lookup a function, then find the symbol,
they can be merged into the same symbol context and not cause
multiple symbol contexts to appear in a symbol context list that
describes the same function.
Fixed the SymbolContext not equal operator which was causing mixed
mode disassembly to not work ("disassembler --mixed --name main").
Modified the disassembler classes to know about the fact we know,
for a given architecture, what the min and max opcode byte sizes
are. The InstructionList class was modified to return the max
opcode byte size for all of the instructions in its list.
These two fixes means when disassemble a list of instructions and dump
them and show the opcode bytes, we can format the output more
intelligently when showing opcode bytes. This affects any architectures
that have varying opcode byte sizes (x86_64 and i386). Knowing the max
opcode byte size also helps us to be able to disassemble N instructions
without having to re-read data if we didn't read enough bytes.
Added the ability to set the architecture for the disassemble command.
This means you can easily cross disassemble data for any supported
architecture. I also added the ability to specify "thumb" as an
architecture so that we can force disassembly into thumb mode when
needed. In GDB this was done using a hack of specifying an odd
address when disassembling. I don't want to repeat this hack in LLDB,
so the auto detection between ARM and thumb is failing, just specify
thumb when disassembling:
(lldb) disassemble --arch thumb --name main
You can also have data in say an x86_64 file executable and disassemble
data as any other supported architecture:
% lldb a.out
Current executable set to 'a.out' (x86_64).
(lldb) b main
(lldb) run
(lldb) disassemble --arch thumb --count 2 --start-address 0x0000000100001080 --bytes
0x100001080: 0xb580 push {r7, lr}
0x100001082: 0xaf00 add r7, sp, #0
Fixed Target::ReadMemory(...) to be able to deal with Address argument object
that isn't section offset. When an address object was supplied that was
out on the heap or stack, target read memory would fail. Disassembly uses
Target::ReadMemory(...), and the example above where we disassembler thumb
opcodes in an x86 binary was failing do to this bug.
llvm-svn: 128347
2011-03-27 03:14:58 +08:00
Address resolved_addr ;
if ( ! addr . IsSectionOffset ( ) )
2010-06-09 00:52:24 +08:00
{
2011-07-13 01:06:17 +08:00
if ( m_section_load_list . IsEmpty ( ) )
2011-07-11 13:12:02 +08:00
{
2011-07-13 01:06:17 +08:00
// No sections are loaded, so we must assume we are not running
// yet and anything we are given is a file address.
file_addr = addr . GetOffset ( ) ; // "addr" doesn't have a section, so its offset is the file address
m_images . ResolveFileAddress ( file_addr , resolved_addr ) ;
2011-07-11 13:12:02 +08:00
}
2010-07-01 07:03:03 +08:00
else
2011-07-11 13:12:02 +08:00
{
2011-07-13 01:06:17 +08:00
// We have at least one section loaded. This can be becuase
// we have manually loaded some sections with "target modules load ..."
// or because we have have a live process that has sections loaded
// through the dynamic loader
load_addr = addr . GetOffset ( ) ; // "addr" doesn't have a section, so its offset is the load address
m_section_load_list . ResolveLoadAddress ( load_addr , resolved_addr ) ;
2011-07-11 13:12:02 +08:00
}
2010-07-01 07:03:03 +08:00
}
Added the ability to get the min and max instruction byte size for
an architecture into ArchSpec:
uint32_t
ArchSpec::GetMinimumOpcodeByteSize() const;
uint32_t
ArchSpec::GetMaximumOpcodeByteSize() const;
Added an AddressClass to the Instruction class in Disassembler.h.
This allows decoded instructions to know know if they are code,
code with alternate ISA (thumb), or even data which can be mixed
into code. The instruction does have an address, but it is a good
idea to cache this value so we don't have to look it up more than
once.
Fixed an issue in Opcode::SetOpcodeBytes() where the length wasn't
getting set.
Changed:
bool
SymbolContextList::AppendIfUnique (const SymbolContext& sc);
To:
bool
SymbolContextList::AppendIfUnique (const SymbolContext& sc,
bool merge_symbol_into_function);
This function was typically being used when looking up functions
and symbols. Now if you lookup a function, then find the symbol,
they can be merged into the same symbol context and not cause
multiple symbol contexts to appear in a symbol context list that
describes the same function.
Fixed the SymbolContext not equal operator which was causing mixed
mode disassembly to not work ("disassembler --mixed --name main").
Modified the disassembler classes to know about the fact we know,
for a given architecture, what the min and max opcode byte sizes
are. The InstructionList class was modified to return the max
opcode byte size for all of the instructions in its list.
These two fixes means when disassemble a list of instructions and dump
them and show the opcode bytes, we can format the output more
intelligently when showing opcode bytes. This affects any architectures
that have varying opcode byte sizes (x86_64 and i386). Knowing the max
opcode byte size also helps us to be able to disassemble N instructions
without having to re-read data if we didn't read enough bytes.
Added the ability to set the architecture for the disassemble command.
This means you can easily cross disassemble data for any supported
architecture. I also added the ability to specify "thumb" as an
architecture so that we can force disassembly into thumb mode when
needed. In GDB this was done using a hack of specifying an odd
address when disassembling. I don't want to repeat this hack in LLDB,
so the auto detection between ARM and thumb is failing, just specify
thumb when disassembling:
(lldb) disassemble --arch thumb --name main
You can also have data in say an x86_64 file executable and disassemble
data as any other supported architecture:
% lldb a.out
Current executable set to 'a.out' (x86_64).
(lldb) b main
(lldb) run
(lldb) disassemble --arch thumb --count 2 --start-address 0x0000000100001080 --bytes
0x100001080: 0xb580 push {r7, lr}
0x100001082: 0xaf00 add r7, sp, #0
Fixed Target::ReadMemory(...) to be able to deal with Address argument object
that isn't section offset. When an address object was supplied that was
out on the heap or stack, target read memory would fail. Disassembly uses
Target::ReadMemory(...), and the example above where we disassembler thumb
opcodes in an x86 binary was failing do to this bug.
llvm-svn: 128347
2011-03-27 03:14:58 +08:00
if ( ! resolved_addr . IsValid ( ) )
resolved_addr = addr ;
2010-07-01 07:03:03 +08:00
2011-07-11 13:12:02 +08:00
2011-01-07 09:57:07 +08:00
if ( prefer_file_cache )
{
bytes_read = ReadMemoryFromFileCache ( resolved_addr , dst , dst_len , error ) ;
if ( bytes_read > 0 )
return bytes_read ;
}
2010-07-01 07:03:03 +08:00
2011-09-21 07:28:55 +08:00
if ( ProcessIsValid ( ) )
2010-07-01 07:03:03 +08:00
{
2011-07-11 13:12:02 +08:00
if ( load_addr = = LLDB_INVALID_ADDRESS )
load_addr = resolved_addr . GetLoadAddress ( this ) ;
2010-07-01 07:03:03 +08:00
if ( load_addr = = LLDB_INVALID_ADDRESS )
{
2012-02-24 09:59:29 +08:00
ModuleSP addr_module_sp ( resolved_addr . GetModule ( ) ) ;
if ( addr_module_sp & & addr_module_sp - > GetFileSpec ( ) )
2011-10-26 08:56:27 +08:00
error . SetErrorStringWithFormat ( " %s[0x%llx] can't be resolved, %s in not currently loaded " ,
2012-02-24 09:59:29 +08:00
addr_module_sp - > GetFileSpec ( ) . GetFilename ( ) . AsCString ( ) ,
2011-09-20 08:26:08 +08:00
resolved_addr . GetFileAddress ( ) ,
2012-02-24 09:59:29 +08:00
addr_module_sp - > GetFileSpec ( ) . GetFilename ( ) . AsCString ( ) ) ;
2010-06-09 00:52:24 +08:00
else
2011-10-26 08:56:27 +08:00
error . SetErrorStringWithFormat ( " 0x%llx can't be resolved " , resolved_addr . GetFileAddress ( ) ) ;
2010-06-09 00:52:24 +08:00
}
2010-07-01 07:03:03 +08:00
else
2010-06-09 00:52:24 +08:00
{
2011-01-07 09:57:07 +08:00
bytes_read = m_process_sp - > ReadMemory ( load_addr , dst , dst_len , error ) ;
2010-06-09 00:52:24 +08:00
if ( bytes_read ! = dst_len )
{
if ( error . Success ( ) )
{
if ( bytes_read = = 0 )
2011-10-26 08:56:27 +08:00
error . SetErrorStringWithFormat ( " read memory from 0x%llx failed " , load_addr ) ;
2010-06-09 00:52:24 +08:00
else
2011-10-26 08:56:27 +08:00
error . SetErrorStringWithFormat ( " only %zu of %zu bytes were read from memory at 0x%llx " , bytes_read , dst_len , load_addr ) ;
2010-06-09 00:52:24 +08:00
}
}
2010-07-01 07:03:03 +08:00
if ( bytes_read )
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
{
if ( load_addr_ptr )
* load_addr_ptr = load_addr ;
2010-07-01 07:03:03 +08:00
return bytes_read ;
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
}
2010-07-01 07:03:03 +08:00
// If the address is not section offset we have an address that
// doesn't resolve to any address in any currently loaded shared
// libaries and we failed to read memory so there isn't anything
// more we can do. If it is section offset, we might be able to
// read cached memory from the object file.
if ( ! resolved_addr . IsSectionOffset ( ) )
return 0 ;
2010-06-09 00:52:24 +08:00
}
}
2010-07-01 07:03:03 +08:00
2011-07-11 13:12:02 +08:00
if ( ! prefer_file_cache & & resolved_addr . IsSectionOffset ( ) )
2010-07-01 07:03:03 +08:00
{
2011-01-07 09:57:07 +08:00
// If we didn't already try and read from the object file cache, then
// try it after failing to read from the process.
return ReadMemoryFromFileCache ( resolved_addr , dst , dst_len , error ) ;
2010-07-01 07:03:03 +08:00
}
return 0 ;
2010-06-09 00:52:24 +08:00
}
2011-07-13 01:06:17 +08:00
size_t
Target : : ReadScalarIntegerFromMemory ( const Address & addr ,
bool prefer_file_cache ,
uint32_t byte_size ,
bool is_signed ,
Scalar & scalar ,
Error & error )
{
uint64_t uval ;
if ( byte_size < = sizeof ( uval ) )
{
size_t bytes_read = ReadMemory ( addr , prefer_file_cache , & uval , byte_size , error ) ;
if ( bytes_read = = byte_size )
{
DataExtractor data ( & uval , sizeof ( uval ) , m_arch . GetByteOrder ( ) , m_arch . GetAddressByteSize ( ) ) ;
uint32_t offset = 0 ;
if ( byte_size < = 4 )
scalar = data . GetMaxU32 ( & offset , byte_size ) ;
else
scalar = data . GetMaxU64 ( & offset , byte_size ) ;
if ( is_signed )
scalar . SignExtend ( byte_size * 8 ) ;
return bytes_read ;
}
}
else
{
error . SetErrorStringWithFormat ( " byte size of %u is too large for integer scalar type " , byte_size ) ;
}
return 0 ;
}
uint64_t
Target : : ReadUnsignedIntegerFromMemory ( const Address & addr ,
bool prefer_file_cache ,
size_t integer_byte_size ,
uint64_t fail_value ,
Error & error )
{
Scalar scalar ;
if ( ReadScalarIntegerFromMemory ( addr ,
prefer_file_cache ,
integer_byte_size ,
false ,
scalar ,
error ) )
return scalar . ULongLong ( fail_value ) ;
return fail_value ;
}
bool
Target : : ReadPointerFromMemory ( const Address & addr ,
bool prefer_file_cache ,
Error & error ,
Address & pointer_addr )
{
Scalar scalar ;
if ( ReadScalarIntegerFromMemory ( addr ,
prefer_file_cache ,
m_arch . GetAddressByteSize ( ) ,
false ,
scalar ,
error ) )
{
addr_t pointer_vm_addr = scalar . ULongLong ( LLDB_INVALID_ADDRESS ) ;
if ( pointer_vm_addr ! = LLDB_INVALID_ADDRESS )
{
if ( m_section_load_list . IsEmpty ( ) )
{
// No sections are loaded, so we must assume we are not running
// yet and anything we are given is a file address.
m_images . ResolveFileAddress ( pointer_vm_addr , pointer_addr ) ;
}
else
{
// We have at least one section loaded. This can be becuase
// we have manually loaded some sections with "target modules load ..."
// or because we have have a live process that has sections loaded
// through the dynamic loader
m_section_load_list . ResolveLoadAddress ( pointer_vm_addr , pointer_addr ) ;
}
// We weren't able to resolve the pointer value, so just return
// an address with no section
if ( ! pointer_addr . IsValid ( ) )
pointer_addr . SetOffset ( pointer_vm_addr ) ;
return true ;
}
}
return false ;
}
2010-06-09 00:52:24 +08:00
ModuleSP
2012-02-26 13:51:37 +08:00
Target : : GetSharedModule ( const ModuleSpec & module_spec , Error * error_ptr )
2010-06-09 00:52:24 +08:00
{
// Don't pass in the UUID so we can tell if we have a stale value in our list
ModuleSP old_module_sp ; // This will get filled in if we have a new version of the library
bool did_create_module = false ;
ModuleSP module_sp ;
Error error ;
Many improvements to the Platform base class and subclasses. The base Platform
class now implements the Host functionality for a lot of things that make
sense by default so that subclasses can check:
int
PlatformSubclass::Foo ()
{
if (IsHost())
return Platform::Foo (); // Let the platform base class do the host specific stuff
// Platform subclass specific code...
int result = ...
return result;
}
Added new functions to the platform:
virtual const char *Platform::GetUserName (uint32_t uid);
virtual const char *Platform::GetGroupName (uint32_t gid);
The user and group names are cached locally so that remote platforms can avoid
sending packets multiple times to resolve this information.
Added the parent process ID to the ProcessInfo class.
Added a new ProcessInfoMatch class which helps us to match processes up
and changed the Host layer over to using this new class. The new class allows
us to search for processs:
1 - by name (equal to, starts with, ends with, contains, and regex)
2 - by pid
3 - And further check for parent pid == value, uid == value, gid == value,
euid == value, egid == value, arch == value, parent == value.
This is all hookup up to the "platform process list" command which required
adding dumping routines to dump process information. If the Host class
implements the process lookup routines, you can now lists processes on
your local machine:
machine1.foo.com % lldb
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
94727 244 username usergroup username usergroup x86_64-apple-darwin Xcode
92742 92710 username usergroup username usergroup i386-apple-darwin debugserver
This of course also works remotely with the lldb-platform:
machine1.foo.com % lldb-platform --listen 1234
machine2.foo.com % lldb
(lldb) platform create remote-macosx
Platform: remote-macosx
Connected: no
(lldb) platform connect connect://localhost:1444
Platform: remote-macosx
Triple: x86_64-apple-darwin
OS Version: 10.6.7 (10J869)
Kernel: Darwin Kernel Version 10.7.0: Sat Jan 29 15:17:16 PST 2011; root:xnu-1504.9.37~1/RELEASE_I386
Hostname: machine1.foo.com
Connected: yes
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99556 244 username usergroup username usergroup x86_64-apple-darwin trustevaluation
99548 65539 username usergroup username usergroup x86_64-apple-darwin lldb
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
The lldb-platform implements everything with the Host:: layer, so this should
"just work" for linux. I will probably be adding more stuff to the Host layer
for launching processes and attaching to processes so that this support should
eventually just work as well.
Modified the target to be able to be created with an architecture that differs
from the main executable. This is needed for iOS debugging since we can have
an "armv6" binary which can run on an "armv7" machine, so we want to be able
to do:
% lldb
(lldb) platform create remote-ios
(lldb) file --arch armv7 a.out
Where "a.out" is an armv6 executable. The platform then can correctly decide
to open all "armv7" images for all dependent shared libraries.
Modified the disassembly to show the current PC value. Example output:
(lldb) disassemble --frame
a.out`main:
0x1eb7: pushl %ebp
0x1eb8: movl %esp, %ebp
0x1eba: pushl %ebx
0x1ebb: subl $20, %esp
0x1ebe: calll 0x1ec3 ; main + 12 at test.c:18
0x1ec3: popl %ebx
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
0x1edb: leal 213(%ebx), %eax
0x1ee1: movl %eax, (%esp)
0x1ee4: calll 0x1f1e ; puts
0x1ee9: calll 0x1f0c ; getchar
0x1eee: movl $20, (%esp)
0x1ef5: calll 0x1e6a ; sleep_loop at test.c:6
0x1efa: movl $12, %eax
0x1eff: addl $20, %esp
0x1f02: popl %ebx
0x1f03: leave
0x1f04: ret
This can be handy when dealing with the new --line options that was recently
added:
(lldb) disassemble --line
a.out`main + 13 at test.c:19
18 {
-> 19 printf("Process: %i\n\n", getpid());
20 puts("Press any key to continue..."); getchar();
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
Modified the ModuleList to have a lookup based solely on a UUID. Since the
UUID is typically the MD5 checksum of a binary image, there is no need
to give the path and architecture when searching for a pre-existing
image in an image list.
Now that we support remote debugging a bit better, our lldb_private::Module
needs to be able to track what the original path for file was as the platform
knows it, as well as where the file is locally. The module has the two
following functions to retrieve both paths:
const FileSpec &Module::GetFileSpec () const;
const FileSpec &Module::GetPlatformFileSpec () const;
llvm-svn: 128563
2011-03-31 02:16:51 +08:00
// If there are image search path entries, try to use them first to acquire a suitable image.
2010-06-09 00:52:24 +08:00
if ( m_image_search_paths . GetSize ( ) )
{
2012-02-26 13:51:37 +08:00
ModuleSpec transformed_spec ( module_spec ) ;
if ( m_image_search_paths . RemapPath ( module_spec . GetFileSpec ( ) . GetDirectory ( ) , transformed_spec . GetFileSpec ( ) . GetDirectory ( ) ) )
2010-06-09 00:52:24 +08:00
{
2012-02-26 13:51:37 +08:00
transformed_spec . GetFileSpec ( ) . GetFilename ( ) = module_spec . GetFileSpec ( ) . GetFilename ( ) ;
2012-02-14 07:10:39 +08:00
error = ModuleList : : GetSharedModule ( transformed_spec ,
module_sp ,
& GetExecutableSearchPaths ( ) ,
& old_module_sp ,
& did_create_module ) ;
2010-06-09 00:52:24 +08:00
}
}
Many improvements to the Platform base class and subclasses. The base Platform
class now implements the Host functionality for a lot of things that make
sense by default so that subclasses can check:
int
PlatformSubclass::Foo ()
{
if (IsHost())
return Platform::Foo (); // Let the platform base class do the host specific stuff
// Platform subclass specific code...
int result = ...
return result;
}
Added new functions to the platform:
virtual const char *Platform::GetUserName (uint32_t uid);
virtual const char *Platform::GetGroupName (uint32_t gid);
The user and group names are cached locally so that remote platforms can avoid
sending packets multiple times to resolve this information.
Added the parent process ID to the ProcessInfo class.
Added a new ProcessInfoMatch class which helps us to match processes up
and changed the Host layer over to using this new class. The new class allows
us to search for processs:
1 - by name (equal to, starts with, ends with, contains, and regex)
2 - by pid
3 - And further check for parent pid == value, uid == value, gid == value,
euid == value, egid == value, arch == value, parent == value.
This is all hookup up to the "platform process list" command which required
adding dumping routines to dump process information. If the Host class
implements the process lookup routines, you can now lists processes on
your local machine:
machine1.foo.com % lldb
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
94727 244 username usergroup username usergroup x86_64-apple-darwin Xcode
92742 92710 username usergroup username usergroup i386-apple-darwin debugserver
This of course also works remotely with the lldb-platform:
machine1.foo.com % lldb-platform --listen 1234
machine2.foo.com % lldb
(lldb) platform create remote-macosx
Platform: remote-macosx
Connected: no
(lldb) platform connect connect://localhost:1444
Platform: remote-macosx
Triple: x86_64-apple-darwin
OS Version: 10.6.7 (10J869)
Kernel: Darwin Kernel Version 10.7.0: Sat Jan 29 15:17:16 PST 2011; root:xnu-1504.9.37~1/RELEASE_I386
Hostname: machine1.foo.com
Connected: yes
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99556 244 username usergroup username usergroup x86_64-apple-darwin trustevaluation
99548 65539 username usergroup username usergroup x86_64-apple-darwin lldb
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
The lldb-platform implements everything with the Host:: layer, so this should
"just work" for linux. I will probably be adding more stuff to the Host layer
for launching processes and attaching to processes so that this support should
eventually just work as well.
Modified the target to be able to be created with an architecture that differs
from the main executable. This is needed for iOS debugging since we can have
an "armv6" binary which can run on an "armv7" machine, so we want to be able
to do:
% lldb
(lldb) platform create remote-ios
(lldb) file --arch armv7 a.out
Where "a.out" is an armv6 executable. The platform then can correctly decide
to open all "armv7" images for all dependent shared libraries.
Modified the disassembly to show the current PC value. Example output:
(lldb) disassemble --frame
a.out`main:
0x1eb7: pushl %ebp
0x1eb8: movl %esp, %ebp
0x1eba: pushl %ebx
0x1ebb: subl $20, %esp
0x1ebe: calll 0x1ec3 ; main + 12 at test.c:18
0x1ec3: popl %ebx
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
0x1edb: leal 213(%ebx), %eax
0x1ee1: movl %eax, (%esp)
0x1ee4: calll 0x1f1e ; puts
0x1ee9: calll 0x1f0c ; getchar
0x1eee: movl $20, (%esp)
0x1ef5: calll 0x1e6a ; sleep_loop at test.c:6
0x1efa: movl $12, %eax
0x1eff: addl $20, %esp
0x1f02: popl %ebx
0x1f03: leave
0x1f04: ret
This can be handy when dealing with the new --line options that was recently
added:
(lldb) disassemble --line
a.out`main + 13 at test.c:19
18 {
-> 19 printf("Process: %i\n\n", getpid());
20 puts("Press any key to continue..."); getchar();
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
Modified the ModuleList to have a lookup based solely on a UUID. Since the
UUID is typically the MD5 checksum of a binary image, there is no need
to give the path and architecture when searching for a pre-existing
image in an image list.
Now that we support remote debugging a bit better, our lldb_private::Module
needs to be able to track what the original path for file was as the platform
knows it, as well as where the file is locally. The module has the two
following functions to retrieve both paths:
const FileSpec &Module::GetFileSpec () const;
const FileSpec &Module::GetPlatformFileSpec () const;
llvm-svn: 128563
2011-03-31 02:16:51 +08:00
// The platform is responsible for finding and caching an appropriate
// module in the shared module cache.
if ( m_platform_sp )
2010-06-09 00:52:24 +08:00
{
Many improvements to the Platform base class and subclasses. The base Platform
class now implements the Host functionality for a lot of things that make
sense by default so that subclasses can check:
int
PlatformSubclass::Foo ()
{
if (IsHost())
return Platform::Foo (); // Let the platform base class do the host specific stuff
// Platform subclass specific code...
int result = ...
return result;
}
Added new functions to the platform:
virtual const char *Platform::GetUserName (uint32_t uid);
virtual const char *Platform::GetGroupName (uint32_t gid);
The user and group names are cached locally so that remote platforms can avoid
sending packets multiple times to resolve this information.
Added the parent process ID to the ProcessInfo class.
Added a new ProcessInfoMatch class which helps us to match processes up
and changed the Host layer over to using this new class. The new class allows
us to search for processs:
1 - by name (equal to, starts with, ends with, contains, and regex)
2 - by pid
3 - And further check for parent pid == value, uid == value, gid == value,
euid == value, egid == value, arch == value, parent == value.
This is all hookup up to the "platform process list" command which required
adding dumping routines to dump process information. If the Host class
implements the process lookup routines, you can now lists processes on
your local machine:
machine1.foo.com % lldb
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
94727 244 username usergroup username usergroup x86_64-apple-darwin Xcode
92742 92710 username usergroup username usergroup i386-apple-darwin debugserver
This of course also works remotely with the lldb-platform:
machine1.foo.com % lldb-platform --listen 1234
machine2.foo.com % lldb
(lldb) platform create remote-macosx
Platform: remote-macosx
Connected: no
(lldb) platform connect connect://localhost:1444
Platform: remote-macosx
Triple: x86_64-apple-darwin
OS Version: 10.6.7 (10J869)
Kernel: Darwin Kernel Version 10.7.0: Sat Jan 29 15:17:16 PST 2011; root:xnu-1504.9.37~1/RELEASE_I386
Hostname: machine1.foo.com
Connected: yes
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99556 244 username usergroup username usergroup x86_64-apple-darwin trustevaluation
99548 65539 username usergroup username usergroup x86_64-apple-darwin lldb
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
The lldb-platform implements everything with the Host:: layer, so this should
"just work" for linux. I will probably be adding more stuff to the Host layer
for launching processes and attaching to processes so that this support should
eventually just work as well.
Modified the target to be able to be created with an architecture that differs
from the main executable. This is needed for iOS debugging since we can have
an "armv6" binary which can run on an "armv7" machine, so we want to be able
to do:
% lldb
(lldb) platform create remote-ios
(lldb) file --arch armv7 a.out
Where "a.out" is an armv6 executable. The platform then can correctly decide
to open all "armv7" images for all dependent shared libraries.
Modified the disassembly to show the current PC value. Example output:
(lldb) disassemble --frame
a.out`main:
0x1eb7: pushl %ebp
0x1eb8: movl %esp, %ebp
0x1eba: pushl %ebx
0x1ebb: subl $20, %esp
0x1ebe: calll 0x1ec3 ; main + 12 at test.c:18
0x1ec3: popl %ebx
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
0x1edb: leal 213(%ebx), %eax
0x1ee1: movl %eax, (%esp)
0x1ee4: calll 0x1f1e ; puts
0x1ee9: calll 0x1f0c ; getchar
0x1eee: movl $20, (%esp)
0x1ef5: calll 0x1e6a ; sleep_loop at test.c:6
0x1efa: movl $12, %eax
0x1eff: addl $20, %esp
0x1f02: popl %ebx
0x1f03: leave
0x1f04: ret
This can be handy when dealing with the new --line options that was recently
added:
(lldb) disassemble --line
a.out`main + 13 at test.c:19
18 {
-> 19 printf("Process: %i\n\n", getpid());
20 puts("Press any key to continue..."); getchar();
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
Modified the ModuleList to have a lookup based solely on a UUID. Since the
UUID is typically the MD5 checksum of a binary image, there is no need
to give the path and architecture when searching for a pre-existing
image in an image list.
Now that we support remote debugging a bit better, our lldb_private::Module
needs to be able to track what the original path for file was as the platform
knows it, as well as where the file is locally. The module has the two
following functions to retrieve both paths:
const FileSpec &Module::GetFileSpec () const;
const FileSpec &Module::GetPlatformFileSpec () const;
llvm-svn: 128563
2011-03-31 02:16:51 +08:00
FileSpec platform_file_spec ;
2012-02-26 13:51:37 +08:00
error = m_platform_sp - > GetSharedModule ( module_spec ,
Many improvements to the Platform base class and subclasses. The base Platform
class now implements the Host functionality for a lot of things that make
sense by default so that subclasses can check:
int
PlatformSubclass::Foo ()
{
if (IsHost())
return Platform::Foo (); // Let the platform base class do the host specific stuff
// Platform subclass specific code...
int result = ...
return result;
}
Added new functions to the platform:
virtual const char *Platform::GetUserName (uint32_t uid);
virtual const char *Platform::GetGroupName (uint32_t gid);
The user and group names are cached locally so that remote platforms can avoid
sending packets multiple times to resolve this information.
Added the parent process ID to the ProcessInfo class.
Added a new ProcessInfoMatch class which helps us to match processes up
and changed the Host layer over to using this new class. The new class allows
us to search for processs:
1 - by name (equal to, starts with, ends with, contains, and regex)
2 - by pid
3 - And further check for parent pid == value, uid == value, gid == value,
euid == value, egid == value, arch == value, parent == value.
This is all hookup up to the "platform process list" command which required
adding dumping routines to dump process information. If the Host class
implements the process lookup routines, you can now lists processes on
your local machine:
machine1.foo.com % lldb
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
94727 244 username usergroup username usergroup x86_64-apple-darwin Xcode
92742 92710 username usergroup username usergroup i386-apple-darwin debugserver
This of course also works remotely with the lldb-platform:
machine1.foo.com % lldb-platform --listen 1234
machine2.foo.com % lldb
(lldb) platform create remote-macosx
Platform: remote-macosx
Connected: no
(lldb) platform connect connect://localhost:1444
Platform: remote-macosx
Triple: x86_64-apple-darwin
OS Version: 10.6.7 (10J869)
Kernel: Darwin Kernel Version 10.7.0: Sat Jan 29 15:17:16 PST 2011; root:xnu-1504.9.37~1/RELEASE_I386
Hostname: machine1.foo.com
Connected: yes
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99556 244 username usergroup username usergroup x86_64-apple-darwin trustevaluation
99548 65539 username usergroup username usergroup x86_64-apple-darwin lldb
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
The lldb-platform implements everything with the Host:: layer, so this should
"just work" for linux. I will probably be adding more stuff to the Host layer
for launching processes and attaching to processes so that this support should
eventually just work as well.
Modified the target to be able to be created with an architecture that differs
from the main executable. This is needed for iOS debugging since we can have
an "armv6" binary which can run on an "armv7" machine, so we want to be able
to do:
% lldb
(lldb) platform create remote-ios
(lldb) file --arch armv7 a.out
Where "a.out" is an armv6 executable. The platform then can correctly decide
to open all "armv7" images for all dependent shared libraries.
Modified the disassembly to show the current PC value. Example output:
(lldb) disassemble --frame
a.out`main:
0x1eb7: pushl %ebp
0x1eb8: movl %esp, %ebp
0x1eba: pushl %ebx
0x1ebb: subl $20, %esp
0x1ebe: calll 0x1ec3 ; main + 12 at test.c:18
0x1ec3: popl %ebx
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
0x1edb: leal 213(%ebx), %eax
0x1ee1: movl %eax, (%esp)
0x1ee4: calll 0x1f1e ; puts
0x1ee9: calll 0x1f0c ; getchar
0x1eee: movl $20, (%esp)
0x1ef5: calll 0x1e6a ; sleep_loop at test.c:6
0x1efa: movl $12, %eax
0x1eff: addl $20, %esp
0x1f02: popl %ebx
0x1f03: leave
0x1f04: ret
This can be handy when dealing with the new --line options that was recently
added:
(lldb) disassemble --line
a.out`main + 13 at test.c:19
18 {
-> 19 printf("Process: %i\n\n", getpid());
20 puts("Press any key to continue..."); getchar();
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
Modified the ModuleList to have a lookup based solely on a UUID. Since the
UUID is typically the MD5 checksum of a binary image, there is no need
to give the path and architecture when searching for a pre-existing
image in an image list.
Now that we support remote debugging a bit better, our lldb_private::Module
needs to be able to track what the original path for file was as the platform
knows it, as well as where the file is locally. The module has the two
following functions to retrieve both paths:
const FileSpec &Module::GetFileSpec () const;
const FileSpec &Module::GetPlatformFileSpec () const;
llvm-svn: 128563
2011-03-31 02:16:51 +08:00
module_sp ,
2012-02-14 07:10:39 +08:00
& GetExecutableSearchPaths ( ) ,
Many improvements to the Platform base class and subclasses. The base Platform
class now implements the Host functionality for a lot of things that make
sense by default so that subclasses can check:
int
PlatformSubclass::Foo ()
{
if (IsHost())
return Platform::Foo (); // Let the platform base class do the host specific stuff
// Platform subclass specific code...
int result = ...
return result;
}
Added new functions to the platform:
virtual const char *Platform::GetUserName (uint32_t uid);
virtual const char *Platform::GetGroupName (uint32_t gid);
The user and group names are cached locally so that remote platforms can avoid
sending packets multiple times to resolve this information.
Added the parent process ID to the ProcessInfo class.
Added a new ProcessInfoMatch class which helps us to match processes up
and changed the Host layer over to using this new class. The new class allows
us to search for processs:
1 - by name (equal to, starts with, ends with, contains, and regex)
2 - by pid
3 - And further check for parent pid == value, uid == value, gid == value,
euid == value, egid == value, arch == value, parent == value.
This is all hookup up to the "platform process list" command which required
adding dumping routines to dump process information. If the Host class
implements the process lookup routines, you can now lists processes on
your local machine:
machine1.foo.com % lldb
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
94727 244 username usergroup username usergroup x86_64-apple-darwin Xcode
92742 92710 username usergroup username usergroup i386-apple-darwin debugserver
This of course also works remotely with the lldb-platform:
machine1.foo.com % lldb-platform --listen 1234
machine2.foo.com % lldb
(lldb) platform create remote-macosx
Platform: remote-macosx
Connected: no
(lldb) platform connect connect://localhost:1444
Platform: remote-macosx
Triple: x86_64-apple-darwin
OS Version: 10.6.7 (10J869)
Kernel: Darwin Kernel Version 10.7.0: Sat Jan 29 15:17:16 PST 2011; root:xnu-1504.9.37~1/RELEASE_I386
Hostname: machine1.foo.com
Connected: yes
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99556 244 username usergroup username usergroup x86_64-apple-darwin trustevaluation
99548 65539 username usergroup username usergroup x86_64-apple-darwin lldb
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
The lldb-platform implements everything with the Host:: layer, so this should
"just work" for linux. I will probably be adding more stuff to the Host layer
for launching processes and attaching to processes so that this support should
eventually just work as well.
Modified the target to be able to be created with an architecture that differs
from the main executable. This is needed for iOS debugging since we can have
an "armv6" binary which can run on an "armv7" machine, so we want to be able
to do:
% lldb
(lldb) platform create remote-ios
(lldb) file --arch armv7 a.out
Where "a.out" is an armv6 executable. The platform then can correctly decide
to open all "armv7" images for all dependent shared libraries.
Modified the disassembly to show the current PC value. Example output:
(lldb) disassemble --frame
a.out`main:
0x1eb7: pushl %ebp
0x1eb8: movl %esp, %ebp
0x1eba: pushl %ebx
0x1ebb: subl $20, %esp
0x1ebe: calll 0x1ec3 ; main + 12 at test.c:18
0x1ec3: popl %ebx
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
0x1edb: leal 213(%ebx), %eax
0x1ee1: movl %eax, (%esp)
0x1ee4: calll 0x1f1e ; puts
0x1ee9: calll 0x1f0c ; getchar
0x1eee: movl $20, (%esp)
0x1ef5: calll 0x1e6a ; sleep_loop at test.c:6
0x1efa: movl $12, %eax
0x1eff: addl $20, %esp
0x1f02: popl %ebx
0x1f03: leave
0x1f04: ret
This can be handy when dealing with the new --line options that was recently
added:
(lldb) disassemble --line
a.out`main + 13 at test.c:19
18 {
-> 19 printf("Process: %i\n\n", getpid());
20 puts("Press any key to continue..."); getchar();
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
Modified the ModuleList to have a lookup based solely on a UUID. Since the
UUID is typically the MD5 checksum of a binary image, there is no need
to give the path and architecture when searching for a pre-existing
image in an image list.
Now that we support remote debugging a bit better, our lldb_private::Module
needs to be able to track what the original path for file was as the platform
knows it, as well as where the file is locally. The module has the two
following functions to retrieve both paths:
const FileSpec &Module::GetFileSpec () const;
const FileSpec &Module::GetPlatformFileSpec () const;
llvm-svn: 128563
2011-03-31 02:16:51 +08:00
& old_module_sp ,
& did_create_module ) ;
}
else
{
error . SetErrorString ( " no platform is currently set " ) ;
2010-06-09 00:52:24 +08:00
}
Many improvements to the Platform base class and subclasses. The base Platform
class now implements the Host functionality for a lot of things that make
sense by default so that subclasses can check:
int
PlatformSubclass::Foo ()
{
if (IsHost())
return Platform::Foo (); // Let the platform base class do the host specific stuff
// Platform subclass specific code...
int result = ...
return result;
}
Added new functions to the platform:
virtual const char *Platform::GetUserName (uint32_t uid);
virtual const char *Platform::GetGroupName (uint32_t gid);
The user and group names are cached locally so that remote platforms can avoid
sending packets multiple times to resolve this information.
Added the parent process ID to the ProcessInfo class.
Added a new ProcessInfoMatch class which helps us to match processes up
and changed the Host layer over to using this new class. The new class allows
us to search for processs:
1 - by name (equal to, starts with, ends with, contains, and regex)
2 - by pid
3 - And further check for parent pid == value, uid == value, gid == value,
euid == value, egid == value, arch == value, parent == value.
This is all hookup up to the "platform process list" command which required
adding dumping routines to dump process information. If the Host class
implements the process lookup routines, you can now lists processes on
your local machine:
machine1.foo.com % lldb
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
94727 244 username usergroup username usergroup x86_64-apple-darwin Xcode
92742 92710 username usergroup username usergroup i386-apple-darwin debugserver
This of course also works remotely with the lldb-platform:
machine1.foo.com % lldb-platform --listen 1234
machine2.foo.com % lldb
(lldb) platform create remote-macosx
Platform: remote-macosx
Connected: no
(lldb) platform connect connect://localhost:1444
Platform: remote-macosx
Triple: x86_64-apple-darwin
OS Version: 10.6.7 (10J869)
Kernel: Darwin Kernel Version 10.7.0: Sat Jan 29 15:17:16 PST 2011; root:xnu-1504.9.37~1/RELEASE_I386
Hostname: machine1.foo.com
Connected: yes
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99556 244 username usergroup username usergroup x86_64-apple-darwin trustevaluation
99548 65539 username usergroup username usergroup x86_64-apple-darwin lldb
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
The lldb-platform implements everything with the Host:: layer, so this should
"just work" for linux. I will probably be adding more stuff to the Host layer
for launching processes and attaching to processes so that this support should
eventually just work as well.
Modified the target to be able to be created with an architecture that differs
from the main executable. This is needed for iOS debugging since we can have
an "armv6" binary which can run on an "armv7" machine, so we want to be able
to do:
% lldb
(lldb) platform create remote-ios
(lldb) file --arch armv7 a.out
Where "a.out" is an armv6 executable. The platform then can correctly decide
to open all "armv7" images for all dependent shared libraries.
Modified the disassembly to show the current PC value. Example output:
(lldb) disassemble --frame
a.out`main:
0x1eb7: pushl %ebp
0x1eb8: movl %esp, %ebp
0x1eba: pushl %ebx
0x1ebb: subl $20, %esp
0x1ebe: calll 0x1ec3 ; main + 12 at test.c:18
0x1ec3: popl %ebx
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
0x1edb: leal 213(%ebx), %eax
0x1ee1: movl %eax, (%esp)
0x1ee4: calll 0x1f1e ; puts
0x1ee9: calll 0x1f0c ; getchar
0x1eee: movl $20, (%esp)
0x1ef5: calll 0x1e6a ; sleep_loop at test.c:6
0x1efa: movl $12, %eax
0x1eff: addl $20, %esp
0x1f02: popl %ebx
0x1f03: leave
0x1f04: ret
This can be handy when dealing with the new --line options that was recently
added:
(lldb) disassemble --line
a.out`main + 13 at test.c:19
18 {
-> 19 printf("Process: %i\n\n", getpid());
20 puts("Press any key to continue..."); getchar();
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
Modified the ModuleList to have a lookup based solely on a UUID. Since the
UUID is typically the MD5 checksum of a binary image, there is no need
to give the path and architecture when searching for a pre-existing
image in an image list.
Now that we support remote debugging a bit better, our lldb_private::Module
needs to be able to track what the original path for file was as the platform
knows it, as well as where the file is locally. The module has the two
following functions to retrieve both paths:
const FileSpec &Module::GetFileSpec () const;
const FileSpec &Module::GetPlatformFileSpec () const;
llvm-svn: 128563
2011-03-31 02:16:51 +08:00
// If a module hasn't been found yet, use the unmodified path.
2010-06-09 00:52:24 +08:00
if ( module_sp )
{
m_images . Append ( module_sp ) ;
if ( did_create_module )
{
if ( old_module_sp & & m_images . GetIndexForModule ( old_module_sp . get ( ) ) ! = LLDB_INVALID_INDEX32 )
ModuleUpdated ( old_module_sp , module_sp ) ;
else
ModuleAdded ( module_sp ) ;
}
}
if ( error_ptr )
* error_ptr = error ;
return module_sp ;
}
2012-02-18 13:35:26 +08:00
TargetSP
2010-06-09 00:52:24 +08:00
Target : : CalculateTarget ( )
{
2012-02-18 13:35:26 +08:00
return shared_from_this ( ) ;
2010-06-09 00:52:24 +08:00
}
2012-02-18 13:35:26 +08:00
ProcessSP
2010-06-09 00:52:24 +08:00
Target : : CalculateProcess ( )
{
2012-02-18 13:35:26 +08:00
return ProcessSP ( ) ;
2010-06-09 00:52:24 +08:00
}
2012-02-18 13:35:26 +08:00
ThreadSP
2010-06-09 00:52:24 +08:00
Target : : CalculateThread ( )
{
2012-02-18 13:35:26 +08:00
return ThreadSP ( ) ;
2010-06-09 00:52:24 +08:00
}
2012-02-18 13:35:26 +08:00
StackFrameSP
2010-06-09 00:52:24 +08:00
Target : : CalculateStackFrame ( )
{
2012-02-18 13:35:26 +08:00
return StackFrameSP ( ) ;
2010-06-09 00:52:24 +08:00
}
void
2010-10-04 09:05:56 +08:00
Target : : CalculateExecutionContext ( ExecutionContext & exe_ctx )
2010-06-09 00:52:24 +08:00
{
2011-09-22 12:58:26 +08:00
exe_ctx . Clear ( ) ;
exe_ctx . SetTargetPtr ( this ) ;
2010-06-09 00:52:24 +08:00
}
PathMappingList &
Target : : GetImageSearchPathList ( )
{
return m_image_search_paths ;
}
void
Target : : ImageSearchPathsChanged
(
const PathMappingList & path_list ,
void * baton
)
{
Target * target = ( Target * ) baton ;
2011-08-11 10:48:45 +08:00
ModuleSP exe_module_sp ( target - > GetExecutableModule ( ) ) ;
if ( exe_module_sp )
2010-06-09 00:52:24 +08:00
{
2011-08-11 10:48:45 +08:00
target - > m_images . Clear ( ) ;
target - > SetExecutableModule ( exe_module_sp , true ) ;
2010-06-09 00:52:24 +08:00
}
}
ClangASTContext *
2011-12-01 07:18:53 +08:00
Target : : GetScratchClangASTContext ( bool create_on_demand )
2010-06-09 00:52:24 +08:00
{
2011-08-03 09:23:55 +08:00
// Now see if we know the target triple, and if so, create our scratch AST context:
2011-12-01 07:18:53 +08:00
if ( m_scratch_ast_context_ap . get ( ) = = NULL & & m_arch . IsValid ( ) & & create_on_demand )
2011-11-16 06:27:19 +08:00
{
2011-08-03 09:23:55 +08:00
m_scratch_ast_context_ap . reset ( new ClangASTContext ( m_arch . GetTriple ( ) . str ( ) . c_str ( ) ) ) ;
2012-01-30 04:56:30 +08:00
m_scratch_ast_source_ap . reset ( new ClangASTSource ( shared_from_this ( ) ) ) ;
2011-11-16 06:27:19 +08:00
m_scratch_ast_source_ap - > InstallASTContext ( m_scratch_ast_context_ap - > getASTContext ( ) ) ;
llvm : : OwningPtr < clang : : ExternalASTSource > proxy_ast_source ( m_scratch_ast_source_ap - > CreateProxy ( ) ) ;
m_scratch_ast_context_ap - > SetExternalSource ( proxy_ast_source ) ;
}
2010-06-09 00:52:24 +08:00
return m_scratch_ast_context_ap . get ( ) ;
}
2010-09-21 04:44:43 +08:00
2011-11-17 02:20:47 +08:00
ClangASTImporter *
Target : : GetClangASTImporter ( )
{
ClangASTImporter * ast_importer = m_ast_importer_ap . get ( ) ;
if ( ! ast_importer )
{
ast_importer = new ClangASTImporter ( ) ;
m_ast_importer_ap . reset ( ast_importer ) ;
}
return ast_importer ;
}
2010-11-19 07:32:35 +08:00
void
2011-03-11 06:14:10 +08:00
Target : : SettingsInitialize ( )
2010-09-21 04:44:43 +08:00
{
2012-01-30 15:41:31 +08:00
UserSettingsController : : InitializeSettingsController ( GetSettingsController ( ) ,
2010-11-19 07:32:35 +08:00
SettingsController : : global_settings_table ,
SettingsController : : instance_settings_table ) ;
2011-03-11 06:14:10 +08:00
// Now call SettingsInitialize() on each 'child' setting of Target
Process : : SettingsInitialize ( ) ;
2010-11-19 07:32:35 +08:00
}
2010-09-21 04:44:43 +08:00
2010-11-19 07:32:35 +08:00
void
2011-03-11 06:14:10 +08:00
Target : : SettingsTerminate ( )
2010-11-19 07:32:35 +08:00
{
2011-03-11 06:14:10 +08:00
// Must call SettingsTerminate() on each settings 'child' of Target, before terminating Target's Settings.
Process : : SettingsTerminate ( ) ;
// Now terminate Target Settings.
2010-11-19 07:32:35 +08:00
UserSettingsControllerSP & usc = GetSettingsController ( ) ;
UserSettingsController : : FinalizeSettingsController ( usc ) ;
usc . reset ( ) ;
}
2010-09-21 04:44:43 +08:00
2010-11-19 07:32:35 +08:00
UserSettingsControllerSP &
Target : : GetSettingsController ( )
{
2012-01-30 15:41:31 +08:00
static UserSettingsControllerSP g_settings_controller_sp ;
if ( ! g_settings_controller_sp )
{
g_settings_controller_sp . reset ( new Target : : SettingsController ) ;
// The first shared pointer to Target::SettingsController in
// g_settings_controller_sp must be fully created above so that
// the TargetInstanceSettings can use a weak_ptr to refer back
// to the master setttings controller
InstanceSettingsSP default_instance_settings_sp ( new TargetInstanceSettings ( g_settings_controller_sp ,
false ,
InstanceSettings : : GetDefaultName ( ) . AsCString ( ) ) ) ;
g_settings_controller_sp - > SetDefaultInstanceSettings ( default_instance_settings_sp ) ;
}
return g_settings_controller_sp ;
2010-09-21 04:44:43 +08:00
}
2012-02-14 07:10:39 +08:00
FileSpecList
Target : : GetDefaultExecutableSearchPaths ( )
{
lldb : : UserSettingsControllerSP settings_controller_sp ( GetSettingsController ( ) ) ;
if ( settings_controller_sp )
{
lldb : : InstanceSettingsSP instance_settings_sp ( settings_controller_sp - > GetDefaultInstanceSettings ( ) ) ;
if ( instance_settings_sp )
return static_cast < TargetInstanceSettings * > ( instance_settings_sp . get ( ) ) - > GetExecutableSearchPaths ( ) ;
}
return FileSpecList ( ) ;
}
2010-09-21 04:44:43 +08:00
ArchSpec
Target : : GetDefaultArchitecture ( )
{
2011-02-23 08:35:02 +08:00
lldb : : UserSettingsControllerSP settings_controller_sp ( GetSettingsController ( ) ) ;
if ( settings_controller_sp )
return static_cast < Target : : SettingsController * > ( settings_controller_sp . get ( ) ) - > GetArchitecture ( ) ;
return ArchSpec ( ) ;
2010-09-21 04:44:43 +08:00
}
void
2011-02-23 08:35:02 +08:00
Target : : SetDefaultArchitecture ( const ArchSpec & arch )
2010-09-21 04:44:43 +08:00
{
2011-02-23 08:35:02 +08:00
lldb : : UserSettingsControllerSP settings_controller_sp ( GetSettingsController ( ) ) ;
if ( settings_controller_sp )
static_cast < Target : : SettingsController * > ( settings_controller_sp . get ( ) ) - > GetArchitecture ( ) = arch ;
2010-09-21 04:44:43 +08:00
}
2010-10-04 09:05:56 +08:00
Target *
Target : : GetTargetFromContexts ( const ExecutionContext * exe_ctx_ptr , const SymbolContext * sc_ptr )
{
// The target can either exist in the "process" of ExecutionContext, or in
// the "target_sp" member of SymbolContext. This accessor helper function
// will get the target from one of these locations.
Target * target = NULL ;
if ( sc_ptr ! = NULL )
target = sc_ptr - > target_sp . get ( ) ;
2011-09-22 12:58:26 +08:00
if ( target = = NULL & & exe_ctx_ptr )
target = exe_ctx_ptr - > GetTargetPtr ( ) ;
2010-10-04 09:05:56 +08:00
return target ;
}
2010-09-27 08:30:10 +08:00
void
Target : : UpdateInstanceName ( )
{
StreamString sstr ;
2011-08-11 10:48:45 +08:00
Module * exe_module = GetExecutableModulePointer ( ) ;
if ( exe_module )
2010-09-27 08:30:10 +08:00
{
2010-10-27 10:06:37 +08:00
sstr . Printf ( " %s_%s " ,
2011-08-11 10:48:45 +08:00
exe_module - > GetFileSpec ( ) . GetFilename ( ) . AsCString ( ) ,
exe_module - > GetArchitecture ( ) . GetArchitectureName ( ) ) ;
GetSettingsController ( ) - > RenameInstanceSettings ( GetInstanceName ( ) . AsCString ( ) , sstr . GetData ( ) ) ;
2010-09-27 08:30:10 +08:00
}
}
2010-10-29 08:29:03 +08:00
const char *
Target : : GetExpressionPrefixContentsAsCString ( )
{
2011-11-16 09:54:57 +08:00
if ( ! m_expr_prefix_contents . empty ( ) )
return m_expr_prefix_contents . c_str ( ) ;
2011-04-23 10:04:55 +08:00
return NULL ;
2010-10-29 08:29:03 +08:00
}
2010-12-14 10:59:59 +08:00
ExecutionResults
Target : : EvaluateExpression
(
const char * expr_cstr ,
StackFrame * frame ,
This patch modifies the expression parser to allow it
to execute expressions even in the absence of a process.
This allows expressions to run in situations where the
target cannot run -- e.g., to perform calculations based
on type information, or to inspect a binary's static
data.
This modification touches the following files:
lldb-private-enumerations.h
Introduce a new enum specifying the policy for
processing an expression. Some expressions should
always be JITted, for example if they are functions
that will be used over and over again. Some
expressions should always be interpreted, for
example if the target is unsafe to run. For most,
it is acceptable to JIT them, but interpretation
is preferable when possible.
Target.[h,cpp]
Have EvaluateExpression now accept the new enum.
ClangExpressionDeclMap.[cpp,h]
Add support for the IR interpreter and also make
the ClangExpressionDeclMap more robust in the
absence of a process.
ClangFunction.[cpp,h]
Add support for the new enum.
IRInterpreter.[cpp,h]
New implementation.
ClangUserExpression.[cpp,h]
Add support for the new enum, and for running
expressions in the absence of a process.
ClangExpression.h
Remove references to the old DWARF-based method
of evaluating expressions, because it has been
superseded for now.
ClangUtilityFunction.[cpp,h]
Add support for the new enum.
ClangExpressionParser.[cpp,h]
Add support for the new enum, remove references
to DWARF, and add support for checking whether
the expression could be evaluated statically.
IRForTarget.[h,cpp]
Add support for the new enum, and add utility
functions to support the interpreter.
IRToDWARF.cpp
Removed
CommandObjectExpression.cpp
Remove references to the obsolete -i option.
Process.cpp
Modify calls to ClangUserExpression::Evaluate
to pass the correct enum (for dlopen/dlclose)
SBValue.cpp
Add support for the new enum.
SBFrame.cpp
Add support for he new enum.
BreakpointOptions.cpp
Add support for the new enum.
llvm-svn: 139772
2011-09-15 10:13:07 +08:00
lldb_private : : ExecutionPolicy execution_policy ,
2011-12-22 06:22:58 +08:00
bool coerce_to_id ,
2010-12-14 10:59:59 +08:00
bool unwind_on_error ,
2011-01-13 16:53:35 +08:00
bool keep_in_memory ,
2011-05-04 11:43:18 +08:00
lldb : : DynamicValueType use_dynamic ,
2010-12-14 10:59:59 +08:00
lldb : : ValueObjectSP & result_valobj_sp
)
{
ExecutionResults execution_results = eExecutionSetupError ;
result_valobj_sp . reset ( ) ;
2011-12-08 10:13:16 +08:00
if ( expr_cstr = = NULL | | expr_cstr [ 0 ] = = ' \0 ' )
return execution_results ;
2011-05-12 10:06:14 +08:00
// We shouldn't run stop hooks in expressions.
// Be sure to reset this if you return anywhere within this function.
bool old_suppress_value = m_suppress_stop_hooks ;
m_suppress_stop_hooks = true ;
2010-12-14 10:59:59 +08:00
ExecutionContext exe_ctx ;
2011-12-08 10:13:16 +08:00
const size_t expr_cstr_len = : : strlen ( expr_cstr ) ;
2010-12-14 10:59:59 +08:00
if ( frame )
{
frame - > CalculateExecutionContext ( exe_ctx ) ;
2010-12-15 13:08:08 +08:00
Error error ;
2011-01-21 03:27:18 +08:00
const uint32_t expr_path_options = StackFrame : : eExpressionPathOptionCheckPtrVsMember |
2011-08-09 09:04:56 +08:00
StackFrame : : eExpressionPathOptionsNoFragileObjcIvar |
StackFrame : : eExpressionPathOptionsNoSyntheticChildren ;
2011-05-04 11:43:18 +08:00
lldb : : VariableSP var_sp ;
2011-12-08 10:13:16 +08:00
// Make sure we don't have any things that we know a variable expression
// won't be able to deal with before calling into it
if ( : : strcspn ( expr_cstr , " ()+*&|!~<=/^%,? " ) = = expr_cstr_len )
{
result_valobj_sp = frame - > GetValueForVariableExpressionPath ( expr_cstr ,
use_dynamic ,
expr_path_options ,
var_sp ,
error ) ;
}
2010-12-14 10:59:59 +08:00
}
else if ( m_process_sp )
{
m_process_sp - > CalculateExecutionContext ( exe_ctx ) ;
}
else
{
CalculateExecutionContext ( exe_ctx ) ;
}
if ( result_valobj_sp )
{
execution_results = eExecutionCompleted ;
// We got a result from the frame variable expression path above...
ConstString persistent_variable_name ( m_persistent_variables . GetNextPersistentVariableName ( ) ) ;
lldb : : ValueObjectSP const_valobj_sp ;
// Check in case our value is already a constant value
if ( result_valobj_sp - > GetIsConstant ( ) )
{
const_valobj_sp = result_valobj_sp ;
const_valobj_sp - > SetName ( persistent_variable_name ) ;
}
else
2011-04-16 08:01:13 +08:00
{
2011-05-04 11:43:18 +08:00
if ( use_dynamic ! = lldb : : eNoDynamicValues )
2011-04-16 08:01:13 +08:00
{
2011-05-04 11:43:18 +08:00
ValueObjectSP dynamic_sp = result_valobj_sp - > GetDynamicValue ( use_dynamic ) ;
2011-04-16 08:01:13 +08:00
if ( dynamic_sp )
result_valobj_sp = dynamic_sp ;
}
2011-03-31 08:19:25 +08:00
const_valobj_sp = result_valobj_sp - > CreateConstantValue ( persistent_variable_name ) ;
2011-04-16 08:01:13 +08:00
}
2010-12-14 10:59:59 +08:00
2011-01-13 16:53:35 +08:00
lldb : : ValueObjectSP live_valobj_sp = result_valobj_sp ;
2010-12-14 10:59:59 +08:00
result_valobj_sp = const_valobj_sp ;
2011-01-13 16:53:35 +08:00
ClangExpressionVariableSP clang_expr_variable_sp ( m_persistent_variables . CreatePersistentVariable ( result_valobj_sp ) ) ;
assert ( clang_expr_variable_sp . get ( ) ) ;
// Set flags and live data as appropriate
const Value & result_value = live_valobj_sp - > GetValue ( ) ;
switch ( result_value . GetValueType ( ) )
{
case Value : : eValueTypeHostAddress :
case Value : : eValueTypeFileAddress :
// we don't do anything with these for now
break ;
case Value : : eValueTypeScalar :
clang_expr_variable_sp - > m_flags | = ClangExpressionVariable : : EVIsLLDBAllocated ;
clang_expr_variable_sp - > m_flags | = ClangExpressionVariable : : EVNeedsAllocation ;
break ;
case Value : : eValueTypeLoadAddress :
clang_expr_variable_sp - > m_live_sp = live_valobj_sp ;
clang_expr_variable_sp - > m_flags | = ClangExpressionVariable : : EVIsProgramReference ;
break ;
}
2010-12-14 10:59:59 +08:00
}
else
{
// Make sure we aren't just trying to see the value of a persistent
// variable (something like "$0")
2011-01-10 05:07:35 +08:00
lldb : : ClangExpressionVariableSP persistent_var_sp ;
// Only check for persistent variables the expression starts with a '$'
if ( expr_cstr [ 0 ] = = ' $ ' )
persistent_var_sp = m_persistent_variables . GetVariable ( expr_cstr ) ;
2010-12-14 10:59:59 +08:00
if ( persistent_var_sp )
{
result_valobj_sp = persistent_var_sp - > GetValueObject ( ) ;
execution_results = eExecutionCompleted ;
}
else
{
const char * prefix = GetExpressionPrefixContentsAsCString ( ) ;
This patch modifies the expression parser to allow it
to execute expressions even in the absence of a process.
This allows expressions to run in situations where the
target cannot run -- e.g., to perform calculations based
on type information, or to inspect a binary's static
data.
This modification touches the following files:
lldb-private-enumerations.h
Introduce a new enum specifying the policy for
processing an expression. Some expressions should
always be JITted, for example if they are functions
that will be used over and over again. Some
expressions should always be interpreted, for
example if the target is unsafe to run. For most,
it is acceptable to JIT them, but interpretation
is preferable when possible.
Target.[h,cpp]
Have EvaluateExpression now accept the new enum.
ClangExpressionDeclMap.[cpp,h]
Add support for the IR interpreter and also make
the ClangExpressionDeclMap more robust in the
absence of a process.
ClangFunction.[cpp,h]
Add support for the new enum.
IRInterpreter.[cpp,h]
New implementation.
ClangUserExpression.[cpp,h]
Add support for the new enum, and for running
expressions in the absence of a process.
ClangExpression.h
Remove references to the old DWARF-based method
of evaluating expressions, because it has been
superseded for now.
ClangUtilityFunction.[cpp,h]
Add support for the new enum.
ClangExpressionParser.[cpp,h]
Add support for the new enum, remove references
to DWARF, and add support for checking whether
the expression could be evaluated statically.
IRForTarget.[h,cpp]
Add support for the new enum, and add utility
functions to support the interpreter.
IRToDWARF.cpp
Removed
CommandObjectExpression.cpp
Remove references to the obsolete -i option.
Process.cpp
Modify calls to ClangUserExpression::Evaluate
to pass the correct enum (for dlopen/dlclose)
SBValue.cpp
Add support for the new enum.
SBFrame.cpp
Add support for he new enum.
BreakpointOptions.cpp
Add support for the new enum.
llvm-svn: 139772
2011-09-15 10:13:07 +08:00
2010-12-14 10:59:59 +08:00
execution_results = ClangUserExpression : : Evaluate ( exe_ctx ,
This patch modifies the expression parser to allow it
to execute expressions even in the absence of a process.
This allows expressions to run in situations where the
target cannot run -- e.g., to perform calculations based
on type information, or to inspect a binary's static
data.
This modification touches the following files:
lldb-private-enumerations.h
Introduce a new enum specifying the policy for
processing an expression. Some expressions should
always be JITted, for example if they are functions
that will be used over and over again. Some
expressions should always be interpreted, for
example if the target is unsafe to run. For most,
it is acceptable to JIT them, but interpretation
is preferable when possible.
Target.[h,cpp]
Have EvaluateExpression now accept the new enum.
ClangExpressionDeclMap.[cpp,h]
Add support for the IR interpreter and also make
the ClangExpressionDeclMap more robust in the
absence of a process.
ClangFunction.[cpp,h]
Add support for the new enum.
IRInterpreter.[cpp,h]
New implementation.
ClangUserExpression.[cpp,h]
Add support for the new enum, and for running
expressions in the absence of a process.
ClangExpression.h
Remove references to the old DWARF-based method
of evaluating expressions, because it has been
superseded for now.
ClangUtilityFunction.[cpp,h]
Add support for the new enum.
ClangExpressionParser.[cpp,h]
Add support for the new enum, remove references
to DWARF, and add support for checking whether
the expression could be evaluated statically.
IRForTarget.[h,cpp]
Add support for the new enum, and add utility
functions to support the interpreter.
IRToDWARF.cpp
Removed
CommandObjectExpression.cpp
Remove references to the obsolete -i option.
Process.cpp
Modify calls to ClangUserExpression::Evaluate
to pass the correct enum (for dlopen/dlclose)
SBValue.cpp
Add support for the new enum.
SBFrame.cpp
Add support for he new enum.
BreakpointOptions.cpp
Add support for the new enum.
llvm-svn: 139772
2011-09-15 10:13:07 +08:00
execution_policy ,
2011-11-08 07:35:40 +08:00
lldb : : eLanguageTypeUnknown ,
2011-12-22 06:22:58 +08:00
coerce_to_id ? ClangUserExpression : : eResultTypeId : ClangUserExpression : : eResultTypeAny ,
2011-01-13 16:53:35 +08:00
unwind_on_error ,
2010-12-14 10:59:59 +08:00
expr_cstr ,
prefix ,
result_valobj_sp ) ;
}
}
2011-05-12 10:06:14 +08:00
m_suppress_stop_hooks = old_suppress_value ;
2010-12-14 10:59:59 +08:00
return execution_results ;
}
Added new lldb_private::Process memory read/write functions to stop a bunch
of duplicated code from appearing all over LLDB:
lldb::addr_t
Process::ReadPointerFromMemory (lldb::addr_t vm_addr, Error &error);
bool
Process::WritePointerToMemory (lldb::addr_t vm_addr, lldb::addr_t ptr_value, Error &error);
size_t
Process::ReadScalarIntegerFromMemory (lldb::addr_t addr, uint32_t byte_size, bool is_signed, Scalar &scalar, Error &error);
size_t
Process::WriteScalarToMemory (lldb::addr_t vm_addr, const Scalar &scalar, uint32_t size, Error &error);
in lldb_private::Process the following functions were renamed:
From:
uint64_t
Process::ReadUnsignedInteger (lldb::addr_t load_addr,
size_t byte_size,
Error &error);
To:
uint64_t
Process::ReadUnsignedIntegerFromMemory (lldb::addr_t load_addr,
size_t byte_size,
uint64_t fail_value,
Error &error);
Cleaned up a lot of code that was manually doing what the above functions do
to use the functions listed above.
Added the ability to get a scalar value as a buffer that can be written down
to a process (byte swapping the Scalar value if needed):
uint32_t
Scalar::GetAsMemoryData (void *dst,
uint32_t dst_len,
lldb::ByteOrder dst_byte_order,
Error &error) const;
The "dst_len" can be smaller that the size of the scalar and the least
significant bytes will be written. "dst_len" can also be larger and the
most significant bytes will be padded with zeroes.
Centralized the code that adds or removes address bits for callable and opcode
addresses into lldb_private::Target:
lldb::addr_t
Target::GetCallableLoadAddress (lldb::addr_t load_addr, AddressClass addr_class) const;
lldb::addr_t
Target::GetOpcodeLoadAddress (lldb::addr_t load_addr, AddressClass addr_class) const;
All necessary lldb_private::Address functions now use the target versions so
changes should only need to happen in one place if anything needs updating.
Fixed up a lot of places that were calling :
addr_t
Address::GetLoadAddress(Target*);
to call the Address::GetCallableLoadAddress() or Address::GetOpcodeLoadAddress()
as needed. There were many places in the breakpoint code where things could
go wrong for ARM if these weren't used.
llvm-svn: 131878
2011-05-23 06:46:53 +08:00
lldb : : addr_t
Target : : GetCallableLoadAddress ( lldb : : addr_t load_addr , AddressClass addr_class ) const
{
addr_t code_addr = load_addr ;
switch ( m_arch . GetMachine ( ) )
{
case llvm : : Triple : : arm :
case llvm : : Triple : : thumb :
switch ( addr_class )
{
case eAddressClassData :
case eAddressClassDebug :
return LLDB_INVALID_ADDRESS ;
case eAddressClassUnknown :
case eAddressClassInvalid :
case eAddressClassCode :
case eAddressClassCodeAlternateISA :
case eAddressClassRuntime :
// Check if bit zero it no set?
if ( ( code_addr & 1ull ) = = 0 )
{
// Bit zero isn't set, check if the address is a multiple of 2?
if ( code_addr & 2ull )
{
// The address is a multiple of 2 so it must be thumb, set bit zero
code_addr | = 1ull ;
}
else if ( addr_class = = eAddressClassCodeAlternateISA )
{
// We checked the address and the address claims to be the alternate ISA
// which means thumb, so set bit zero.
code_addr | = 1ull ;
}
}
break ;
}
break ;
default :
break ;
}
return code_addr ;
}
lldb : : addr_t
Target : : GetOpcodeLoadAddress ( lldb : : addr_t load_addr , AddressClass addr_class ) const
{
addr_t opcode_addr = load_addr ;
switch ( m_arch . GetMachine ( ) )
{
case llvm : : Triple : : arm :
case llvm : : Triple : : thumb :
switch ( addr_class )
{
case eAddressClassData :
case eAddressClassDebug :
return LLDB_INVALID_ADDRESS ;
case eAddressClassInvalid :
case eAddressClassUnknown :
case eAddressClassCode :
case eAddressClassCodeAlternateISA :
case eAddressClassRuntime :
opcode_addr & = ~ ( 1ull ) ;
break ;
}
break ;
default :
break ;
}
return opcode_addr ;
}
Add a first pass at a "stop hook" mechanism. This allows you to add commands that get run every time the debugger stops, whether due to a breakpoint, the end of a step, interrupt, etc. You can also specify in which context you want the stop hook to run, for instance only on a particular thread, or only in a particular shared library, function, file, line range within a file.
Still need to add "in methods of a class" to the specifiers, and the ability to write the stop hooks in the Scripting language as well as in the Command Language.
llvm-svn: 127457
2011-03-11 11:53:59 +08:00
lldb : : user_id_t
Target : : AddStopHook ( Target : : StopHookSP & new_hook_sp )
{
lldb : : user_id_t new_uid = + + m_stop_hook_next_id ;
2012-01-30 04:56:30 +08:00
new_hook_sp . reset ( new StopHook ( shared_from_this ( ) , new_uid ) ) ;
Add a first pass at a "stop hook" mechanism. This allows you to add commands that get run every time the debugger stops, whether due to a breakpoint, the end of a step, interrupt, etc. You can also specify in which context you want the stop hook to run, for instance only on a particular thread, or only in a particular shared library, function, file, line range within a file.
Still need to add "in methods of a class" to the specifiers, and the ability to write the stop hooks in the Scripting language as well as in the Command Language.
llvm-svn: 127457
2011-03-11 11:53:59 +08:00
m_stop_hooks [ new_uid ] = new_hook_sp ;
return new_uid ;
}
bool
Target : : RemoveStopHookByID ( lldb : : user_id_t user_id )
{
size_t num_removed ;
num_removed = m_stop_hooks . erase ( user_id ) ;
if ( num_removed = = 0 )
return false ;
else
return true ;
}
void
Target : : RemoveAllStopHooks ( )
{
m_stop_hooks . clear ( ) ;
}
Target : : StopHookSP
Target : : GetStopHookByID ( lldb : : user_id_t user_id )
{
StopHookSP found_hook ;
StopHookCollection : : iterator specified_hook_iter ;
specified_hook_iter = m_stop_hooks . find ( user_id ) ;
if ( specified_hook_iter ! = m_stop_hooks . end ( ) )
found_hook = ( * specified_hook_iter ) . second ;
return found_hook ;
}
bool
Target : : SetStopHookActiveStateByID ( lldb : : user_id_t user_id , bool active_state )
{
StopHookCollection : : iterator specified_hook_iter ;
specified_hook_iter = m_stop_hooks . find ( user_id ) ;
if ( specified_hook_iter = = m_stop_hooks . end ( ) )
return false ;
( * specified_hook_iter ) . second - > SetIsActive ( active_state ) ;
return true ;
}
void
Target : : SetAllStopHooksActiveState ( bool active_state )
{
StopHookCollection : : iterator pos , end = m_stop_hooks . end ( ) ;
for ( pos = m_stop_hooks . begin ( ) ; pos ! = end ; pos + + )
{
( * pos ) . second - > SetIsActive ( active_state ) ;
}
}
void
Target : : RunStopHooks ( )
{
2011-05-12 10:06:14 +08:00
if ( m_suppress_stop_hooks )
return ;
Add a first pass at a "stop hook" mechanism. This allows you to add commands that get run every time the debugger stops, whether due to a breakpoint, the end of a step, interrupt, etc. You can also specify in which context you want the stop hook to run, for instance only on a particular thread, or only in a particular shared library, function, file, line range within a file.
Still need to add "in methods of a class" to the specifiers, and the ability to write the stop hooks in the Scripting language as well as in the Command Language.
llvm-svn: 127457
2011-03-11 11:53:59 +08:00
if ( ! m_process_sp )
return ;
if ( m_stop_hooks . empty ( ) )
return ;
StopHookCollection : : iterator pos , end = m_stop_hooks . end ( ) ;
// If there aren't any active stop hooks, don't bother either:
bool any_active_hooks = false ;
for ( pos = m_stop_hooks . begin ( ) ; pos ! = end ; pos + + )
{
if ( ( * pos ) . second - > IsActive ( ) )
{
any_active_hooks = true ;
break ;
}
}
if ( ! any_active_hooks )
return ;
CommandReturnObject result ;
std : : vector < ExecutionContext > exc_ctx_with_reasons ;
std : : vector < SymbolContext > sym_ctx_with_reasons ;
ThreadList & cur_threadlist = m_process_sp - > GetThreadList ( ) ;
size_t num_threads = cur_threadlist . GetSize ( ) ;
for ( size_t i = 0 ; i < num_threads ; i + + )
{
lldb : : ThreadSP cur_thread_sp = cur_threadlist . GetThreadAtIndex ( i ) ;
if ( cur_thread_sp - > ThreadStoppedForAReason ( ) )
{
lldb : : StackFrameSP cur_frame_sp = cur_thread_sp - > GetStackFrameAtIndex ( 0 ) ;
exc_ctx_with_reasons . push_back ( ExecutionContext ( m_process_sp . get ( ) , cur_thread_sp . get ( ) , cur_frame_sp . get ( ) ) ) ;
sym_ctx_with_reasons . push_back ( cur_frame_sp - > GetSymbolContext ( eSymbolContextEverything ) ) ;
}
}
// If no threads stopped for a reason, don't run the stop-hooks.
size_t num_exe_ctx = exc_ctx_with_reasons . size ( ) ;
if ( num_exe_ctx = = 0 )
return ;
2011-06-03 07:58:26 +08:00
result . SetImmediateOutputStream ( m_debugger . GetAsyncOutputStream ( ) ) ;
result . SetImmediateErrorStream ( m_debugger . GetAsyncErrorStream ( ) ) ;
Add a first pass at a "stop hook" mechanism. This allows you to add commands that get run every time the debugger stops, whether due to a breakpoint, the end of a step, interrupt, etc. You can also specify in which context you want the stop hook to run, for instance only on a particular thread, or only in a particular shared library, function, file, line range within a file.
Still need to add "in methods of a class" to the specifiers, and the ability to write the stop hooks in the Scripting language as well as in the Command Language.
llvm-svn: 127457
2011-03-11 11:53:59 +08:00
bool keep_going = true ;
bool hooks_ran = false ;
2011-03-22 09:47:27 +08:00
bool print_hook_header ;
bool print_thread_header ;
if ( num_exe_ctx = = 1 )
print_thread_header = false ;
else
print_thread_header = true ;
if ( m_stop_hooks . size ( ) = = 1 )
print_hook_header = false ;
else
print_hook_header = true ;
Add a first pass at a "stop hook" mechanism. This allows you to add commands that get run every time the debugger stops, whether due to a breakpoint, the end of a step, interrupt, etc. You can also specify in which context you want the stop hook to run, for instance only on a particular thread, or only in a particular shared library, function, file, line range within a file.
Still need to add "in methods of a class" to the specifiers, and the ability to write the stop hooks in the Scripting language as well as in the Command Language.
llvm-svn: 127457
2011-03-11 11:53:59 +08:00
for ( pos = m_stop_hooks . begin ( ) ; keep_going & & pos ! = end ; pos + + )
{
// result.Clear();
StopHookSP cur_hook_sp = ( * pos ) . second ;
if ( ! cur_hook_sp - > IsActive ( ) )
continue ;
bool any_thread_matched = false ;
for ( size_t i = 0 ; keep_going & & i < num_exe_ctx ; i + + )
{
if ( ( cur_hook_sp - > GetSpecifier ( ) = = NULL
| | cur_hook_sp - > GetSpecifier ( ) - > SymbolContextMatches ( sym_ctx_with_reasons [ i ] ) )
& & ( cur_hook_sp - > GetThreadSpecifier ( ) = = NULL
2011-09-22 12:58:26 +08:00
| | cur_hook_sp - > GetThreadSpecifier ( ) - > ThreadPassesBasicTests ( exc_ctx_with_reasons [ i ] . GetThreadPtr ( ) ) ) )
Add a first pass at a "stop hook" mechanism. This allows you to add commands that get run every time the debugger stops, whether due to a breakpoint, the end of a step, interrupt, etc. You can also specify in which context you want the stop hook to run, for instance only on a particular thread, or only in a particular shared library, function, file, line range within a file.
Still need to add "in methods of a class" to the specifiers, and the ability to write the stop hooks in the Scripting language as well as in the Command Language.
llvm-svn: 127457
2011-03-11 11:53:59 +08:00
{
if ( ! hooks_ran )
{
hooks_ran = true ;
}
2011-03-22 09:47:27 +08:00
if ( print_hook_header & & ! any_thread_matched )
Add a first pass at a "stop hook" mechanism. This allows you to add commands that get run every time the debugger stops, whether due to a breakpoint, the end of a step, interrupt, etc. You can also specify in which context you want the stop hook to run, for instance only on a particular thread, or only in a particular shared library, function, file, line range within a file.
Still need to add "in methods of a class" to the specifiers, and the ability to write the stop hooks in the Scripting language as well as in the Command Language.
llvm-svn: 127457
2011-03-11 11:53:59 +08:00
{
2011-10-25 07:01:06 +08:00
const char * cmd = ( cur_hook_sp - > GetCommands ( ) . GetSize ( ) = = 1 ?
cur_hook_sp - > GetCommands ( ) . GetStringAtIndex ( 0 ) :
NULL ) ;
if ( cmd )
result . AppendMessageWithFormat ( " \n - Hook %llu (%s) \n " , cur_hook_sp - > GetID ( ) , cmd ) ;
else
result . AppendMessageWithFormat ( " \n - Hook %llu \n " , cur_hook_sp - > GetID ( ) ) ;
Add a first pass at a "stop hook" mechanism. This allows you to add commands that get run every time the debugger stops, whether due to a breakpoint, the end of a step, interrupt, etc. You can also specify in which context you want the stop hook to run, for instance only on a particular thread, or only in a particular shared library, function, file, line range within a file.
Still need to add "in methods of a class" to the specifiers, and the ability to write the stop hooks in the Scripting language as well as in the Command Language.
llvm-svn: 127457
2011-03-11 11:53:59 +08:00
any_thread_matched = true ;
}
2011-03-22 09:47:27 +08:00
if ( print_thread_header )
2011-09-22 12:58:26 +08:00
result . AppendMessageWithFormat ( " -- Thread %d \n " , exc_ctx_with_reasons [ i ] . GetThreadPtr ( ) - > GetIndexID ( ) ) ;
Add a first pass at a "stop hook" mechanism. This allows you to add commands that get run every time the debugger stops, whether due to a breakpoint, the end of a step, interrupt, etc. You can also specify in which context you want the stop hook to run, for instance only on a particular thread, or only in a particular shared library, function, file, line range within a file.
Still need to add "in methods of a class" to the specifiers, and the ability to write the stop hooks in the Scripting language as well as in the Command Language.
llvm-svn: 127457
2011-03-11 11:53:59 +08:00
bool stop_on_continue = true ;
bool stop_on_error = true ;
bool echo_commands = false ;
bool print_results = true ;
GetDebugger ( ) . GetCommandInterpreter ( ) . HandleCommands ( cur_hook_sp - > GetCommands ( ) ,
Many improvements to the Platform base class and subclasses. The base Platform
class now implements the Host functionality for a lot of things that make
sense by default so that subclasses can check:
int
PlatformSubclass::Foo ()
{
if (IsHost())
return Platform::Foo (); // Let the platform base class do the host specific stuff
// Platform subclass specific code...
int result = ...
return result;
}
Added new functions to the platform:
virtual const char *Platform::GetUserName (uint32_t uid);
virtual const char *Platform::GetGroupName (uint32_t gid);
The user and group names are cached locally so that remote platforms can avoid
sending packets multiple times to resolve this information.
Added the parent process ID to the ProcessInfo class.
Added a new ProcessInfoMatch class which helps us to match processes up
and changed the Host layer over to using this new class. The new class allows
us to search for processs:
1 - by name (equal to, starts with, ends with, contains, and regex)
2 - by pid
3 - And further check for parent pid == value, uid == value, gid == value,
euid == value, egid == value, arch == value, parent == value.
This is all hookup up to the "platform process list" command which required
adding dumping routines to dump process information. If the Host class
implements the process lookup routines, you can now lists processes on
your local machine:
machine1.foo.com % lldb
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
94727 244 username usergroup username usergroup x86_64-apple-darwin Xcode
92742 92710 username usergroup username usergroup i386-apple-darwin debugserver
This of course also works remotely with the lldb-platform:
machine1.foo.com % lldb-platform --listen 1234
machine2.foo.com % lldb
(lldb) platform create remote-macosx
Platform: remote-macosx
Connected: no
(lldb) platform connect connect://localhost:1444
Platform: remote-macosx
Triple: x86_64-apple-darwin
OS Version: 10.6.7 (10J869)
Kernel: Darwin Kernel Version 10.7.0: Sat Jan 29 15:17:16 PST 2011; root:xnu-1504.9.37~1/RELEASE_I386
Hostname: machine1.foo.com
Connected: yes
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99556 244 username usergroup username usergroup x86_64-apple-darwin trustevaluation
99548 65539 username usergroup username usergroup x86_64-apple-darwin lldb
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
The lldb-platform implements everything with the Host:: layer, so this should
"just work" for linux. I will probably be adding more stuff to the Host layer
for launching processes and attaching to processes so that this support should
eventually just work as well.
Modified the target to be able to be created with an architecture that differs
from the main executable. This is needed for iOS debugging since we can have
an "armv6" binary which can run on an "armv7" machine, so we want to be able
to do:
% lldb
(lldb) platform create remote-ios
(lldb) file --arch armv7 a.out
Where "a.out" is an armv6 executable. The platform then can correctly decide
to open all "armv7" images for all dependent shared libraries.
Modified the disassembly to show the current PC value. Example output:
(lldb) disassemble --frame
a.out`main:
0x1eb7: pushl %ebp
0x1eb8: movl %esp, %ebp
0x1eba: pushl %ebx
0x1ebb: subl $20, %esp
0x1ebe: calll 0x1ec3 ; main + 12 at test.c:18
0x1ec3: popl %ebx
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
0x1edb: leal 213(%ebx), %eax
0x1ee1: movl %eax, (%esp)
0x1ee4: calll 0x1f1e ; puts
0x1ee9: calll 0x1f0c ; getchar
0x1eee: movl $20, (%esp)
0x1ef5: calll 0x1e6a ; sleep_loop at test.c:6
0x1efa: movl $12, %eax
0x1eff: addl $20, %esp
0x1f02: popl %ebx
0x1f03: leave
0x1f04: ret
This can be handy when dealing with the new --line options that was recently
added:
(lldb) disassemble --line
a.out`main + 13 at test.c:19
18 {
-> 19 printf("Process: %i\n\n", getpid());
20 puts("Press any key to continue..."); getchar();
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
Modified the ModuleList to have a lookup based solely on a UUID. Since the
UUID is typically the MD5 checksum of a binary image, there is no need
to give the path and architecture when searching for a pre-existing
image in an image list.
Now that we support remote debugging a bit better, our lldb_private::Module
needs to be able to track what the original path for file was as the platform
knows it, as well as where the file is locally. The module has the two
following functions to retrieve both paths:
const FileSpec &Module::GetFileSpec () const;
const FileSpec &Module::GetPlatformFileSpec () const;
llvm-svn: 128563
2011-03-31 02:16:51 +08:00
& exc_ctx_with_reasons [ i ] ,
stop_on_continue ,
stop_on_error ,
echo_commands ,
print_results ,
result ) ;
Add a first pass at a "stop hook" mechanism. This allows you to add commands that get run every time the debugger stops, whether due to a breakpoint, the end of a step, interrupt, etc. You can also specify in which context you want the stop hook to run, for instance only on a particular thread, or only in a particular shared library, function, file, line range within a file.
Still need to add "in methods of a class" to the specifiers, and the ability to write the stop hooks in the Scripting language as well as in the Command Language.
llvm-svn: 127457
2011-03-11 11:53:59 +08:00
// If the command started the target going again, we should bag out of
// running the stop hooks.
Many improvements to the Platform base class and subclasses. The base Platform
class now implements the Host functionality for a lot of things that make
sense by default so that subclasses can check:
int
PlatformSubclass::Foo ()
{
if (IsHost())
return Platform::Foo (); // Let the platform base class do the host specific stuff
// Platform subclass specific code...
int result = ...
return result;
}
Added new functions to the platform:
virtual const char *Platform::GetUserName (uint32_t uid);
virtual const char *Platform::GetGroupName (uint32_t gid);
The user and group names are cached locally so that remote platforms can avoid
sending packets multiple times to resolve this information.
Added the parent process ID to the ProcessInfo class.
Added a new ProcessInfoMatch class which helps us to match processes up
and changed the Host layer over to using this new class. The new class allows
us to search for processs:
1 - by name (equal to, starts with, ends with, contains, and regex)
2 - by pid
3 - And further check for parent pid == value, uid == value, gid == value,
euid == value, egid == value, arch == value, parent == value.
This is all hookup up to the "platform process list" command which required
adding dumping routines to dump process information. If the Host class
implements the process lookup routines, you can now lists processes on
your local machine:
machine1.foo.com % lldb
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
94727 244 username usergroup username usergroup x86_64-apple-darwin Xcode
92742 92710 username usergroup username usergroup i386-apple-darwin debugserver
This of course also works remotely with the lldb-platform:
machine1.foo.com % lldb-platform --listen 1234
machine2.foo.com % lldb
(lldb) platform create remote-macosx
Platform: remote-macosx
Connected: no
(lldb) platform connect connect://localhost:1444
Platform: remote-macosx
Triple: x86_64-apple-darwin
OS Version: 10.6.7 (10J869)
Kernel: Darwin Kernel Version 10.7.0: Sat Jan 29 15:17:16 PST 2011; root:xnu-1504.9.37~1/RELEASE_I386
Hostname: machine1.foo.com
Connected: yes
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99556 244 username usergroup username usergroup x86_64-apple-darwin trustevaluation
99548 65539 username usergroup username usergroup x86_64-apple-darwin lldb
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
The lldb-platform implements everything with the Host:: layer, so this should
"just work" for linux. I will probably be adding more stuff to the Host layer
for launching processes and attaching to processes so that this support should
eventually just work as well.
Modified the target to be able to be created with an architecture that differs
from the main executable. This is needed for iOS debugging since we can have
an "armv6" binary which can run on an "armv7" machine, so we want to be able
to do:
% lldb
(lldb) platform create remote-ios
(lldb) file --arch armv7 a.out
Where "a.out" is an armv6 executable. The platform then can correctly decide
to open all "armv7" images for all dependent shared libraries.
Modified the disassembly to show the current PC value. Example output:
(lldb) disassemble --frame
a.out`main:
0x1eb7: pushl %ebp
0x1eb8: movl %esp, %ebp
0x1eba: pushl %ebx
0x1ebb: subl $20, %esp
0x1ebe: calll 0x1ec3 ; main + 12 at test.c:18
0x1ec3: popl %ebx
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
0x1edb: leal 213(%ebx), %eax
0x1ee1: movl %eax, (%esp)
0x1ee4: calll 0x1f1e ; puts
0x1ee9: calll 0x1f0c ; getchar
0x1eee: movl $20, (%esp)
0x1ef5: calll 0x1e6a ; sleep_loop at test.c:6
0x1efa: movl $12, %eax
0x1eff: addl $20, %esp
0x1f02: popl %ebx
0x1f03: leave
0x1f04: ret
This can be handy when dealing with the new --line options that was recently
added:
(lldb) disassemble --line
a.out`main + 13 at test.c:19
18 {
-> 19 printf("Process: %i\n\n", getpid());
20 puts("Press any key to continue..."); getchar();
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
Modified the ModuleList to have a lookup based solely on a UUID. Since the
UUID is typically the MD5 checksum of a binary image, there is no need
to give the path and architecture when searching for a pre-existing
image in an image list.
Now that we support remote debugging a bit better, our lldb_private::Module
needs to be able to track what the original path for file was as the platform
knows it, as well as where the file is locally. The module has the two
following functions to retrieve both paths:
const FileSpec &Module::GetFileSpec () const;
const FileSpec &Module::GetPlatformFileSpec () const;
llvm-svn: 128563
2011-03-31 02:16:51 +08:00
if ( ( result . GetStatus ( ) = = eReturnStatusSuccessContinuingNoResult ) | |
( result . GetStatus ( ) = = eReturnStatusSuccessContinuingResult ) )
Add a first pass at a "stop hook" mechanism. This allows you to add commands that get run every time the debugger stops, whether due to a breakpoint, the end of a step, interrupt, etc. You can also specify in which context you want the stop hook to run, for instance only on a particular thread, or only in a particular shared library, function, file, line range within a file.
Still need to add "in methods of a class" to the specifiers, and the ability to write the stop hooks in the Scripting language as well as in the Command Language.
llvm-svn: 127457
2011-03-11 11:53:59 +08:00
{
2011-10-20 02:09:39 +08:00
result . AppendMessageWithFormat ( " Aborting stop hooks, hook %llu set the program running. " , cur_hook_sp - > GetID ( ) ) ;
Add a first pass at a "stop hook" mechanism. This allows you to add commands that get run every time the debugger stops, whether due to a breakpoint, the end of a step, interrupt, etc. You can also specify in which context you want the stop hook to run, for instance only on a particular thread, or only in a particular shared library, function, file, line range within a file.
Still need to add "in methods of a class" to the specifiers, and the ability to write the stop hooks in the Scripting language as well as in the Command Language.
llvm-svn: 127457
2011-03-11 11:53:59 +08:00
keep_going = false ;
}
}
}
}
2011-09-23 08:42:55 +08:00
This patch captures and serializes all output being written by the
command line driver, including the lldb prompt being output by
editline, the asynchronous process output & error messages, and
asynchronous messages written by target stop-hooks.
As part of this it introduces a new Stream class,
StreamAsynchronousIO. A StreamAsynchronousIO object is created with a
broadcaster, who will eventually broadcast the stream's data for a
listener to handle, and an event type indicating what type of event
the broadcaster will broadcast. When the Write method is called on a
StreamAsynchronousIO object, the data is appended to an internal
string. When the Flush method is called on a StreamAsynchronousIO
object, it broadcasts it's data string and clears the string.
Anything in lldb-core that needs to generate asynchronous output for
the end-user should use the StreamAsynchronousIO objects.
I have also added a new notification type for InputReaders, to let
them know that a asynchronous output has been written. This is to
allow the input readers to, for example, refresh their prompts and
lines, if desired. I added the case statements to all the input
readers to catch this notification, but I haven't added any code for
handling them yet (except to the IOChannel input reader).
llvm-svn: 130721
2011-05-03 04:41:46 +08:00
result . GetImmediateOutputStream ( ) - > Flush ( ) ;
result . GetImmediateErrorStream ( ) - > Flush ( ) ;
Add a first pass at a "stop hook" mechanism. This allows you to add commands that get run every time the debugger stops, whether due to a breakpoint, the end of a step, interrupt, etc. You can also specify in which context you want the stop hook to run, for instance only on a particular thread, or only in a particular shared library, function, file, line range within a file.
Still need to add "in methods of a class" to the specifiers, and the ability to write the stop hooks in the Scripting language as well as in the Command Language.
llvm-svn: 127457
2011-03-11 11:53:59 +08:00
}
2011-07-08 08:48:09 +08:00
bool
Target : : LoadModuleWithSlide ( Module * module , lldb : : addr_t slide )
{
bool changed = false ;
if ( module )
{
ObjectFile * object_file = module - > GetObjectFile ( ) ;
if ( object_file )
{
SectionList * section_list = object_file - > GetSectionList ( ) ;
if ( section_list )
{
// All sections listed in the dyld image info structure will all
// either be fixed up already, or they will all be off by a single
// slide amount that is determined by finding the first segment
// that is at file offset zero which also has bytes (a file size
// that is greater than zero) in the object file.
// Determine the slide amount (if any)
const size_t num_sections = section_list - > GetSize ( ) ;
size_t sect_idx = 0 ;
for ( sect_idx = 0 ; sect_idx < num_sections ; + + sect_idx )
{
// Iterate through the object file sections to find the
// first section that starts of file offset zero and that
// has bytes in the file...
Section * section = section_list - > GetSectionAtIndex ( sect_idx ) . get ( ) ;
if ( section )
{
if ( m_section_load_list . SetSectionLoadAddress ( section , section - > GetFileAddress ( ) + slide ) )
changed = true ;
}
}
}
}
}
return changed ;
}
Add a first pass at a "stop hook" mechanism. This allows you to add commands that get run every time the debugger stops, whether due to a breakpoint, the end of a step, interrupt, etc. You can also specify in which context you want the stop hook to run, for instance only on a particular thread, or only in a particular shared library, function, file, line range within a file.
Still need to add "in methods of a class" to the specifiers, and the ability to write the stop hooks in the Scripting language as well as in the Command Language.
llvm-svn: 127457
2011-03-11 11:53:59 +08:00
//--------------------------------------------------------------
// class Target::StopHook
//--------------------------------------------------------------
Target : : StopHook : : StopHook ( lldb : : TargetSP target_sp , lldb : : user_id_t uid ) :
UserID ( uid ) ,
m_target_sp ( target_sp ) ,
m_commands ( ) ,
m_specifier_sp ( ) ,
2011-04-12 03:41:40 +08:00
m_thread_spec_ap ( NULL ) ,
m_active ( true )
Add a first pass at a "stop hook" mechanism. This allows you to add commands that get run every time the debugger stops, whether due to a breakpoint, the end of a step, interrupt, etc. You can also specify in which context you want the stop hook to run, for instance only on a particular thread, or only in a particular shared library, function, file, line range within a file.
Still need to add "in methods of a class" to the specifiers, and the ability to write the stop hooks in the Scripting language as well as in the Command Language.
llvm-svn: 127457
2011-03-11 11:53:59 +08:00
{
}
Target : : StopHook : : StopHook ( const StopHook & rhs ) :
UserID ( rhs . GetID ( ) ) ,
m_target_sp ( rhs . m_target_sp ) ,
m_commands ( rhs . m_commands ) ,
m_specifier_sp ( rhs . m_specifier_sp ) ,
2011-04-12 03:41:40 +08:00
m_thread_spec_ap ( NULL ) ,
m_active ( rhs . m_active )
Add a first pass at a "stop hook" mechanism. This allows you to add commands that get run every time the debugger stops, whether due to a breakpoint, the end of a step, interrupt, etc. You can also specify in which context you want the stop hook to run, for instance only on a particular thread, or only in a particular shared library, function, file, line range within a file.
Still need to add "in methods of a class" to the specifiers, and the ability to write the stop hooks in the Scripting language as well as in the Command Language.
llvm-svn: 127457
2011-03-11 11:53:59 +08:00
{
if ( rhs . m_thread_spec_ap . get ( ) ! = NULL )
m_thread_spec_ap . reset ( new ThreadSpec ( * rhs . m_thread_spec_ap . get ( ) ) ) ;
}
Target : : StopHook : : ~ StopHook ( )
{
}
void
Target : : StopHook : : SetThreadSpecifier ( ThreadSpec * specifier )
{
m_thread_spec_ap . reset ( specifier ) ;
}
void
Target : : StopHook : : GetDescription ( Stream * s , lldb : : DescriptionLevel level ) const
{
int indent_level = s - > GetIndentLevel ( ) ;
s - > SetIndentLevel ( indent_level + 2 ) ;
2011-10-20 02:09:39 +08:00
s - > Printf ( " Hook: %llu \n " , GetID ( ) ) ;
Add a first pass at a "stop hook" mechanism. This allows you to add commands that get run every time the debugger stops, whether due to a breakpoint, the end of a step, interrupt, etc. You can also specify in which context you want the stop hook to run, for instance only on a particular thread, or only in a particular shared library, function, file, line range within a file.
Still need to add "in methods of a class" to the specifiers, and the ability to write the stop hooks in the Scripting language as well as in the Command Language.
llvm-svn: 127457
2011-03-11 11:53:59 +08:00
if ( m_active )
s - > Indent ( " State: enabled \n " ) ;
else
s - > Indent ( " State: disabled \n " ) ;
if ( m_specifier_sp )
{
s - > Indent ( ) ;
s - > PutCString ( " Specifier: \n " ) ;
s - > SetIndentLevel ( indent_level + 4 ) ;
m_specifier_sp - > GetDescription ( s , level ) ;
s - > SetIndentLevel ( indent_level + 2 ) ;
}
if ( m_thread_spec_ap . get ( ) ! = NULL )
{
StreamString tmp ;
s - > Indent ( " Thread: \n " ) ;
m_thread_spec_ap - > GetDescription ( & tmp , level ) ;
s - > SetIndentLevel ( indent_level + 4 ) ;
s - > Indent ( tmp . GetData ( ) ) ;
s - > PutCString ( " \n " ) ;
s - > SetIndentLevel ( indent_level + 2 ) ;
}
s - > Indent ( " Commands: \n " ) ;
s - > SetIndentLevel ( indent_level + 4 ) ;
uint32_t num_commands = m_commands . GetSize ( ) ;
for ( uint32_t i = 0 ; i < num_commands ; i + + )
{
s - > Indent ( m_commands . GetStringAtIndex ( i ) ) ;
s - > PutCString ( " \n " ) ;
}
s - > SetIndentLevel ( indent_level ) ;
}
2010-09-21 04:44:43 +08:00
//--------------------------------------------------------------
// class Target::SettingsController
//--------------------------------------------------------------
Target : : SettingsController : : SettingsController ( ) :
UserSettingsController ( " target " , Debugger : : GetSettingsController ( ) ) ,
m_default_architecture ( )
{
}
Target : : SettingsController : : ~ SettingsController ( )
{
}
lldb : : InstanceSettingsSP
Target : : SettingsController : : CreateInstanceSettings ( const char * instance_name )
{
2012-01-30 15:41:31 +08:00
lldb : : InstanceSettingsSP new_settings_sp ( new TargetInstanceSettings ( GetSettingsController ( ) ,
false ,
instance_name ) ) ;
2010-09-21 04:44:43 +08:00
return new_settings_sp ;
}
2011-02-18 09:44:25 +08:00
2011-11-08 10:43:13 +08:00
# define TSC_DEFAULT_ARCH "default-arch"
# define TSC_EXPR_PREFIX "expr-prefix"
# define TSC_PREFER_DYNAMIC "prefer-dynamic-value"
# define TSC_SKIP_PROLOGUE "skip-prologue"
# define TSC_SOURCE_MAP "source-map"
2012-02-14 07:10:39 +08:00
# define TSC_EXE_SEARCH_PATHS "exec-search-paths"
2011-11-08 10:43:13 +08:00
# define TSC_MAX_CHILDREN "max-children-count"
# define TSC_MAX_STRLENSUMMARY "max-string-summary-length"
# define TSC_PLATFORM_AVOID "breakpoints-use-platform-avoid-list"
# define TSC_RUN_ARGS "run-args"
# define TSC_ENV_VARS "env-vars"
# define TSC_INHERIT_ENV "inherit-env"
# define TSC_STDIN_PATH "input-path"
# define TSC_STDOUT_PATH "output-path"
# define TSC_STDERR_PATH "error-path"
# define TSC_DISABLE_ASLR "disable-aslr"
# define TSC_DISABLE_STDIO "disable-stdio"
2011-02-18 09:44:25 +08:00
static const ConstString &
GetSettingNameForDefaultArch ( )
{
static ConstString g_const_string ( TSC_DEFAULT_ARCH ) ;
return g_const_string ;
}
static const ConstString &
GetSettingNameForExpressionPrefix ( )
{
static ConstString g_const_string ( TSC_EXPR_PREFIX ) ;
return g_const_string ;
}
2011-04-16 08:01:13 +08:00
static const ConstString &
GetSettingNameForPreferDynamicValue ( )
{
static ConstString g_const_string ( TSC_PREFER_DYNAMIC ) ;
return g_const_string ;
}
2011-04-23 10:04:55 +08:00
static const ConstString &
GetSettingNameForSourcePathMap ( )
{
static ConstString g_const_string ( TSC_SOURCE_MAP ) ;
return g_const_string ;
}
2011-02-18 09:44:25 +08:00
2012-02-14 07:10:39 +08:00
static const ConstString &
GetSettingNameForExecutableSearchPaths ( )
{
static ConstString g_const_string ( TSC_EXE_SEARCH_PATHS ) ;
return g_const_string ;
}
2011-04-22 11:55:06 +08:00
static const ConstString &
GetSettingNameForSkipPrologue ( )
{
static ConstString g_const_string ( TSC_SKIP_PROLOGUE ) ;
return g_const_string ;
}
2011-08-12 10:00:06 +08:00
static const ConstString &
GetSettingNameForMaxChildren ( )
{
static ConstString g_const_string ( TSC_MAX_CHILDREN ) ;
return g_const_string ;
}
2011-04-22 11:55:06 +08:00
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
static const ConstString &
GetSettingNameForMaxStringSummaryLength ( )
{
static ConstString g_const_string ( TSC_MAX_STRLENSUMMARY ) ;
return g_const_string ;
}
2011-04-22 11:55:06 +08:00
2011-10-29 07:14:11 +08:00
static const ConstString &
GetSettingNameForPlatformAvoid ( )
{
static ConstString g_const_string ( TSC_PLATFORM_AVOID ) ;
return g_const_string ;
}
2011-11-08 10:43:13 +08:00
const ConstString &
GetSettingNameForRunArgs ( )
{
static ConstString g_const_string ( TSC_RUN_ARGS ) ;
return g_const_string ;
}
const ConstString &
GetSettingNameForEnvVars ( )
{
static ConstString g_const_string ( TSC_ENV_VARS ) ;
return g_const_string ;
}
const ConstString &
GetSettingNameForInheritHostEnv ( )
{
static ConstString g_const_string ( TSC_INHERIT_ENV ) ;
return g_const_string ;
}
const ConstString &
GetSettingNameForInputPath ( )
{
static ConstString g_const_string ( TSC_STDIN_PATH ) ;
return g_const_string ;
}
const ConstString &
GetSettingNameForOutputPath ( )
{
static ConstString g_const_string ( TSC_STDOUT_PATH ) ;
return g_const_string ;
}
const ConstString &
GetSettingNameForErrorPath ( )
{
static ConstString g_const_string ( TSC_STDERR_PATH ) ;
return g_const_string ;
}
const ConstString &
GetSettingNameForDisableASLR ( )
{
static ConstString g_const_string ( TSC_DISABLE_ASLR ) ;
return g_const_string ;
}
const ConstString &
GetSettingNameForDisableSTDIO ( )
{
static ConstString g_const_string ( TSC_DISABLE_STDIO ) ;
return g_const_string ;
}
2011-10-29 07:14:11 +08:00
2010-09-21 04:44:43 +08:00
bool
Target : : SettingsController : : SetGlobalVariable ( const ConstString & var_name ,
const char * index_value ,
const char * value ,
const SettingEntry & entry ,
2011-03-25 05:19:54 +08:00
const VarSetOperationType op ,
2010-09-21 04:44:43 +08:00
Error & err )
{
2011-02-18 09:44:25 +08:00
if ( var_name = = GetSettingNameForDefaultArch ( ) )
2010-09-21 04:44:43 +08:00
{
2011-04-08 06:46:35 +08:00
m_default_architecture . SetTriple ( value , NULL ) ;
2011-02-23 08:35:02 +08:00
if ( ! m_default_architecture . IsValid ( ) )
err . SetErrorStringWithFormat ( " '%s' is not a valid architecture or triple. " , value ) ;
2010-09-21 04:44:43 +08:00
}
return true ;
}
bool
Target : : SettingsController : : GetGlobalVariable ( const ConstString & var_name ,
StringList & value ,
Error & err )
{
2011-02-18 09:44:25 +08:00
if ( var_name = = GetSettingNameForDefaultArch ( ) )
2010-09-21 04:44:43 +08:00
{
2010-10-27 10:06:37 +08:00
// If the arch is invalid (the default), don't show a string for it
if ( m_default_architecture . IsValid ( ) )
2011-02-23 08:35:02 +08:00
value . AppendString ( m_default_architecture . GetArchitectureName ( ) ) ;
2010-09-21 04:44:43 +08:00
return true ;
}
else
err . SetErrorStringWithFormat ( " unrecognized variable name '%s' " , var_name . AsCString ( ) ) ;
return false ;
}
//--------------------------------------------------------------
// class TargetInstanceSettings
//--------------------------------------------------------------
2010-12-04 08:10:17 +08:00
TargetInstanceSettings : : TargetInstanceSettings
(
2012-01-30 15:41:31 +08:00
const lldb : : UserSettingsControllerSP & owner_sp ,
2010-12-04 08:10:17 +08:00
bool live_instance ,
const char * name
) :
2012-01-30 15:41:31 +08:00
InstanceSettings ( owner_sp , name ? name : InstanceSettings : : InvalidName ( ) . AsCString ( ) , live_instance ) ,
2011-04-23 10:04:55 +08:00
m_expr_prefix_file ( ) ,
2011-11-16 09:54:57 +08:00
m_expr_prefix_contents ( ) ,
2011-05-04 11:43:18 +08:00
m_prefer_dynamic_value ( 2 ) ,
2011-04-23 10:04:55 +08:00
m_skip_prologue ( true , true ) ,
2011-08-12 10:00:06 +08:00
m_source_map ( NULL , NULL ) ,
2012-02-14 07:10:39 +08:00
m_exe_search_paths ( ) ,
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
m_max_children_display ( 256 ) ,
2011-10-29 07:14:11 +08:00
m_max_strlen_length ( 1024 ) ,
2011-11-08 10:43:13 +08:00
m_breakpoints_use_platform_avoid ( true , true ) ,
m_run_args ( ) ,
m_env_vars ( ) ,
m_input_path ( ) ,
m_output_path ( ) ,
m_error_path ( ) ,
m_disable_aslr ( true ) ,
m_disable_stdio ( false ) ,
m_inherit_host_env ( true ) ,
m_got_host_env ( false )
2010-09-21 04:44:43 +08:00
{
// CopyInstanceSettings is a pure virtual function in InstanceSettings; it therefore cannot be called
// until the vtables for TargetInstanceSettings are properly set up, i.e. AFTER all the initializers.
// For this reason it has to be called here, rather than in the initializer or in the parent constructor.
// This is true for CreateInstanceName() too.
if ( GetInstanceName ( ) = = InstanceSettings : : InvalidName ( ) )
{
ChangeInstanceName ( std : : string ( CreateInstanceName ( ) . AsCString ( ) ) ) ;
2012-01-30 15:41:31 +08:00
owner_sp - > RegisterInstanceSettings ( this ) ;
2010-09-21 04:44:43 +08:00
}
if ( live_instance )
{
2012-01-30 15:41:31 +08:00
const lldb : : InstanceSettingsSP & pending_settings = owner_sp - > FindPendingSettings ( m_instance_name ) ;
2010-09-21 04:44:43 +08:00
CopyInstanceSettings ( pending_settings , false ) ;
}
}
TargetInstanceSettings : : TargetInstanceSettings ( const TargetInstanceSettings & rhs ) :
2012-01-30 15:41:31 +08:00
InstanceSettings ( Target : : GetSettingsController ( ) , CreateInstanceName ( ) . AsCString ( ) ) ,
2011-04-23 10:04:55 +08:00
m_expr_prefix_file ( rhs . m_expr_prefix_file ) ,
2011-11-16 09:54:57 +08:00
m_expr_prefix_contents ( rhs . m_expr_prefix_contents ) ,
2011-04-23 10:04:55 +08:00
m_prefer_dynamic_value ( rhs . m_prefer_dynamic_value ) ,
m_skip_prologue ( rhs . m_skip_prologue ) ,
2011-08-12 10:00:06 +08:00
m_source_map ( rhs . m_source_map ) ,
2012-02-14 07:10:39 +08:00
m_exe_search_paths ( rhs . m_exe_search_paths ) ,
2011-11-08 10:43:13 +08:00
m_max_children_display ( rhs . m_max_children_display ) ,
m_max_strlen_length ( rhs . m_max_strlen_length ) ,
m_breakpoints_use_platform_avoid ( rhs . m_breakpoints_use_platform_avoid ) ,
m_run_args ( rhs . m_run_args ) ,
m_env_vars ( rhs . m_env_vars ) ,
m_input_path ( rhs . m_input_path ) ,
m_output_path ( rhs . m_output_path ) ,
m_error_path ( rhs . m_error_path ) ,
m_disable_aslr ( rhs . m_disable_aslr ) ,
m_disable_stdio ( rhs . m_disable_stdio ) ,
m_inherit_host_env ( rhs . m_inherit_host_env )
2010-09-21 04:44:43 +08:00
{
if ( m_instance_name ! = InstanceSettings : : GetDefaultName ( ) )
{
2012-01-30 15:41:31 +08:00
UserSettingsControllerSP owner_sp ( m_owner_wp . lock ( ) ) ;
if ( owner_sp )
CopyInstanceSettings ( owner_sp - > FindPendingSettings ( m_instance_name ) , false ) ;
2010-09-21 04:44:43 +08:00
}
}
TargetInstanceSettings : : ~ TargetInstanceSettings ( )
{
}
TargetInstanceSettings &
TargetInstanceSettings : : operator = ( const TargetInstanceSettings & rhs )
{
if ( this ! = & rhs )
{
2011-11-08 10:43:13 +08:00
m_expr_prefix_file = rhs . m_expr_prefix_file ;
2011-11-16 09:54:57 +08:00
m_expr_prefix_contents = rhs . m_expr_prefix_contents ;
2011-11-08 10:43:13 +08:00
m_prefer_dynamic_value = rhs . m_prefer_dynamic_value ;
m_skip_prologue = rhs . m_skip_prologue ;
m_source_map = rhs . m_source_map ;
2012-02-14 07:10:39 +08:00
m_exe_search_paths = rhs . m_exe_search_paths ;
2011-11-08 10:43:13 +08:00
m_max_children_display = rhs . m_max_children_display ;
m_max_strlen_length = rhs . m_max_strlen_length ;
m_breakpoints_use_platform_avoid = rhs . m_breakpoints_use_platform_avoid ;
m_run_args = rhs . m_run_args ;
m_env_vars = rhs . m_env_vars ;
m_input_path = rhs . m_input_path ;
m_output_path = rhs . m_output_path ;
m_error_path = rhs . m_error_path ;
m_disable_aslr = rhs . m_disable_aslr ;
m_disable_stdio = rhs . m_disable_stdio ;
m_inherit_host_env = rhs . m_inherit_host_env ;
2010-09-21 04:44:43 +08:00
}
return * this ;
}
void
TargetInstanceSettings : : UpdateInstanceSettingsVariable ( const ConstString & var_name ,
const char * index_value ,
const char * value ,
const ConstString & instance_name ,
const SettingEntry & entry ,
2011-03-25 05:19:54 +08:00
VarSetOperationType op ,
2010-09-21 04:44:43 +08:00
Error & err ,
bool pending )
{
2011-02-18 09:44:25 +08:00
if ( var_name = = GetSettingNameForExpressionPrefix ( ) )
2010-10-29 08:29:03 +08:00
{
2011-04-23 10:04:55 +08:00
err = UserSettingsController : : UpdateFileSpecOptionValue ( value , op , m_expr_prefix_file ) ;
if ( err . Success ( ) )
2010-10-29 08:29:03 +08:00
{
2011-04-23 10:04:55 +08:00
switch ( op )
2010-10-29 08:29:03 +08:00
{
2011-04-23 10:04:55 +08:00
default :
break ;
case eVarSetOperationAssign :
case eVarSetOperationAppend :
2010-10-29 08:29:03 +08:00
{
2012-01-06 10:01:06 +08:00
m_expr_prefix_contents . clear ( ) ;
2011-04-23 10:04:55 +08:00
if ( ! m_expr_prefix_file . GetCurrentValue ( ) . Exists ( ) )
{
err . SetErrorToGenericError ( ) ;
2011-10-26 08:56:27 +08:00
err . SetErrorStringWithFormat ( " %s does not exist " , value ) ;
2011-04-23 10:04:55 +08:00
return ;
}
2012-01-06 10:01:06 +08:00
DataBufferSP file_data_sp ( m_expr_prefix_file . GetCurrentValue ( ) . ReadFileContents ( 0 , SIZE_MAX , & err ) ) ;
2011-11-16 09:54:57 +08:00
2012-01-06 10:01:06 +08:00
if ( err . Success ( ) )
2011-04-23 10:04:55 +08:00
{
2012-01-06 10:01:06 +08:00
if ( file_data_sp & & file_data_sp - > GetByteSize ( ) > 0 )
{
m_expr_prefix_contents . assign ( ( const char * ) file_data_sp - > GetBytes ( ) , file_data_sp - > GetByteSize ( ) ) ;
}
else
{
err . SetErrorStringWithFormat ( " couldn't read data from '%s' " , value ) ;
}
2011-04-23 10:04:55 +08:00
}
2010-10-29 08:29:03 +08:00
}
2011-04-23 10:04:55 +08:00
break ;
case eVarSetOperationClear :
2011-11-16 09:54:57 +08:00
m_expr_prefix_contents . clear ( ) ;
2010-10-29 08:29:03 +08:00
}
}
}
2011-04-16 08:01:13 +08:00
else if ( var_name = = GetSettingNameForPreferDynamicValue ( ) )
{
2011-05-04 11:43:18 +08:00
int new_value ;
UserSettingsController : : UpdateEnumVariable ( g_dynamic_value_types , & new_value , value , err ) ;
if ( err . Success ( ) )
m_prefer_dynamic_value = new_value ;
2011-04-22 11:55:06 +08:00
}
else if ( var_name = = GetSettingNameForSkipPrologue ( ) )
{
2011-04-23 10:04:55 +08:00
err = UserSettingsController : : UpdateBooleanOptionValue ( value , op , m_skip_prologue ) ;
}
2011-08-12 10:00:06 +08:00
else if ( var_name = = GetSettingNameForMaxChildren ( ) )
{
bool ok ;
uint32_t new_value = Args : : StringToUInt32 ( value , 0 , 10 , & ok ) ;
if ( ok )
m_max_children_display = new_value ;
}
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
else if ( var_name = = GetSettingNameForMaxStringSummaryLength ( ) )
{
bool ok ;
uint32_t new_value = Args : : StringToUInt32 ( value , 0 , 10 , & ok ) ;
if ( ok )
m_max_strlen_length = new_value ;
}
2012-02-14 07:10:39 +08:00
else if ( var_name = = GetSettingNameForExecutableSearchPaths ( ) )
{
switch ( op )
{
case eVarSetOperationReplace :
case eVarSetOperationInsertBefore :
case eVarSetOperationInsertAfter :
case eVarSetOperationRemove :
default :
break ;
case eVarSetOperationAssign :
m_exe_search_paths . Clear ( ) ;
// Fall through to append....
case eVarSetOperationAppend :
{
Args args ( value ) ;
const uint32_t argc = args . GetArgumentCount ( ) ;
if ( argc > 0 )
{
const char * exe_search_path_dir ;
for ( uint32_t idx = 0 ; ( exe_search_path_dir = args . GetArgumentAtIndex ( idx ) ) ! = NULL ; + + idx )
{
FileSpec file_spec ;
file_spec . GetDirectory ( ) . SetCString ( exe_search_path_dir ) ;
FileSpec : : FileType file_type = file_spec . GetFileType ( ) ;
if ( file_type = = FileSpec : : eFileTypeDirectory | | file_type = = FileSpec : : eFileTypeInvalid )
{
m_exe_search_paths . Append ( file_spec ) ;
}
else
{
err . SetErrorStringWithFormat ( " executable search path '%s' exists, but it does not resolve to a directory " , exe_search_path_dir ) ;
}
}
}
}
break ;
case eVarSetOperationClear :
m_exe_search_paths . Clear ( ) ;
break ;
}
}
2011-04-23 10:04:55 +08:00
else if ( var_name = = GetSettingNameForSourcePathMap ( ) )
{
switch ( op )
{
case eVarSetOperationReplace :
case eVarSetOperationInsertBefore :
case eVarSetOperationInsertAfter :
case eVarSetOperationRemove :
default :
break ;
case eVarSetOperationAssign :
m_source_map . Clear ( true ) ;
// Fall through to append....
case eVarSetOperationAppend :
{
Args args ( value ) ;
const uint32_t argc = args . GetArgumentCount ( ) ;
if ( argc & 1 | | argc = = 0 )
{
err . SetErrorStringWithFormat ( " an even number of paths must be supplied to to the source-map setting: %u arguments given " , argc ) ;
}
else
{
char resolved_new_path [ PATH_MAX ] ;
FileSpec file_spec ;
const char * old_path ;
for ( uint32_t idx = 0 ; ( old_path = args . GetArgumentAtIndex ( idx ) ) ! = NULL ; idx + = 2 )
{
const char * new_path = args . GetArgumentAtIndex ( idx + 1 ) ;
assert ( new_path ) ; // We have an even number of paths, this shouldn't happen!
file_spec . SetFile ( new_path , true ) ;
if ( file_spec . Exists ( ) )
{
if ( file_spec . GetPath ( resolved_new_path , sizeof ( resolved_new_path ) ) > = sizeof ( resolved_new_path ) )
{
err . SetErrorStringWithFormat ( " new path '%s' is too long " , new_path ) ;
return ;
}
}
else
{
err . SetErrorStringWithFormat ( " new path '%s' doesn't exist " , new_path ) ;
return ;
}
m_source_map . Append ( ConstString ( old_path ) , ConstString ( resolved_new_path ) , true ) ;
}
}
}
break ;
case eVarSetOperationClear :
m_source_map . Clear ( true ) ;
break ;
}
2011-04-16 08:01:13 +08:00
}
2011-10-29 07:14:11 +08:00
else if ( var_name = = GetSettingNameForPlatformAvoid ( ) )
{
err = UserSettingsController : : UpdateBooleanOptionValue ( value , op , m_breakpoints_use_platform_avoid ) ;
}
2011-11-08 10:43:13 +08:00
else if ( var_name = = GetSettingNameForRunArgs ( ) )
{
UserSettingsController : : UpdateStringArrayVariable ( op , index_value , m_run_args , value , err ) ;
}
else if ( var_name = = GetSettingNameForEnvVars ( ) )
{
// This is nice for local debugging, but it is isn't correct for
// remote debugging. We need to stop process.env-vars from being
// populated with the host environment and add this as a launch option
// and get the correct environment from the Target's platform.
// GetHostEnvironmentIfNeeded ();
UserSettingsController : : UpdateDictionaryVariable ( op , index_value , m_env_vars , value , err ) ;
}
else if ( var_name = = GetSettingNameForInputPath ( ) )
{
UserSettingsController : : UpdateStringVariable ( op , m_input_path , value , err ) ;
}
else if ( var_name = = GetSettingNameForOutputPath ( ) )
{
UserSettingsController : : UpdateStringVariable ( op , m_output_path , value , err ) ;
}
else if ( var_name = = GetSettingNameForErrorPath ( ) )
{
UserSettingsController : : UpdateStringVariable ( op , m_error_path , value , err ) ;
}
else if ( var_name = = GetSettingNameForDisableASLR ( ) )
{
UserSettingsController : : UpdateBooleanVariable ( op , m_disable_aslr , value , true , err ) ;
}
else if ( var_name = = GetSettingNameForDisableSTDIO ( ) )
{
UserSettingsController : : UpdateBooleanVariable ( op , m_disable_stdio , value , false , err ) ;
}
2010-09-21 04:44:43 +08:00
}
void
2011-02-18 09:44:25 +08:00
TargetInstanceSettings : : CopyInstanceSettings ( const lldb : : InstanceSettingsSP & new_settings , bool pending )
2010-09-21 04:44:43 +08:00
{
2010-10-29 08:29:03 +08:00
TargetInstanceSettings * new_settings_ptr = static_cast < TargetInstanceSettings * > ( new_settings . get ( ) ) ;
if ( ! new_settings_ptr )
return ;
2011-11-08 10:43:13 +08:00
* this = * new_settings_ptr ;
2010-09-21 04:44:43 +08:00
}
2010-09-21 05:37:42 +08:00
bool
2010-09-21 04:44:43 +08:00
TargetInstanceSettings : : GetInstanceSettingsValue ( const SettingEntry & entry ,
const ConstString & var_name ,
StringList & value ,
2010-09-21 05:37:42 +08:00
Error * err )
2010-09-21 04:44:43 +08:00
{
2011-02-18 09:44:25 +08:00
if ( var_name = = GetSettingNameForExpressionPrefix ( ) )
2010-10-29 08:29:03 +08:00
{
2011-04-23 10:04:55 +08:00
char path [ PATH_MAX ] ;
const size_t path_len = m_expr_prefix_file . GetCurrentValue ( ) . GetPath ( path , sizeof ( path ) ) ;
if ( path_len > 0 )
value . AppendString ( path , path_len ) ;
2010-10-29 08:29:03 +08:00
}
2011-04-16 08:01:13 +08:00
else if ( var_name = = GetSettingNameForPreferDynamicValue ( ) )
{
2011-05-04 11:43:18 +08:00
value . AppendString ( g_dynamic_value_types [ m_prefer_dynamic_value ] . string_value ) ;
2011-04-16 08:01:13 +08:00
}
2011-04-22 11:55:06 +08:00
else if ( var_name = = GetSettingNameForSkipPrologue ( ) )
{
if ( m_skip_prologue )
value . AppendString ( " true " ) ;
else
value . AppendString ( " false " ) ;
}
2012-02-14 07:10:39 +08:00
else if ( var_name = = GetSettingNameForExecutableSearchPaths ( ) )
{
if ( m_exe_search_paths . GetSize ( ) )
{
for ( size_t i = 0 , n = m_exe_search_paths . GetSize ( ) ; i < n ; + + i )
{
value . AppendString ( m_exe_search_paths . GetFileSpecAtIndex ( i ) . GetDirectory ( ) . AsCString ( ) ) ;
}
}
}
2011-04-23 10:04:55 +08:00
else if ( var_name = = GetSettingNameForSourcePathMap ( ) )
{
2011-12-13 05:59:28 +08:00
if ( m_source_map . GetSize ( ) )
{
size_t i ;
for ( i = 0 ; i < m_source_map . GetSize ( ) ; + + i ) {
StreamString sstr ;
m_source_map . Dump ( & sstr , i ) ;
value . AppendString ( sstr . GetData ( ) ) ;
}
}
2011-04-23 10:04:55 +08:00
}
2011-08-12 10:00:06 +08:00
else if ( var_name = = GetSettingNameForMaxChildren ( ) )
{
StreamString count_str ;
count_str . Printf ( " %d " , m_max_children_display ) ;
value . AppendString ( count_str . GetData ( ) ) ;
}
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
else if ( var_name = = GetSettingNameForMaxStringSummaryLength ( ) )
{
StreamString count_str ;
count_str . Printf ( " %d " , m_max_strlen_length ) ;
value . AppendString ( count_str . GetData ( ) ) ;
}
2011-10-29 07:14:11 +08:00
else if ( var_name = = GetSettingNameForPlatformAvoid ( ) )
{
if ( m_breakpoints_use_platform_avoid )
value . AppendString ( " true " ) ;
else
value . AppendString ( " false " ) ;
}
2011-11-08 10:43:13 +08:00
else if ( var_name = = GetSettingNameForRunArgs ( ) )
{
if ( m_run_args . GetArgumentCount ( ) > 0 )
{
for ( int i = 0 ; i < m_run_args . GetArgumentCount ( ) ; + + i )
value . AppendString ( m_run_args . GetArgumentAtIndex ( i ) ) ;
}
}
else if ( var_name = = GetSettingNameForEnvVars ( ) )
{
GetHostEnvironmentIfNeeded ( ) ;
if ( m_env_vars . size ( ) > 0 )
{
std : : map < std : : string , std : : string > : : iterator pos ;
for ( pos = m_env_vars . begin ( ) ; pos ! = m_env_vars . end ( ) ; + + pos )
{
StreamString value_str ;
value_str . Printf ( " %s=%s " , pos - > first . c_str ( ) , pos - > second . c_str ( ) ) ;
value . AppendString ( value_str . GetData ( ) ) ;
}
}
}
else if ( var_name = = GetSettingNameForInputPath ( ) )
{
value . AppendString ( m_input_path . c_str ( ) ) ;
}
else if ( var_name = = GetSettingNameForOutputPath ( ) )
{
value . AppendString ( m_output_path . c_str ( ) ) ;
}
else if ( var_name = = GetSettingNameForErrorPath ( ) )
{
value . AppendString ( m_error_path . c_str ( ) ) ;
}
else if ( var_name = = GetSettingNameForInheritHostEnv ( ) )
{
if ( m_inherit_host_env )
value . AppendString ( " true " ) ;
else
value . AppendString ( " false " ) ;
}
else if ( var_name = = GetSettingNameForDisableASLR ( ) )
{
if ( m_disable_aslr )
value . AppendString ( " true " ) ;
else
value . AppendString ( " false " ) ;
}
else if ( var_name = = GetSettingNameForDisableSTDIO ( ) )
{
if ( m_disable_stdio )
value . AppendString ( " true " ) ;
else
value . AppendString ( " false " ) ;
}
2010-10-29 08:29:03 +08:00
else
{
if ( err )
err - > SetErrorStringWithFormat ( " unrecognized variable name '%s' " , var_name . AsCString ( ) ) ;
return false ;
}
return true ;
2010-09-21 04:44:43 +08:00
}
2011-11-08 10:43:13 +08:00
void
Target : : TargetInstanceSettings : : GetHostEnvironmentIfNeeded ( )
{
if ( m_inherit_host_env & & ! m_got_host_env )
{
m_got_host_env = true ;
StringList host_env ;
const size_t host_env_count = Host : : GetEnvironment ( host_env ) ;
for ( size_t idx = 0 ; idx < host_env_count ; idx + + )
{
const char * env_entry = host_env . GetStringAtIndex ( idx ) ;
if ( env_entry )
{
const char * equal_pos = : : strchr ( env_entry , ' = ' ) ;
if ( equal_pos )
{
std : : string key ( env_entry , equal_pos - env_entry ) ;
std : : string value ( equal_pos + 1 ) ;
if ( m_env_vars . find ( key ) = = m_env_vars . end ( ) )
m_env_vars [ key ] = value ;
}
}
}
}
}
size_t
Target : : TargetInstanceSettings : : GetEnvironmentAsArgs ( Args & env )
{
GetHostEnvironmentIfNeeded ( ) ;
dictionary : : const_iterator pos , end = m_env_vars . end ( ) ;
for ( pos = m_env_vars . begin ( ) ; pos ! = end ; + + pos )
{
std : : string env_var_equal_value ( pos - > first ) ;
env_var_equal_value . append ( 1 , ' = ' ) ;
env_var_equal_value . append ( pos - > second ) ;
env . AppendArgument ( env_var_equal_value . c_str ( ) ) ;
}
return env . GetArgumentCount ( ) ;
}
2010-09-21 04:44:43 +08:00
const ConstString
TargetInstanceSettings : : CreateInstanceName ( )
{
StreamString sstr ;
2010-09-27 08:30:10 +08:00
static int instance_count = 1 ;
2010-09-21 04:44:43 +08:00
sstr . Printf ( " target_%d " , instance_count ) ;
+ + instance_count ;
const ConstString ret_val ( sstr . GetData ( ) ) ;
return ret_val ;
}
//--------------------------------------------------
// Target::SettingsController Variable Tables
//--------------------------------------------------
2011-05-04 11:43:18 +08:00
OptionEnumValueElement
TargetInstanceSettings : : g_dynamic_value_types [ ] =
{
2011-05-30 08:39:48 +08:00
{ eNoDynamicValues , " no-dynamic-values " , " Don't calculate the dynamic type of values " } ,
{ eDynamicCanRunTarget , " run-target " , " Calculate the dynamic type of values even if you have to run the target. " } ,
{ eDynamicDontRunTarget , " no-run-target " , " Calculate the dynamic type of values, but don't run the target. " } ,
2011-05-04 11:43:18 +08:00
{ 0 , NULL , NULL }
} ;
2010-09-21 04:44:43 +08:00
SettingEntry
Target : : SettingsController : : global_settings_table [ ] =
{
2011-02-18 09:44:25 +08:00
// var-name var-type default enum init'd hidden help-text
// ================= ================== =========== ==== ====== ====== =========================================================================
{ TSC_DEFAULT_ARCH , eSetVarTypeString , NULL , NULL , false , false , " Default architecture to choose, when there's a choice. " } ,
{ NULL , eSetVarTypeNone , NULL , NULL , false , false , NULL }
} ;
2010-09-21 04:44:43 +08:00
SettingEntry
Target : : SettingsController : : instance_settings_table [ ] =
{
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
// var-name var-type default enum init'd hidden help-text
// ================= ================== =============== ======================= ====== ====== =========================================================================
{ TSC_EXPR_PREFIX , eSetVarTypeString , NULL , NULL , false , false , " Path to a file containing expressions to be prepended to all expressions. " } ,
{ TSC_PREFER_DYNAMIC , eSetVarTypeEnum , NULL , g_dynamic_value_types , false , false , " Should printed values be shown as their dynamic value. " } ,
{ TSC_SKIP_PROLOGUE , eSetVarTypeBoolean , " true " , NULL , false , false , " Skip function prologues when setting breakpoints by name. " } ,
{ TSC_SOURCE_MAP , eSetVarTypeArray , NULL , NULL , false , false , " Source path remappings to use when locating source files from debug information. " } ,
2012-02-14 07:10:39 +08:00
{ TSC_EXE_SEARCH_PATHS , eSetVarTypeArray , NULL , NULL , false , false , " Executable search paths to use when locating executable files whose paths don't match the local file system. " } ,
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
{ TSC_MAX_CHILDREN , eSetVarTypeInt , " 256 " , NULL , true , false , " Maximum number of children to expand in any level of depth. " } ,
{ TSC_MAX_STRLENSUMMARY , eSetVarTypeInt , " 1024 " , NULL , true , false , " Maximum number of characters to show when using %s in summary strings. " } ,
2011-10-29 07:14:11 +08:00
{ TSC_PLATFORM_AVOID , eSetVarTypeBoolean , " true " , NULL , false , false , " Consult the platform module avoid list when setting non-module specific breakpoints. " } ,
2011-11-08 10:43:13 +08:00
{ TSC_RUN_ARGS , eSetVarTypeArray , NULL , NULL , false , false , " A list containing all the arguments to be passed to the executable when it is run. " } ,
{ TSC_ENV_VARS , eSetVarTypeDictionary , NULL , NULL , false , false , " A list of all the environment variables to be passed to the executable's environment, and their values. " } ,
{ TSC_INHERIT_ENV , eSetVarTypeBoolean , " true " , NULL , false , false , " Inherit the environment from the process that is running LLDB. " } ,
{ TSC_STDIN_PATH , eSetVarTypeString , NULL , NULL , false , false , " The file/path to be used by the executable program for reading its standard input. " } ,
{ TSC_STDOUT_PATH , eSetVarTypeString , NULL , NULL , false , false , " The file/path to be used by the executable program for writing its standard output. " } ,
{ TSC_STDERR_PATH , eSetVarTypeString , NULL , NULL , false , false , " The file/path to be used by the executable program for writing its standard error. " } ,
// { "plugin", eSetVarTypeEnum, NULL, NULL, false, false, "The plugin to be used to run the process." },
{ TSC_DISABLE_ASLR , eSetVarTypeBoolean , " true " , NULL , false , false , " Disable Address Space Layout Randomization (ASLR) " } ,
{ TSC_DISABLE_STDIO , eSetVarTypeBoolean , " false " , NULL , false , false , " Disable stdin/stdout for process (e.g. for a GUI application) " } ,
Redesign of the interaction between Python and frozen objects:
- introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from
a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored
in frozen objects ; now such reads transparently move from host to target as required
- as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also
removed code that enabled to recognize an expression result VO as such
- introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO
representing a T* or T[], and doing dereferences transparently
in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData
- as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it
en lieu of doing the raw read itself
- introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers,
this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory)
in public layer this returns an SBData, just like GetPointeeData()
- introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData
the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any
of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values
- added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing
Solved a bug where global pointers to global variables were not dereferenced correctly for display
New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128
Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command
Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type
of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file
addresses that generate file address children UNLESS we have a live process)
Updated help text for summary-string
Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers
Edited the syntax and help for some commands to have proper argument types
llvm-svn: 139160
2011-09-07 03:20:51 +08:00
{ NULL , eSetVarTypeNone , NULL , NULL , false , false , NULL }
2010-09-21 04:44:43 +08:00
} ;
2012-02-16 14:50:00 +08:00
const ConstString &
Target : : TargetEventData : : GetFlavorString ( )
{
static ConstString g_flavor ( " Target::TargetEventData " ) ;
return g_flavor ;
}
const ConstString &
Target : : TargetEventData : : GetFlavor ( ) const
{
return TargetEventData : : GetFlavorString ( ) ;
}
Target : : TargetEventData : : TargetEventData ( const lldb : : TargetSP & new_target_sp ) :
EventData ( ) ,
m_target_sp ( new_target_sp )
{
}
Target : : TargetEventData : : ~ TargetEventData ( )
{
}
void
Target : : TargetEventData : : Dump ( Stream * s ) const
{
}
const TargetSP
Target : : TargetEventData : : GetTargetFromEvent ( const lldb : : EventSP & event_sp )
{
TargetSP target_sp ;
const TargetEventData * data = GetEventDataFromEvent ( event_sp . get ( ) ) ;
if ( data )
target_sp = data - > m_target_sp ;
return target_sp ;
}
const Target : : TargetEventData *
Target : : TargetEventData : : GetEventDataFromEvent ( const Event * event_ptr )
{
if ( event_ptr )
{
const EventData * event_data = event_ptr - > GetData ( ) ;
if ( event_data & & event_data - > GetFlavor ( ) = = TargetEventData : : GetFlavorString ( ) )
return static_cast < const TargetEventData * > ( event_ptr - > GetData ( ) ) ;
}
return NULL ;
}