diff options
Diffstat (limited to 'lldb/source/Host/macosx')
19 files changed, 2870 insertions, 3267 deletions
diff --git a/lldb/source/Host/macosx/Host.mm b/lldb/source/Host/macosx/Host.mm index 7754bc60ec1..01231ce2792 100644 --- a/lldb/source/Host/macosx/Host.mm +++ b/lldb/source/Host/macosx/Host.mm @@ -11,8 +11,9 @@ #include <AvailabilityMacros.h> -#if !defined(MAC_OS_X_VERSION_10_7) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 -#define NO_XPC_SERVICES 1 +#if !defined(MAC_OS_X_VERSION_10_7) || \ + MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 +#define NO_XPC_SERVICES 1 #endif #if !defined(NO_XPC_SERVICES) @@ -21,18 +22,19 @@ #define LaunchUsingXPCRightName "com.apple.dt.Xcode.RootDebuggingXPCService" -// These XPC messaging keys are used for communication between Host.mm and the XPC service. -#define LauncherXPCServiceAuthKey "auth-key" -#define LauncherXPCServiceArgPrefxKey "arg" -#define LauncherXPCServiceEnvPrefxKey "env" -#define LauncherXPCServiceCPUTypeKey "cpuType" -#define LauncherXPCServicePosixspawnFlagsKey "posixspawnFlags" -#define LauncherXPCServiceStdInPathKeyKey "stdInPath" -#define LauncherXPCServiceStdOutPathKeyKey "stdOutPath" -#define LauncherXPCServiceStdErrPathKeyKey "stdErrPath" -#define LauncherXPCServiceChildPIDKey "childPID" -#define LauncherXPCServiceErrorTypeKey "errorType" -#define LauncherXPCServiceCodeTypeKey "errorCode" +// These XPC messaging keys are used for communication between Host.mm and the +// XPC service. +#define LauncherXPCServiceAuthKey "auth-key" +#define LauncherXPCServiceArgPrefxKey "arg" +#define LauncherXPCServiceEnvPrefxKey "env" +#define LauncherXPCServiceCPUTypeKey "cpuType" +#define LauncherXPCServicePosixspawnFlagsKey "posixspawnFlags" +#define LauncherXPCServiceStdInPathKeyKey "stdInPath" +#define LauncherXPCServiceStdOutPathKeyKey "stdOutPath" +#define LauncherXPCServiceStdErrPathKeyKey "stdErrPath" +#define LauncherXPCServiceChildPIDKey "childPID" +#define LauncherXPCServiceErrorTypeKey "errorType" +#define LauncherXPCServiceCodeTypeKey "errorCode" #endif @@ -79,132 +81,112 @@ #include "cfcpp/CFCReleaser.h" #include "cfcpp/CFCString.h" - #include <objc/objc-auto.h> #include <CoreFoundation/CoreFoundation.h> #include <Foundation/Foundation.h> #ifndef _POSIX_SPAWN_DISABLE_ASLR -#define _POSIX_SPAWN_DISABLE_ASLR 0x0100 +#define _POSIX_SPAWN_DISABLE_ASLR 0x0100 #endif -extern "C" -{ - int __pthread_chdir(const char *path); - int __pthread_fchdir (int fildes); +extern "C" { +int __pthread_chdir(const char *path); +int __pthread_fchdir(int fildes); } using namespace lldb; using namespace lldb_private; -bool -Host::GetBundleDirectory (const FileSpec &file, FileSpec &bundle_directory) -{ -#if defined (__APPLE__) - if (file.GetFileType () == FileSpec::eFileTypeDirectory) - { - char path[PATH_MAX]; - if (file.GetPath(path, sizeof(path))) - { - CFCBundle bundle (path); - if (bundle.GetPath (path, sizeof(path))) - { - bundle_directory.SetFile (path, false); - return true; - } - } +bool Host::GetBundleDirectory(const FileSpec &file, + FileSpec &bundle_directory) { +#if defined(__APPLE__) + if (file.GetFileType() == FileSpec::eFileTypeDirectory) { + char path[PATH_MAX]; + if (file.GetPath(path, sizeof(path))) { + CFCBundle bundle(path); + if (bundle.GetPath(path, sizeof(path))) { + bundle_directory.SetFile(path, false); + return true; + } } + } #endif - bundle_directory.Clear(); - return false; + bundle_directory.Clear(); + return false; } - -bool -Host::ResolveExecutableInBundle (FileSpec &file) -{ -#if defined (__APPLE__) - if (file.GetFileType () == FileSpec::eFileTypeDirectory) - { - char path[PATH_MAX]; - if (file.GetPath(path, sizeof(path))) - { - CFCBundle bundle (path); - CFCReleaser<CFURLRef> url(bundle.CopyExecutableURL ()); - if (url.get()) - { - if (::CFURLGetFileSystemRepresentation (url.get(), YES, (UInt8*)path, sizeof(path))) - { - file.SetFile(path, false); - return true; - } - } +bool Host::ResolveExecutableInBundle(FileSpec &file) { +#if defined(__APPLE__) + if (file.GetFileType() == FileSpec::eFileTypeDirectory) { + char path[PATH_MAX]; + if (file.GetPath(path, sizeof(path))) { + CFCBundle bundle(path); + CFCReleaser<CFURLRef> url(bundle.CopyExecutableURL()); + if (url.get()) { + if (::CFURLGetFileSystemRepresentation(url.get(), YES, (UInt8 *)path, + sizeof(path))) { + file.SetFile(path, false); + return true; } + } } + } #endif return false; } -static void * -AcceptPIDFromInferior (void *arg) -{ - const char *connect_url = (const char *)arg; - ConnectionFileDescriptor file_conn; - Error error; - if (file_conn.Connect (connect_url, &error) == eConnectionStatusSuccess) - { - char pid_str[256]; - ::memset (pid_str, 0, sizeof(pid_str)); - ConnectionStatus status; - const size_t pid_str_len = file_conn.Read (pid_str, sizeof(pid_str), 0, status, NULL); - if (pid_str_len > 0) - { - int pid = atoi (pid_str); - return (void *)(intptr_t)pid; - } +static void *AcceptPIDFromInferior(void *arg) { + const char *connect_url = (const char *)arg; + ConnectionFileDescriptor file_conn; + Error error; + if (file_conn.Connect(connect_url, &error) == eConnectionStatusSuccess) { + char pid_str[256]; + ::memset(pid_str, 0, sizeof(pid_str)); + ConnectionStatus status; + const size_t pid_str_len = + file_conn.Read(pid_str, sizeof(pid_str), 0, status, NULL); + if (pid_str_len > 0) { + int pid = atoi(pid_str); + return (void *)(intptr_t)pid; } - return NULL; + } + return NULL; } -static bool -WaitForProcessToSIGSTOP (const lldb::pid_t pid, const int timeout_in_seconds) -{ - const int time_delta_usecs = 100000; - const int num_retries = timeout_in_seconds/time_delta_usecs; - for (int i=0; i<num_retries; i++) - { - struct proc_bsdinfo bsd_info; - int error = ::proc_pidinfo (pid, PROC_PIDTBSDINFO, - (uint64_t) 0, - &bsd_info, - PROC_PIDTBSDINFO_SIZE); - - switch (error) - { - case EINVAL: - case ENOTSUP: - case ESRCH: - case EPERM: - return false; - - default: - break; - - case 0: - if (bsd_info.pbi_status == SSTOP) - return true; - } - ::usleep (time_delta_usecs); +static bool WaitForProcessToSIGSTOP(const lldb::pid_t pid, + const int timeout_in_seconds) { + const int time_delta_usecs = 100000; + const int num_retries = timeout_in_seconds / time_delta_usecs; + for (int i = 0; i < num_retries; i++) { + struct proc_bsdinfo bsd_info; + int error = ::proc_pidinfo(pid, PROC_PIDTBSDINFO, (uint64_t)0, &bsd_info, + PROC_PIDTBSDINFO_SIZE); + + switch (error) { + case EINVAL: + case ENOTSUP: + case ESRCH: + case EPERM: + return false; + + default: + break; + + case 0: + if (bsd_info.pbi_status == SSTOP) + return true; } - return false; + ::usleep(time_delta_usecs); + } + return false; } #if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) -//static lldb::pid_t -//LaunchInNewTerminalWithCommandFile +// static lldb::pid_t +// LaunchInNewTerminalWithCommandFile //( -// const char **argv, +// const char **argv, // const char **envp, // const char *working_dir, // const ArchSpec *arch_spec, @@ -216,18 +198,19 @@ WaitForProcessToSIGSTOP (const lldb::pid_t pid, const int timeout_in_seconds) // return LLDB_INVALID_PROCESS_ID; // // OSStatus error = 0; -// +// // FileSpec program (argv[0], false); -// -// +// +// // std::string unix_socket_name; // // char temp_file_path[PATH_MAX]; // const char *tmpdir = ::getenv ("TMPDIR"); // if (tmpdir == NULL) // tmpdir = "/tmp/"; -// ::snprintf (temp_file_path, sizeof(temp_file_path), "%s%s-XXXXXX", tmpdir, program.GetFilename().AsCString()); -// +// ::snprintf (temp_file_path, sizeof(temp_file_path), "%s%s-XXXXXX", tmpdir, +// program.GetFilename().AsCString()); +// // if (::mktemp (temp_file_path) == NULL) // return LLDB_INVALID_PROCESS_ID; // @@ -236,15 +219,17 @@ WaitForProcessToSIGSTOP (const lldb::pid_t pid, const int timeout_in_seconds) // ::strlcat (temp_file_path, ".command", sizeof (temp_file_path)); // // StreamFile command_file; -// command_file.GetFile().Open (temp_file_path, -// File::eOpenOptionWrite | File::eOpenOptionCanCreate, +// command_file.GetFile().Open (temp_file_path, +// File::eOpenOptionWrite | +// File::eOpenOptionCanCreate, // lldb::eFilePermissionsDefault); -// +// // if (!command_file.GetFile().IsValid()) // return LLDB_INVALID_PROCESS_ID; -// +// // FileSpec darwin_debug_file_spec; -// if (!HostInfo::GetLLDBPath (ePathTypeSupportExecutableDir, darwin_debug_file_spec)) +// if (!HostInfo::GetLLDBPath (ePathTypeSupportExecutableDir, +// darwin_debug_file_spec)) // return LLDB_INVALID_PROCESS_ID; // darwin_debug_file_spec.GetFilename().SetCString("darwin-debug"); // @@ -296,7 +281,8 @@ WaitForProcessToSIGSTOP (const lldb::pid_t pid, const int timeout_in_seconds) // std::string env_val (equal_pos + 1); // CFCString cf_env_key (env_key.c_str(), kCFStringEncodingUTF8); // CFCString cf_env_val (env_val.c_str(), kCFStringEncodingUTF8); -// cf_env_dict.AddValue (cf_env_key.get(), cf_env_val.get(), can_create); +// cf_env_dict.AddValue (cf_env_key.get(), cf_env_val.get(), +// can_create); // } // } // } @@ -307,7 +293,8 @@ WaitForProcessToSIGSTOP (const lldb::pid_t pid, const int timeout_in_seconds) // app_params.argv = NULL; // app_params.environment = (CFDictionaryRef)cf_env_dict.get(); // -// CFCReleaser<CFURLRef> command_file_url (::CFURLCreateFromFileSystemRepresentation (NULL, +// CFCReleaser<CFURLRef> command_file_url +// (::CFURLCreateFromFileSystemRepresentation (NULL, // (const UInt8 *)temp_file_path, // strlen(temp_file_path), // false)); @@ -325,28 +312,33 @@ WaitForProcessToSIGSTOP (const lldb::pid_t pid, const int timeout_in_seconds) // Error lldb_error; // // Sleep and wait a bit for debugserver to start to listen... // char connect_url[128]; -// ::snprintf (connect_url, sizeof(connect_url), "unix-accept://%s", unix_socket_name.c_str()); +// ::snprintf (connect_url, sizeof(connect_url), "unix-accept://%s", +// unix_socket_name.c_str()); // // // Spawn a new thread to accept incoming connection on the connect_url // // so we can grab the pid from the inferior -// lldb::thread_t accept_thread = Host::ThreadCreate (unix_socket_name.c_str(), +// lldb::thread_t accept_thread = Host::ThreadCreate +// (unix_socket_name.c_str(), // AcceptPIDFromInferior, // connect_url, // &lldb_error); // // ProcessSerialNumber psn; -// error = LSOpenURLsWithRole(urls.get(), kLSRolesShell, NULL, &app_params, &psn, 1); +// error = LSOpenURLsWithRole(urls.get(), kLSRolesShell, NULL, &app_params, +// &psn, 1); // if (error == noErr) // { // thread_result_t accept_thread_result = NULL; -// if (Host::ThreadJoin (accept_thread, &accept_thread_result, &lldb_error)) +// if (Host::ThreadJoin (accept_thread, &accept_thread_result, +// &lldb_error)) // { // if (accept_thread_result) // { // pid = (intptr_t)accept_thread_result; // // // Wait for process to be stopped the entry point by watching -// // for the process status to be set to SSTOP which indicates it it +// // for the process status to be set to SSTOP which indicates +// it it // // SIGSTOP'ed at the entry point // WaitForProcessToSIGSTOP (pid, 5); // } @@ -360,12 +352,10 @@ WaitForProcessToSIGSTOP (const lldb::pid_t pid, const int timeout_in_seconds) // return pid; //} -const char *applscript_in_new_tty = -"tell application \"Terminal\"\n" -" activate\n" -" do script \"%s\"\n" -"end tell\n"; - +const char *applscript_in_new_tty = "tell application \"Terminal\"\n" + " activate\n" + " do script \"%s\"\n" + "end tell\n"; const char *applscript_in_existing_tty = "\ set the_shell_script to \"%s\"\n\ @@ -386,1202 +376,1128 @@ tell application \"Terminal\"\n\ do script the_shell_script\n\ end tell\n"; - static Error -LaunchInNewTerminalWithAppleScript (const char *exe_path, ProcessLaunchInfo &launch_info) -{ - Error error; - char unix_socket_name[PATH_MAX] = "/tmp/XXXXXX"; - if (::mktemp (unix_socket_name) == NULL) - { - error.SetErrorString ("failed to make temporary path for a unix socket"); - return error; - } - - StreamString command; - FileSpec darwin_debug_file_spec; - if (!HostInfo::GetLLDBPath(ePathTypeSupportExecutableDir, darwin_debug_file_spec)) - { - error.SetErrorString ("can't locate the 'darwin-debug' executable"); - return error; - } - - darwin_debug_file_spec.GetFilename().SetCString("darwin-debug"); - - if (!darwin_debug_file_spec.Exists()) - { - error.SetErrorStringWithFormat ("the 'darwin-debug' executable doesn't exists at '%s'", - darwin_debug_file_spec.GetPath().c_str()); - return error; - } - - char launcher_path[PATH_MAX]; - darwin_debug_file_spec.GetPath(launcher_path, sizeof(launcher_path)); - - const ArchSpec &arch_spec = launch_info.GetArchitecture(); - // Only set the architecture if it is valid and if it isn't Haswell (x86_64h). - if (arch_spec.IsValid() && arch_spec.GetCore() != ArchSpec::eCore_x86_64_x86_64h) - command.Printf("arch -arch %s ", arch_spec.GetArchitectureName()); +LaunchInNewTerminalWithAppleScript(const char *exe_path, + ProcessLaunchInfo &launch_info) { + Error error; + char unix_socket_name[PATH_MAX] = "/tmp/XXXXXX"; + if (::mktemp(unix_socket_name) == NULL) { + error.SetErrorString("failed to make temporary path for a unix socket"); + return error; + } - command.Printf("'%s' --unix-socket=%s", launcher_path, unix_socket_name); + StreamString command; + FileSpec darwin_debug_file_spec; + if (!HostInfo::GetLLDBPath(ePathTypeSupportExecutableDir, + darwin_debug_file_spec)) { + error.SetErrorString("can't locate the 'darwin-debug' executable"); + return error; + } - if (arch_spec.IsValid()) - command.Printf(" --arch=%s", arch_spec.GetArchitectureName()); + darwin_debug_file_spec.GetFilename().SetCString("darwin-debug"); - FileSpec working_dir{launch_info.GetWorkingDirectory()}; - if (working_dir) - command.Printf(" --working-dir '%s'", working_dir.GetCString()); - else - { - char cwd[PATH_MAX]; - if (getcwd(cwd, PATH_MAX)) - command.Printf(" --working-dir '%s'", cwd); - } - - if (launch_info.GetFlags().Test (eLaunchFlagDisableASLR)) - command.PutCString(" --disable-aslr"); - - // We are launching on this host in a terminal. So compare the environment on the host - // to what is supplied in the launch_info. Any items that aren't in the host environment - // need to be sent to darwin-debug. If we send all environment entries, we might blow the - // max command line length, so we only send user modified entries. - const char **envp = launch_info.GetEnvironmentEntries().GetConstArgumentVector (); - - StringList host_env; - const size_t host_env_count = Host::GetEnvironment (host_env); - - if (envp && envp[0]) - { - const char *env_entry; - for (size_t env_idx = 0; (env_entry = envp[env_idx]) != NULL; ++env_idx) - { - bool add_entry = true; - for (size_t i=0; i<host_env_count; ++i) - { - const char *host_env_entry = host_env.GetStringAtIndex(i); - if (strcmp(env_entry, host_env_entry) == 0) - { - add_entry = false; - break; - } - } - if (add_entry) - { - command.Printf(" --env='%s'", env_entry); - } + if (!darwin_debug_file_spec.Exists()) { + error.SetErrorStringWithFormat( + "the 'darwin-debug' executable doesn't exists at '%s'", + darwin_debug_file_spec.GetPath().c_str()); + return error; + } + + char launcher_path[PATH_MAX]; + darwin_debug_file_spec.GetPath(launcher_path, sizeof(launcher_path)); + + const ArchSpec &arch_spec = launch_info.GetArchitecture(); + // Only set the architecture if it is valid and if it isn't Haswell (x86_64h). + if (arch_spec.IsValid() && + arch_spec.GetCore() != ArchSpec::eCore_x86_64_x86_64h) + command.Printf("arch -arch %s ", arch_spec.GetArchitectureName()); + + command.Printf("'%s' --unix-socket=%s", launcher_path, unix_socket_name); + + if (arch_spec.IsValid()) + command.Printf(" --arch=%s", arch_spec.GetArchitectureName()); + + FileSpec working_dir{launch_info.GetWorkingDirectory()}; + if (working_dir) + command.Printf(" --working-dir '%s'", working_dir.GetCString()); + else { + char cwd[PATH_MAX]; + if (getcwd(cwd, PATH_MAX)) + command.Printf(" --working-dir '%s'", cwd); + } + + if (launch_info.GetFlags().Test(eLaunchFlagDisableASLR)) + command.PutCString(" --disable-aslr"); + + // We are launching on this host in a terminal. So compare the environment on + // the host + // to what is supplied in the launch_info. Any items that aren't in the host + // environment + // need to be sent to darwin-debug. If we send all environment entries, we + // might blow the + // max command line length, so we only send user modified entries. + const char **envp = + launch_info.GetEnvironmentEntries().GetConstArgumentVector(); + + StringList host_env; + const size_t host_env_count = Host::GetEnvironment(host_env); + + if (envp && envp[0]) { + const char *env_entry; + for (size_t env_idx = 0; (env_entry = envp[env_idx]) != NULL; ++env_idx) { + bool add_entry = true; + for (size_t i = 0; i < host_env_count; ++i) { + const char *host_env_entry = host_env.GetStringAtIndex(i); + if (strcmp(env_entry, host_env_entry) == 0) { + add_entry = false; + break; } + } + if (add_entry) { + command.Printf(" --env='%s'", env_entry); + } } + } - command.PutCString(" -- "); - - const char **argv = launch_info.GetArguments().GetConstArgumentVector (); - if (argv) - { - for (size_t i=0; argv[i] != NULL; ++i) - { - if (i==0) - command.Printf(" '%s'", exe_path); - else - command.Printf(" '%s'", argv[i]); - } - } - else - { - command.Printf(" '%s'", exe_path); - } - command.PutCString (" ; echo Process exited with status $?"); - if (launch_info.GetFlags().Test(lldb::eLaunchFlagCloseTTYOnExit)) - command.PutCString (" ; exit"); - - StreamString applescript_source; - - const char *tty_command = command.GetString().c_str(); -// if (tty_name && tty_name[0]) -// { -// applescript_source.Printf (applscript_in_existing_tty, -// tty_command, -// tty_name); -// } -// else -// { - applescript_source.Printf (applscript_in_new_tty, - tty_command); -// } + command.PutCString(" -- "); - - - const char *script_source = applescript_source.GetString().c_str(); - //puts (script_source); - NSAppleScript* applescript = [[NSAppleScript alloc] initWithSource:[NSString stringWithCString:script_source encoding:NSUTF8StringEncoding]]; - - lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; - - Error lldb_error; - // Sleep and wait a bit for debugserver to start to listen... - ConnectionFileDescriptor file_conn; - char connect_url[128]; - ::snprintf (connect_url, sizeof(connect_url), "unix-accept://%s", unix_socket_name); - - // Spawn a new thread to accept incoming connection on the connect_url - // so we can grab the pid from the inferior. We have to do this because we - // are sending an AppleScript that will launch a process in Terminal.app, - // in a shell and the shell will fork/exec a couple of times before we get - // to the process that we wanted to launch. So when our process actually - // gets launched, we will handshake with it and get the process ID for it. - HostThread accept_thread = ThreadLauncher::LaunchThread(unix_socket_name, AcceptPIDFromInferior, connect_url, &lldb_error); - - [applescript executeAndReturnError:nil]; - - thread_result_t accept_thread_result = NULL; - lldb_error = accept_thread.Join(&accept_thread_result); - if (lldb_error.Success() && accept_thread_result) - { - pid = (intptr_t)accept_thread_result; - - // Wait for process to be stopped at the entry point by watching - // for the process status to be set to SSTOP which indicates it it - // SIGSTOP'ed at the entry point - WaitForProcessToSIGSTOP(pid, 5); + const char **argv = launch_info.GetArguments().GetConstArgumentVector(); + if (argv) { + for (size_t i = 0; argv[i] != NULL; ++i) { + if (i == 0) + command.Printf(" '%s'", exe_path); + else + command.Printf(" '%s'", argv[i]); } - - FileSystem::Unlink(FileSpec{unix_socket_name, false}); - [applescript release]; - if (pid != LLDB_INVALID_PROCESS_ID) - launch_info.SetProcessID (pid); - return error; + } else { + command.Printf(" '%s'", exe_path); + } + command.PutCString(" ; echo Process exited with status $?"); + if (launch_info.GetFlags().Test(lldb::eLaunchFlagCloseTTYOnExit)) + command.PutCString(" ; exit"); + + StreamString applescript_source; + + const char *tty_command = command.GetString().c_str(); + // if (tty_name && tty_name[0]) + // { + // applescript_source.Printf (applscript_in_existing_tty, + // tty_command, + // tty_name); + // } + // else + // { + applescript_source.Printf(applscript_in_new_tty, tty_command); + // } + + const char *script_source = applescript_source.GetString().c_str(); + // puts (script_source); + NSAppleScript *applescript = [[NSAppleScript alloc] + initWithSource:[NSString stringWithCString:script_source + encoding:NSUTF8StringEncoding]]; + + lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; + + Error lldb_error; + // Sleep and wait a bit for debugserver to start to listen... + ConnectionFileDescriptor file_conn; + char connect_url[128]; + ::snprintf(connect_url, sizeof(connect_url), "unix-accept://%s", + unix_socket_name); + + // Spawn a new thread to accept incoming connection on the connect_url + // so we can grab the pid from the inferior. We have to do this because we + // are sending an AppleScript that will launch a process in Terminal.app, + // in a shell and the shell will fork/exec a couple of times before we get + // to the process that we wanted to launch. So when our process actually + // gets launched, we will handshake with it and get the process ID for it. + HostThread accept_thread = ThreadLauncher::LaunchThread( + unix_socket_name, AcceptPIDFromInferior, connect_url, &lldb_error); + + [applescript executeAndReturnError:nil]; + + thread_result_t accept_thread_result = NULL; + lldb_error = accept_thread.Join(&accept_thread_result); + if (lldb_error.Success() && accept_thread_result) { + pid = (intptr_t)accept_thread_result; + + // Wait for process to be stopped at the entry point by watching + // for the process status to be set to SSTOP which indicates it it + // SIGSTOP'ed at the entry point + WaitForProcessToSIGSTOP(pid, 5); + } + + FileSystem::Unlink(FileSpec{unix_socket_name, false}); + [applescript release]; + if (pid != LLDB_INVALID_PROCESS_ID) + launch_info.SetProcessID(pid); + return error; } #endif // #if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) - // On MacOSX CrashReporter will display a string for each shared library if // the shared library has an exported symbol named "__crashreporter_info__". -static std::mutex & -GetCrashReporterMutex() -{ - static std::mutex g_mutex; - return g_mutex; +static std::mutex &GetCrashReporterMutex() { + static std::mutex g_mutex; + return g_mutex; } extern "C" { - const char *__crashreporter_info__ = NULL; +const char *__crashreporter_info__ = NULL; } asm(".desc ___crashreporter_info__, 0x10"); -void -Host::SetCrashDescriptionWithFormat (const char *format, ...) -{ - static StreamString g_crash_description; - std::lock_guard<std::mutex> guard(GetCrashReporterMutex()); - - if (format) - { - va_list args; - va_start (args, format); - g_crash_description.GetString().clear(); - g_crash_description.PrintfVarArg(format, args); - va_end (args); - __crashreporter_info__ = g_crash_description.GetData(); - } - else - { - __crashreporter_info__ = NULL; - } +void Host::SetCrashDescriptionWithFormat(const char *format, ...) { + static StreamString g_crash_description; + std::lock_guard<std::mutex> guard(GetCrashReporterMutex()); + + if (format) { + va_list args; + va_start(args, format); + g_crash_description.GetString().clear(); + g_crash_description.PrintfVarArg(format, args); + va_end(args); + __crashreporter_info__ = g_crash_description.GetData(); + } else { + __crashreporter_info__ = NULL; + } } -void -Host::SetCrashDescription (const char *cstr) -{ - std::lock_guard<std::mutex> guard(GetCrashReporterMutex()); - static std::string g_crash_description; - if (cstr) - { - g_crash_description.assign (cstr); - __crashreporter_info__ = g_crash_description.c_str(); - } - else - { - __crashreporter_info__ = NULL; - } +void Host::SetCrashDescription(const char *cstr) { + std::lock_guard<std::mutex> guard(GetCrashReporterMutex()); + static std::string g_crash_description; + if (cstr) { + g_crash_description.assign(cstr); + __crashreporter_info__ = g_crash_description.c_str(); + } else { + __crashreporter_info__ = NULL; + } } -bool -Host::OpenFileInExternalEditor (const FileSpec &file_spec, uint32_t line_no) -{ +bool Host::OpenFileInExternalEditor(const FileSpec &file_spec, + uint32_t line_no) { #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) - return false; + return false; #else - // We attach this to an 'odoc' event to specify a particular selection - typedef struct { - int16_t reserved0; // must be zero - int16_t fLineNumber; - int32_t fSelStart; - int32_t fSelEnd; - uint32_t reserved1; // must be zero - uint32_t reserved2; // must be zero - } BabelAESelInfo; - - Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_HOST)); - char file_path[PATH_MAX]; - file_spec.GetPath(file_path, PATH_MAX); - CFCString file_cfstr (file_path, kCFStringEncodingUTF8); - CFCReleaser<CFURLRef> file_URL (::CFURLCreateWithFileSystemPath (NULL, - file_cfstr.get(), - kCFURLPOSIXPathStyle, - false)); - + // We attach this to an 'odoc' event to specify a particular selection + typedef struct { + int16_t reserved0; // must be zero + int16_t fLineNumber; + int32_t fSelStart; + int32_t fSelEnd; + uint32_t reserved1; // must be zero + uint32_t reserved2; // must be zero + } BabelAESelInfo; + + Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_HOST)); + char file_path[PATH_MAX]; + file_spec.GetPath(file_path, PATH_MAX); + CFCString file_cfstr(file_path, kCFStringEncodingUTF8); + CFCReleaser<CFURLRef> file_URL(::CFURLCreateWithFileSystemPath( + NULL, file_cfstr.get(), kCFURLPOSIXPathStyle, false)); + + if (log) + log->Printf( + "Sending source file: \"%s\" and line: %d to external editor.\n", + file_path, line_no); + + long error; + BabelAESelInfo file_and_line_info = { + 0, // reserved0 + (int16_t)(line_no - 1), // fLineNumber (zero based line number) + 1, // fSelStart + 1024, // fSelEnd + 0, // reserved1 + 0 // reserved2 + }; + + AEKeyDesc file_and_line_desc; + + error = ::AECreateDesc(typeUTF8Text, &file_and_line_info, + sizeof(file_and_line_info), + &(file_and_line_desc.descContent)); + + if (error != noErr) { if (log) - log->Printf("Sending source file: \"%s\" and line: %d to external editor.\n", file_path, line_no); - - long error; - BabelAESelInfo file_and_line_info = - { - 0, // reserved0 - (int16_t)(line_no - 1), // fLineNumber (zero based line number) - 1, // fSelStart - 1024, // fSelEnd - 0, // reserved1 - 0 // reserved2 - }; + log->Printf("Error creating AEDesc: %ld.\n", error); + return false; + } + + file_and_line_desc.descKey = keyAEPosition; + + static std::string g_app_name; + static FSRef g_app_fsref; + + LSApplicationParameters app_params; + ::memset(&app_params, 0, sizeof(app_params)); + app_params.flags = + kLSLaunchDefaults | kLSLaunchDontAddToRecents | kLSLaunchDontSwitch; + + char *external_editor = ::getenv("LLDB_EXTERNAL_EDITOR"); + + if (external_editor) { + if (log) + log->Printf("Looking for external editor \"%s\".\n", external_editor); - AEKeyDesc file_and_line_desc; - - error = ::AECreateDesc (typeUTF8Text, - &file_and_line_info, - sizeof (file_and_line_info), - &(file_and_line_desc.descContent)); - - if (error != noErr) - { + if (g_app_name.empty() || + strcmp(g_app_name.c_str(), external_editor) != 0) { + CFCString editor_name(external_editor, kCFStringEncodingUTF8); + error = ::LSFindApplicationForInfo(kLSUnknownCreator, NULL, + editor_name.get(), &g_app_fsref, NULL); + + // If we found the app, then store away the name so we don't have to + // re-look it up. + if (error != noErr) { if (log) - log->Printf("Error creating AEDesc: %ld.\n", error); + log->Printf( + "Could not find External Editor application, error: %ld.\n", + error); return false; + } } - - file_and_line_desc.descKey = keyAEPosition; - - static std::string g_app_name; - static FSRef g_app_fsref; - - LSApplicationParameters app_params; - ::memset (&app_params, 0, sizeof (app_params)); - app_params.flags = kLSLaunchDefaults | - kLSLaunchDontAddToRecents | - kLSLaunchDontSwitch; - - char *external_editor = ::getenv ("LLDB_EXTERNAL_EDITOR"); - - if (external_editor) - { - if (log) - log->Printf("Looking for external editor \"%s\".\n", external_editor); - - if (g_app_name.empty() || strcmp (g_app_name.c_str(), external_editor) != 0) - { - CFCString editor_name (external_editor, kCFStringEncodingUTF8); - error = ::LSFindApplicationForInfo (kLSUnknownCreator, - NULL, - editor_name.get(), - &g_app_fsref, - NULL); - - // If we found the app, then store away the name so we don't have to re-look it up. - if (error != noErr) - { - if (log) - log->Printf("Could not find External Editor application, error: %ld.\n", error); - return false; - } - - } - app_params.application = &g_app_fsref; - } + app_params.application = &g_app_fsref; + } - ProcessSerialNumber psn; - CFCReleaser<CFArrayRef> file_array(CFArrayCreate (NULL, (const void **) file_URL.ptr_address(false), 1, NULL)); - error = ::LSOpenURLsWithRole (file_array.get(), - kLSRolesAll, - &file_and_line_desc, - &app_params, - &psn, - 1); - - AEDisposeDesc (&(file_and_line_desc.descContent)); - - if (error != noErr) - { - if (log) - log->Printf("LSOpenURLsWithRole failed, error: %ld.\n", error); + ProcessSerialNumber psn; + CFCReleaser<CFArrayRef> file_array( + CFArrayCreate(NULL, (const void **)file_URL.ptr_address(false), 1, NULL)); + error = ::LSOpenURLsWithRole(file_array.get(), kLSRolesAll, + &file_and_line_desc, &app_params, &psn, 1); - return false; - } + AEDisposeDesc(&(file_and_line_desc.descContent)); - return true; + if (error != noErr) { + if (log) + log->Printf("LSOpenURLsWithRole failed, error: %ld.\n", error); + + return false; + } + + return true; #endif // #if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) } -size_t -Host::GetEnvironment (StringList &env) -{ - char **host_env = *_NSGetEnviron(); - char *env_entry; - size_t i; - for (i=0; (env_entry = host_env[i]) != NULL; ++i) - env.AppendString(env_entry); - return i; - +size_t Host::GetEnvironment(StringList &env) { + char **host_env = *_NSGetEnviron(); + char *env_entry; + size_t i; + for (i = 0; (env_entry = host_env[i]) != NULL; ++i) + env.AppendString(env_entry); + return i; } -static bool -GetMacOSXProcessCPUType (ProcessInstanceInfo &process_info) -{ - if (process_info.ProcessIDIsValid()) - { - // Make a new mib to stay thread safe - int mib[CTL_MAXNAME]={0,}; - size_t mib_len = CTL_MAXNAME; - if (::sysctlnametomib("sysctl.proc_cputype", mib, &mib_len)) - return false; - - mib[mib_len] = process_info.GetProcessID(); - mib_len++; - - cpu_type_t cpu, sub = 0; - size_t len = sizeof(cpu); - if (::sysctl (mib, mib_len, &cpu, &len, 0, 0) == 0) - { - switch (cpu) - { - case CPU_TYPE_I386: sub = CPU_SUBTYPE_I386_ALL; break; - case CPU_TYPE_X86_64: sub = CPU_SUBTYPE_X86_64_ALL; break; - -#if defined (CPU_TYPE_ARM64) && defined (CPU_SUBTYPE_ARM64_ALL) - case CPU_TYPE_ARM64: sub = CPU_SUBTYPE_ARM64_ALL; break; +static bool GetMacOSXProcessCPUType(ProcessInstanceInfo &process_info) { + if (process_info.ProcessIDIsValid()) { + // Make a new mib to stay thread safe + int mib[CTL_MAXNAME] = { + 0, + }; + size_t mib_len = CTL_MAXNAME; + if (::sysctlnametomib("sysctl.proc_cputype", mib, &mib_len)) + return false; + + mib[mib_len] = process_info.GetProcessID(); + mib_len++; + + cpu_type_t cpu, sub = 0; + size_t len = sizeof(cpu); + if (::sysctl(mib, mib_len, &cpu, &len, 0, 0) == 0) { + switch (cpu) { + case CPU_TYPE_I386: + sub = CPU_SUBTYPE_I386_ALL; + break; + case CPU_TYPE_X86_64: + sub = CPU_SUBTYPE_X86_64_ALL; + break; + +#if defined(CPU_TYPE_ARM64) && defined(CPU_SUBTYPE_ARM64_ALL) + case CPU_TYPE_ARM64: + sub = CPU_SUBTYPE_ARM64_ALL; + break; #endif - case CPU_TYPE_ARM: - { - // Note that we fetched the cpu type from the PROCESS but we can't get a cpusubtype of the - // process -- we can only get the host's cpu subtype. - uint32_t cpusubtype = 0; - len = sizeof(cpusubtype); - if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0) - sub = cpusubtype; - - bool host_cpu_is_64bit; - uint32_t is64bit_capable; - size_t is64bit_capable_len = sizeof (is64bit_capable); - if (sysctlbyname("hw.cpu64bit_capable", &is64bit_capable, &is64bit_capable_len, NULL, 0) == 0) - host_cpu_is_64bit = true; - else - host_cpu_is_64bit = false; - - // if the host is an armv8 device, its cpusubtype will be in CPU_SUBTYPE_ARM64 numbering - // and we need to rewrite it to a reasonable CPU_SUBTYPE_ARM value instead. - - if (host_cpu_is_64bit) - { - sub = CPU_SUBTYPE_ARM_V7; - } - } - break; - - default: - break; - } - process_info.GetArchitecture ().SetArchitecture (eArchTypeMachO, cpu, sub); - return true; + case CPU_TYPE_ARM: { + // Note that we fetched the cpu type from the PROCESS but we can't get a + // cpusubtype of the + // process -- we can only get the host's cpu subtype. + uint32_t cpusubtype = 0; + len = sizeof(cpusubtype); + if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0) + sub = cpusubtype; + + bool host_cpu_is_64bit; + uint32_t is64bit_capable; + size_t is64bit_capable_len = sizeof(is64bit_capable); + if (sysctlbyname("hw.cpu64bit_capable", &is64bit_capable, + &is64bit_capable_len, NULL, 0) == 0) + host_cpu_is_64bit = true; + else + host_cpu_is_64bit = false; + + // if the host is an armv8 device, its cpusubtype will be in + // CPU_SUBTYPE_ARM64 numbering + // and we need to rewrite it to a reasonable CPU_SUBTYPE_ARM value + // instead. + + if (host_cpu_is_64bit) { + sub = CPU_SUBTYPE_ARM_V7; } + } break; + + default: + break; + } + process_info.GetArchitecture().SetArchitecture(eArchTypeMachO, cpu, sub); + return true; } - process_info.GetArchitecture().Clear(); - return false; + } + process_info.GetArchitecture().Clear(); + return false; } -static bool -GetMacOSXProcessArgs (const ProcessInstanceInfoMatch *match_info_ptr, - ProcessInstanceInfo &process_info) -{ - if (process_info.ProcessIDIsValid()) - { - int proc_args_mib[3] = { CTL_KERN, KERN_PROCARGS2, (int)process_info.GetProcessID() }; - - size_t arg_data_size = 0; - if (::sysctl (proc_args_mib, 3, nullptr, &arg_data_size, NULL, 0) || arg_data_size == 0) - arg_data_size = 8192; - - // Add a few bytes to the calculated length, I know we need to add at least one byte - // to this number otherwise we get junk back, so add 128 just in case... - DataBufferHeap arg_data(arg_data_size+128, 0); - arg_data_size = arg_data.GetByteSize(); - if (::sysctl (proc_args_mib, 3, arg_data.GetBytes(), &arg_data_size , NULL, 0) == 0) - { - DataExtractor data (arg_data.GetBytes(), arg_data_size, endian::InlHostByteOrder(), sizeof(void *)); - lldb::offset_t offset = 0; - uint32_t argc = data.GetU32 (&offset); - llvm::Triple &triple = process_info.GetArchitecture().GetTriple(); - const llvm::Triple::ArchType triple_arch = triple.getArch(); - const bool check_for_ios_simulator = (triple_arch == llvm::Triple::x86 || triple_arch == llvm::Triple::x86_64); - const char *cstr = data.GetCStr (&offset); +static bool GetMacOSXProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr, + ProcessInstanceInfo &process_info) { + if (process_info.ProcessIDIsValid()) { + int proc_args_mib[3] = {CTL_KERN, KERN_PROCARGS2, + (int)process_info.GetProcessID()}; + + size_t arg_data_size = 0; + if (::sysctl(proc_args_mib, 3, nullptr, &arg_data_size, NULL, 0) || + arg_data_size == 0) + arg_data_size = 8192; + + // Add a few bytes to the calculated length, I know we need to add at least + // one byte + // to this number otherwise we get junk back, so add 128 just in case... + DataBufferHeap arg_data(arg_data_size + 128, 0); + arg_data_size = arg_data.GetByteSize(); + if (::sysctl(proc_args_mib, 3, arg_data.GetBytes(), &arg_data_size, NULL, + 0) == 0) { + DataExtractor data(arg_data.GetBytes(), arg_data_size, + endian::InlHostByteOrder(), sizeof(void *)); + lldb::offset_t offset = 0; + uint32_t argc = data.GetU32(&offset); + llvm::Triple &triple = process_info.GetArchitecture().GetTriple(); + const llvm::Triple::ArchType triple_arch = triple.getArch(); + const bool check_for_ios_simulator = + (triple_arch == llvm::Triple::x86 || + triple_arch == llvm::Triple::x86_64); + const char *cstr = data.GetCStr(&offset); + if (cstr) { + process_info.GetExecutableFile().SetFile(cstr, false); + + if (match_info_ptr == NULL || + NameMatches( + process_info.GetExecutableFile().GetFilename().GetCString(), + match_info_ptr->GetNameMatchType(), + match_info_ptr->GetProcessInfo().GetName())) { + // Skip NULLs + while (1) { + const uint8_t *p = data.PeekData(offset, 1); + if ((p == NULL) || (*p != '\0')) + break; + ++offset; + } + // Now extract all arguments + Args &proc_args = process_info.GetArguments(); + for (int i = 0; i < static_cast<int>(argc); ++i) { + cstr = data.GetCStr(&offset); if (cstr) - { - process_info.GetExecutableFile().SetFile(cstr, false); - - if (match_info_ptr == NULL || - NameMatches (process_info.GetExecutableFile().GetFilename().GetCString(), - match_info_ptr->GetNameMatchType(), - match_info_ptr->GetProcessInfo().GetName())) - { - // Skip NULLs - while (1) - { - const uint8_t *p = data.PeekData(offset, 1); - if ((p == NULL) || (*p != '\0')) - break; - ++offset; - } - // Now extract all arguments - Args &proc_args = process_info.GetArguments(); - for (int i=0; i<static_cast<int>(argc); ++i) - { - cstr = data.GetCStr(&offset); - if (cstr) - proc_args.AppendArgument(cstr); - } - - Args &proc_env = process_info.GetEnvironmentEntries (); - while ((cstr = data.GetCStr(&offset))) - { - if (cstr[0] == '\0') - break; - - if (check_for_ios_simulator) - { - if (strncmp(cstr, "SIMULATOR_UDID=", strlen("SIMULATOR_UDID=")) == 0) - process_info.GetArchitecture().GetTriple().setOS(llvm::Triple::IOS); - else - process_info.GetArchitecture().GetTriple().setOS(llvm::Triple::MacOSX); - } - - proc_env.AppendArgument(cstr); - } - return true; - } + proc_args.AppendArgument(cstr); + } + + Args &proc_env = process_info.GetEnvironmentEntries(); + while ((cstr = data.GetCStr(&offset))) { + if (cstr[0] == '\0') + break; + + if (check_for_ios_simulator) { + if (strncmp(cstr, "SIMULATOR_UDID=", strlen("SIMULATOR_UDID=")) == + 0) + process_info.GetArchitecture().GetTriple().setOS( + llvm::Triple::IOS); + else + process_info.GetArchitecture().GetTriple().setOS( + llvm::Triple::MacOSX); } + + proc_env.AppendArgument(cstr); + } + return true; } + } } - return false; + } + return false; } -static bool -GetMacOSXProcessUserAndGroup (ProcessInstanceInfo &process_info) -{ - if (process_info.ProcessIDIsValid()) - { - int mib[4]; - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PID; - mib[3] = process_info.GetProcessID(); - struct kinfo_proc proc_kinfo; - size_t proc_kinfo_size = sizeof(struct kinfo_proc); - - if (::sysctl (mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0) - { - if (proc_kinfo_size > 0) - { - process_info.SetParentProcessID (proc_kinfo.kp_eproc.e_ppid); - process_info.SetUserID (proc_kinfo.kp_eproc.e_pcred.p_ruid); - process_info.SetGroupID (proc_kinfo.kp_eproc.e_pcred.p_rgid); - process_info.SetEffectiveUserID (proc_kinfo.kp_eproc.e_ucred.cr_uid); - if (proc_kinfo.kp_eproc.e_ucred.cr_ngroups > 0) - process_info.SetEffectiveGroupID (proc_kinfo.kp_eproc.e_ucred.cr_groups[0]); - else - process_info.SetEffectiveGroupID (UINT32_MAX); - return true; - } - } +static bool GetMacOSXProcessUserAndGroup(ProcessInstanceInfo &process_info) { + if (process_info.ProcessIDIsValid()) { + int mib[4]; + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PID; + mib[3] = process_info.GetProcessID(); + struct kinfo_proc proc_kinfo; + size_t proc_kinfo_size = sizeof(struct kinfo_proc); + + if (::sysctl(mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0) { + if (proc_kinfo_size > 0) { + process_info.SetParentProcessID(proc_kinfo.kp_eproc.e_ppid); + process_info.SetUserID(proc_kinfo.kp_eproc.e_pcred.p_ruid); + process_info.SetGroupID(proc_kinfo.kp_eproc.e_pcred.p_rgid); + process_info.SetEffectiveUserID(proc_kinfo.kp_eproc.e_ucred.cr_uid); + if (proc_kinfo.kp_eproc.e_ucred.cr_ngroups > 0) + process_info.SetEffectiveGroupID( + proc_kinfo.kp_eproc.e_ucred.cr_groups[0]); + else + process_info.SetEffectiveGroupID(UINT32_MAX); + return true; + } } - process_info.SetParentProcessID (LLDB_INVALID_PROCESS_ID); - process_info.SetUserID (UINT32_MAX); - process_info.SetGroupID (UINT32_MAX); - process_info.SetEffectiveUserID (UINT32_MAX); - process_info.SetEffectiveGroupID (UINT32_MAX); - return false; + } + process_info.SetParentProcessID(LLDB_INVALID_PROCESS_ID); + process_info.SetUserID(UINT32_MAX); + process_info.SetGroupID(UINT32_MAX); + process_info.SetEffectiveUserID(UINT32_MAX); + process_info.SetEffectiveGroupID(UINT32_MAX); + return false; } +uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info, + ProcessInstanceInfoList &process_infos) { + std::vector<struct kinfo_proc> kinfos; -uint32_t -Host::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos) -{ - std::vector<struct kinfo_proc> kinfos; - - int mib[3] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL }; - - size_t pid_data_size = 0; - if (::sysctl (mib, 4, NULL, &pid_data_size, NULL, 0) != 0) - return 0; - - // Add a few extra in case a few more show up - const size_t estimated_pid_count = (pid_data_size / sizeof(struct kinfo_proc)) + 10; - - kinfos.resize (estimated_pid_count); - pid_data_size = kinfos.size() * sizeof(struct kinfo_proc); - - if (::sysctl (mib, 4, &kinfos[0], &pid_data_size, NULL, 0) != 0) - return 0; - - const size_t actual_pid_count = (pid_data_size / sizeof(struct kinfo_proc)); - - bool all_users = match_info.GetMatchAllUsers(); - const lldb::pid_t our_pid = getpid(); - const uid_t our_uid = getuid(); - for (size_t i = 0; i < actual_pid_count; i++) - { - const struct kinfo_proc &kinfo = kinfos[i]; - - bool kinfo_user_matches = false; - if (all_users) - kinfo_user_matches = true; - else - kinfo_user_matches = kinfo.kp_eproc.e_pcred.p_ruid == our_uid; - - // Special case, if lldb is being run as root we can attach to anything. - if (our_uid == 0) - kinfo_user_matches = true; - - if (kinfo_user_matches == false || // Make sure the user is acceptable - static_cast<lldb::pid_t>(kinfo.kp_proc.p_pid) == our_pid || // Skip this process - kinfo.kp_proc.p_pid == 0 || // Skip kernel (kernel pid is zero) - kinfo.kp_proc.p_stat == SZOMB || // Zombies are bad, they like brains... - kinfo.kp_proc.p_flag & P_TRACED || // Being debugged? - kinfo.kp_proc.p_flag & P_WEXIT || // Working on exiting? - kinfo.kp_proc.p_flag & P_TRANSLATED) // Skip translated ppc (Rosetta) - continue; - - ProcessInstanceInfo process_info; - process_info.SetProcessID (kinfo.kp_proc.p_pid); - process_info.SetParentProcessID (kinfo.kp_eproc.e_ppid); - process_info.SetUserID (kinfo.kp_eproc.e_pcred.p_ruid); - process_info.SetGroupID (kinfo.kp_eproc.e_pcred.p_rgid); - process_info.SetEffectiveUserID (kinfo.kp_eproc.e_ucred.cr_uid); - if (kinfo.kp_eproc.e_ucred.cr_ngroups > 0) - process_info.SetEffectiveGroupID (kinfo.kp_eproc.e_ucred.cr_groups[0]); - else - process_info.SetEffectiveGroupID (UINT32_MAX); - - // Make sure our info matches before we go fetch the name and cpu type - if (match_info.Matches (process_info)) - { - // Get CPU type first so we can know to look for iOS simulator is we have x86 or x86_64 - if (GetMacOSXProcessCPUType (process_info)) - { - if (GetMacOSXProcessArgs (&match_info, process_info)) - { - if (match_info.Matches (process_info)) - process_infos.Append (process_info); - } - } + int mib[3] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL}; + + size_t pid_data_size = 0; + if (::sysctl(mib, 4, NULL, &pid_data_size, NULL, 0) != 0) + return 0; + + // Add a few extra in case a few more show up + const size_t estimated_pid_count = + (pid_data_size / sizeof(struct kinfo_proc)) + 10; + + kinfos.resize(estimated_pid_count); + pid_data_size = kinfos.size() * sizeof(struct kinfo_proc); + + if (::sysctl(mib, 4, &kinfos[0], &pid_data_size, NULL, 0) != 0) + return 0; + + const size_t actual_pid_count = (pid_data_size / sizeof(struct kinfo_proc)); + + bool all_users = match_info.GetMatchAllUsers(); + const lldb::pid_t our_pid = getpid(); + const uid_t our_uid = getuid(); + for (size_t i = 0; i < actual_pid_count; i++) { + const struct kinfo_proc &kinfo = kinfos[i]; + + bool kinfo_user_matches = false; + if (all_users) + kinfo_user_matches = true; + else + kinfo_user_matches = kinfo.kp_eproc.e_pcred.p_ruid == our_uid; + + // Special case, if lldb is being run as root we can attach to anything. + if (our_uid == 0) + kinfo_user_matches = true; + + if (kinfo_user_matches == false || // Make sure the user is acceptable + static_cast<lldb::pid_t>(kinfo.kp_proc.p_pid) == + our_pid || // Skip this process + kinfo.kp_proc.p_pid == 0 || // Skip kernel (kernel pid is zero) + kinfo.kp_proc.p_stat == SZOMB || // Zombies are bad, they like brains... + kinfo.kp_proc.p_flag & P_TRACED || // Being debugged? + kinfo.kp_proc.p_flag & P_WEXIT || // Working on exiting? + kinfo.kp_proc.p_flag & P_TRANSLATED) // Skip translated ppc (Rosetta) + continue; + + ProcessInstanceInfo process_info; + process_info.SetProcessID(kinfo.kp_proc.p_pid); + process_info.SetParentProcessID(kinfo.kp_eproc.e_ppid); + process_info.SetUserID(kinfo.kp_eproc.e_pcred.p_ruid); + process_info.SetGroupID(kinfo.kp_eproc.e_pcred.p_rgid); + process_info.SetEffectiveUserID(kinfo.kp_eproc.e_ucred.cr_uid); + if (kinfo.kp_eproc.e_ucred.cr_ngroups > 0) + process_info.SetEffectiveGroupID(kinfo.kp_eproc.e_ucred.cr_groups[0]); + else + process_info.SetEffectiveGroupID(UINT32_MAX); + + // Make sure our info matches before we go fetch the name and cpu type + if (match_info.Matches(process_info)) { + // Get CPU type first so we can know to look for iOS simulator is we have + // x86 or x86_64 + if (GetMacOSXProcessCPUType(process_info)) { + if (GetMacOSXProcessArgs(&match_info, process_info)) { + if (match_info.Matches(process_info)) + process_infos.Append(process_info); } - } - return process_infos.GetSize(); + } + } + } + return process_infos.GetSize(); } -bool -Host::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) -{ - process_info.SetProcessID(pid); - bool success = false; - - // Get CPU type first so we can know to look for iOS simulator is we have x86 or x86_64 - if (GetMacOSXProcessCPUType (process_info)) - success = true; - - if (GetMacOSXProcessArgs (NULL, process_info)) - success = true; - - if (GetMacOSXProcessUserAndGroup (process_info)) - success = true; - - if (success) - return true; - - process_info.Clear(); - return false; +bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) { + process_info.SetProcessID(pid); + bool success = false; + + // Get CPU type first so we can know to look for iOS simulator is we have x86 + // or x86_64 + if (GetMacOSXProcessCPUType(process_info)) + success = true; + + if (GetMacOSXProcessArgs(NULL, process_info)) + success = true; + + if (GetMacOSXProcessUserAndGroup(process_info)) + success = true; + + if (success) + return true; + + process_info.Clear(); + return false; } #if !NO_XPC_SERVICES -static void -PackageXPCArguments (xpc_object_t message, const char *prefix, const Args& args) -{ - size_t count = args.GetArgumentCount(); - char buf[50]; // long enough for 'argXXX' +static void PackageXPCArguments(xpc_object_t message, const char *prefix, + const Args &args) { + size_t count = args.GetArgumentCount(); + char buf[50]; // long enough for 'argXXX' + memset(buf, 0, 50); + sprintf(buf, "%sCount", prefix); + xpc_dictionary_set_int64(message, buf, count); + for (size_t i = 0; i < count; i++) { memset(buf, 0, 50); - sprintf(buf, "%sCount", prefix); - xpc_dictionary_set_int64(message, buf, count); - for (size_t i=0; i<count; i++) { - memset(buf, 0, 50); - sprintf(buf, "%s%zi", prefix, i); - xpc_dictionary_set_string(message, buf, args.GetArgumentAtIndex(i)); - } + sprintf(buf, "%s%zi", prefix, i); + xpc_dictionary_set_string(message, buf, args.GetArgumentAtIndex(i)); + } } /* - A valid authorizationRef means that + A valid authorizationRef means that - there is the LaunchUsingXPCRightName rights in the /etc/authorization - we have successfully copied the rights to be send over the XPC wire Once obtained, it will be valid for as long as the process lives. */ static AuthorizationRef authorizationRef = NULL; -static Error -getXPCAuthorization (ProcessLaunchInfo &launch_info) -{ - Error error; - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS)); - - if ((launch_info.GetUserID() == 0) && !authorizationRef) - { - OSStatus createStatus = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authorizationRef); - if (createStatus != errAuthorizationSuccess) - { - error.SetError(1, eErrorTypeGeneric); - error.SetErrorString("Can't create authorizationRef."); - if (log) - { - error.PutToLog(log, "%s", error.AsCString()); - } - return error; - } - - OSStatus rightsStatus = AuthorizationRightGet(LaunchUsingXPCRightName, NULL); - if (rightsStatus != errAuthorizationSuccess) - { - // No rights in the security database, Create it with the right prompt. - CFStringRef prompt = CFSTR("Xcode is trying to take control of a root process."); - CFStringRef keys[] = { CFSTR("en") }; - CFTypeRef values[] = { prompt }; - CFDictionaryRef promptDict = CFDictionaryCreate(kCFAllocatorDefault, (const void **)keys, (const void **)values, 1, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - - CFStringRef keys1[] = { CFSTR("class"), CFSTR("group"), CFSTR("comment"), CFSTR("default-prompt"), CFSTR("shared") }; - CFTypeRef values1[] = { CFSTR("user"), CFSTR("admin"), CFSTR(LaunchUsingXPCRightName), promptDict, kCFBooleanFalse }; - CFDictionaryRef dict = CFDictionaryCreate(kCFAllocatorDefault, (const void **)keys1, (const void **)values1, 5, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - rightsStatus = AuthorizationRightSet(authorizationRef, LaunchUsingXPCRightName, dict, NULL, NULL, NULL); - CFRelease(promptDict); - CFRelease(dict); - } - - OSStatus copyRightStatus = errAuthorizationDenied; - if (rightsStatus == errAuthorizationSuccess) - { - AuthorizationItem item1 = { LaunchUsingXPCRightName, 0, NULL, 0 }; - AuthorizationItem items[] = {item1}; - AuthorizationRights requestedRights = {1, items }; - AuthorizationFlags authorizationFlags = kAuthorizationFlagInteractionAllowed | kAuthorizationFlagExtendRights; - copyRightStatus = AuthorizationCopyRights(authorizationRef, &requestedRights, kAuthorizationEmptyEnvironment, authorizationFlags, NULL); - } - - if (copyRightStatus != errAuthorizationSuccess) - { - // Eventually when the commandline supports running as root and the user is not - // logged in in the current audit session, we will need the trick in gdb where - // we ask the user to type in the root passwd in the terminal. - error.SetError(2, eErrorTypeGeneric); - error.SetErrorStringWithFormat("Launching as root needs root authorization."); - if (log) - { - error.PutToLog(log, "%s", error.AsCString()); - } - - if (authorizationRef) - { - AuthorizationFree(authorizationRef, kAuthorizationFlagDefaults); - authorizationRef = NULL; - } - } +static Error getXPCAuthorization(ProcessLaunchInfo &launch_info) { + Error error; + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST | + LIBLLDB_LOG_PROCESS)); + + if ((launch_info.GetUserID() == 0) && !authorizationRef) { + OSStatus createStatus = + AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, + kAuthorizationFlagDefaults, &authorizationRef); + if (createStatus != errAuthorizationSuccess) { + error.SetError(1, eErrorTypeGeneric); + error.SetErrorString("Can't create authorizationRef."); + if (log) { + error.PutToLog(log, "%s", error.AsCString()); + } + return error; } - return error; + OSStatus rightsStatus = + AuthorizationRightGet(LaunchUsingXPCRightName, NULL); + if (rightsStatus != errAuthorizationSuccess) { + // No rights in the security database, Create it with the right prompt. + CFStringRef prompt = + CFSTR("Xcode is trying to take control of a root process."); + CFStringRef keys[] = {CFSTR("en")}; + CFTypeRef values[] = {prompt}; + CFDictionaryRef promptDict = CFDictionaryCreate( + kCFAllocatorDefault, (const void **)keys, (const void **)values, 1, + &kCFCopyStringDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + CFStringRef keys1[] = {CFSTR("class"), CFSTR("group"), CFSTR("comment"), + CFSTR("default-prompt"), CFSTR("shared")}; + CFTypeRef values1[] = {CFSTR("user"), CFSTR("admin"), + CFSTR(LaunchUsingXPCRightName), promptDict, + kCFBooleanFalse}; + CFDictionaryRef dict = CFDictionaryCreate( + kCFAllocatorDefault, (const void **)keys1, (const void **)values1, 5, + &kCFCopyStringDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + rightsStatus = AuthorizationRightSet( + authorizationRef, LaunchUsingXPCRightName, dict, NULL, NULL, NULL); + CFRelease(promptDict); + CFRelease(dict); + } + + OSStatus copyRightStatus = errAuthorizationDenied; + if (rightsStatus == errAuthorizationSuccess) { + AuthorizationItem item1 = {LaunchUsingXPCRightName, 0, NULL, 0}; + AuthorizationItem items[] = {item1}; + AuthorizationRights requestedRights = {1, items}; + AuthorizationFlags authorizationFlags = + kAuthorizationFlagInteractionAllowed | kAuthorizationFlagExtendRights; + copyRightStatus = AuthorizationCopyRights( + authorizationRef, &requestedRights, kAuthorizationEmptyEnvironment, + authorizationFlags, NULL); + } + + if (copyRightStatus != errAuthorizationSuccess) { + // Eventually when the commandline supports running as root and the user + // is not + // logged in in the current audit session, we will need the trick in gdb + // where + // we ask the user to type in the root passwd in the terminal. + error.SetError(2, eErrorTypeGeneric); + error.SetErrorStringWithFormat( + "Launching as root needs root authorization."); + if (log) { + error.PutToLog(log, "%s", error.AsCString()); + } + + if (authorizationRef) { + AuthorizationFree(authorizationRef, kAuthorizationFlagDefaults); + authorizationRef = NULL; + } + } + } + + return error; } #endif -static Error -LaunchProcessXPC(const char *exe_path, ProcessLaunchInfo &launch_info, lldb::pid_t &pid) -{ +static Error LaunchProcessXPC(const char *exe_path, + ProcessLaunchInfo &launch_info, + lldb::pid_t &pid) { #if !NO_XPC_SERVICES - Error error = getXPCAuthorization(launch_info); - if (error.Fail()) - return error; - - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS)); - - uid_t requested_uid = launch_info.GetUserID(); - const char *xpc_service = nil; - bool send_auth = false; - AuthorizationExternalForm extForm; - if (requested_uid == 0) - { - if (AuthorizationMakeExternalForm(authorizationRef, &extForm) == errAuthorizationSuccess) - { - send_auth = true; - } - else - { - error.SetError(3, eErrorTypeGeneric); - error.SetErrorStringWithFormat("Launching root via XPC needs to externalize authorization reference."); - if (log) - { - error.PutToLog(log, "%s", error.AsCString()); - } - return error; - } - xpc_service = LaunchUsingXPCRightName; - } - else - { - error.SetError(4, eErrorTypeGeneric); - error.SetErrorStringWithFormat("Launching via XPC is only currently available for root."); - if (log) - { - error.PutToLog(log, "%s", error.AsCString()); - } - return error; - } - - xpc_connection_t conn = xpc_connection_create(xpc_service, NULL); - - xpc_connection_set_event_handler(conn, ^(xpc_object_t event) { - xpc_type_t type = xpc_get_type(event); - - if (type == XPC_TYPE_ERROR) { - if (event == XPC_ERROR_CONNECTION_INTERRUPTED) { - // The service has either canceled itself, crashed, or been terminated. - // The XPC connection is still valid and sending a message to it will re-launch the service. - // If the service is state-full, this is the time to initialize the new service. - return; - } else if (event == XPC_ERROR_CONNECTION_INVALID) { - // The service is invalid. Either the service name supplied to xpc_connection_create() is incorrect - // or we (this process) have canceled the service; we can do any cleanup of application state at this point. - // printf("Service disconnected"); - return; - } else { - // printf("Unexpected error from service: %s", xpc_dictionary_get_string(event, XPC_ERROR_KEY_DESCRIPTION)); - } - - } else { - // printf("Received unexpected event in handler"); - } - }); - - xpc_connection_set_finalizer_f (conn, xpc_finalizer_t(xpc_release)); - xpc_connection_resume (conn); - xpc_object_t message = xpc_dictionary_create (nil, nil, 0); - - if (send_auth) - { - xpc_dictionary_set_data(message, LauncherXPCServiceAuthKey, extForm.bytes, sizeof(AuthorizationExternalForm)); - } - - PackageXPCArguments(message, LauncherXPCServiceArgPrefxKey, launch_info.GetArguments()); - PackageXPCArguments(message, LauncherXPCServiceEnvPrefxKey, launch_info.GetEnvironmentEntries()); - - // Posix spawn stuff. - xpc_dictionary_set_int64(message, LauncherXPCServiceCPUTypeKey, launch_info.GetArchitecture().GetMachOCPUType()); - xpc_dictionary_set_int64(message, LauncherXPCServicePosixspawnFlagsKey, Host::GetPosixspawnFlags(launch_info)); - const FileAction *file_action = launch_info.GetFileActionForFD(STDIN_FILENO); - if (file_action && file_action->GetPath()) - { - xpc_dictionary_set_string(message, LauncherXPCServiceStdInPathKeyKey, file_action->GetPath()); + Error error = getXPCAuthorization(launch_info); + if (error.Fail()) + return error; + + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST | + LIBLLDB_LOG_PROCESS)); + + uid_t requested_uid = launch_info.GetUserID(); + const char *xpc_service = nil; + bool send_auth = false; + AuthorizationExternalForm extForm; + if (requested_uid == 0) { + if (AuthorizationMakeExternalForm(authorizationRef, &extForm) == + errAuthorizationSuccess) { + send_auth = true; + } else { + error.SetError(3, eErrorTypeGeneric); + error.SetErrorStringWithFormat("Launching root via XPC needs to " + "externalize authorization reference."); + if (log) { + error.PutToLog(log, "%s", error.AsCString()); + } + return error; } - file_action = launch_info.GetFileActionForFD(STDOUT_FILENO); - if (file_action && file_action->GetPath()) - { - xpc_dictionary_set_string(message, LauncherXPCServiceStdOutPathKeyKey, file_action->GetPath()); + xpc_service = LaunchUsingXPCRightName; + } else { + error.SetError(4, eErrorTypeGeneric); + error.SetErrorStringWithFormat( + "Launching via XPC is only currently available for root."); + if (log) { + error.PutToLog(log, "%s", error.AsCString()); } - file_action = launch_info.GetFileActionForFD(STDERR_FILENO); - if (file_action && file_action->GetPath()) - { - xpc_dictionary_set_string(message, LauncherXPCServiceStdErrPathKeyKey, file_action->GetPath()); + return error; + } + + xpc_connection_t conn = xpc_connection_create(xpc_service, NULL); + + xpc_connection_set_event_handler(conn, ^(xpc_object_t event) { + xpc_type_t type = xpc_get_type(event); + + if (type == XPC_TYPE_ERROR) { + if (event == XPC_ERROR_CONNECTION_INTERRUPTED) { + // The service has either canceled itself, crashed, or been terminated. + // The XPC connection is still valid and sending a message to it will + // re-launch the service. + // If the service is state-full, this is the time to initialize the new + // service. + return; + } else if (event == XPC_ERROR_CONNECTION_INVALID) { + // The service is invalid. Either the service name supplied to + // xpc_connection_create() is incorrect + // or we (this process) have canceled the service; we can do any cleanup + // of application state at this point. + // printf("Service disconnected"); + return; + } else { + // printf("Unexpected error from service: %s", + // xpc_dictionary_get_string(event, XPC_ERROR_KEY_DESCRIPTION)); + } + + } else { + // printf("Received unexpected event in handler"); } - - xpc_object_t reply = xpc_connection_send_message_with_reply_sync(conn, message); - xpc_type_t returnType = xpc_get_type(reply); - if (returnType == XPC_TYPE_DICTIONARY) - { - pid = xpc_dictionary_get_int64(reply, LauncherXPCServiceChildPIDKey); - if (pid == 0) - { - int errorType = xpc_dictionary_get_int64(reply, LauncherXPCServiceErrorTypeKey); - int errorCode = xpc_dictionary_get_int64(reply, LauncherXPCServiceCodeTypeKey); - - error.SetError(errorCode, eErrorTypeGeneric); - error.SetErrorStringWithFormat("Problems with launching via XPC. Error type : %i, code : %i", errorType, errorCode); - if (log) - { - error.PutToLog(log, "%s", error.AsCString()); - } - - if (authorizationRef) - { - AuthorizationFree(authorizationRef, kAuthorizationFlagDefaults); - authorizationRef = NULL; - } - } + }); + + xpc_connection_set_finalizer_f(conn, xpc_finalizer_t(xpc_release)); + xpc_connection_resume(conn); + xpc_object_t message = xpc_dictionary_create(nil, nil, 0); + + if (send_auth) { + xpc_dictionary_set_data(message, LauncherXPCServiceAuthKey, extForm.bytes, + sizeof(AuthorizationExternalForm)); + } + + PackageXPCArguments(message, LauncherXPCServiceArgPrefxKey, + launch_info.GetArguments()); + PackageXPCArguments(message, LauncherXPCServiceEnvPrefxKey, + launch_info.GetEnvironmentEntries()); + + // Posix spawn stuff. + xpc_dictionary_set_int64(message, LauncherXPCServiceCPUTypeKey, + launch_info.GetArchitecture().GetMachOCPUType()); + xpc_dictionary_set_int64(message, LauncherXPCServicePosixspawnFlagsKey, + Host::GetPosixspawnFlags(launch_info)); + const FileAction *file_action = launch_info.GetFileActionForFD(STDIN_FILENO); + if (file_action && file_action->GetPath()) { + xpc_dictionary_set_string(message, LauncherXPCServiceStdInPathKeyKey, + file_action->GetPath()); + } + file_action = launch_info.GetFileActionForFD(STDOUT_FILENO); + if (file_action && file_action->GetPath()) { + xpc_dictionary_set_string(message, LauncherXPCServiceStdOutPathKeyKey, + file_action->GetPath()); + } + file_action = launch_info.GetFileActionForFD(STDERR_FILENO); + if (file_action && file_action->GetPath()) { + xpc_dictionary_set_string(message, LauncherXPCServiceStdErrPathKeyKey, + file_action->GetPath()); + } + + xpc_object_t reply = + xpc_connection_send_message_with_reply_sync(conn, message); + xpc_type_t returnType = xpc_get_type(reply); + if (returnType == XPC_TYPE_DICTIONARY) { + pid = xpc_dictionary_get_int64(reply, LauncherXPCServiceChildPIDKey); + if (pid == 0) { + int errorType = + xpc_dictionary_get_int64(reply, LauncherXPCServiceErrorTypeKey); + int errorCode = + xpc_dictionary_get_int64(reply, LauncherXPCServiceCodeTypeKey); + + error.SetError(errorCode, eErrorTypeGeneric); + error.SetErrorStringWithFormat( + "Problems with launching via XPC. Error type : %i, code : %i", + errorType, errorCode); + if (log) { + error.PutToLog(log, "%s", error.AsCString()); + } + + if (authorizationRef) { + AuthorizationFree(authorizationRef, kAuthorizationFlagDefaults); + authorizationRef = NULL; + } } - else if (returnType == XPC_TYPE_ERROR) - { - error.SetError(5, eErrorTypeGeneric); - error.SetErrorStringWithFormat("Problems with launching via XPC. XPC error : %s", xpc_dictionary_get_string(reply, XPC_ERROR_KEY_DESCRIPTION)); - if (log) - { - error.PutToLog(log, "%s", error.AsCString()); - } + } else if (returnType == XPC_TYPE_ERROR) { + error.SetError(5, eErrorTypeGeneric); + error.SetErrorStringWithFormat( + "Problems with launching via XPC. XPC error : %s", + xpc_dictionary_get_string(reply, XPC_ERROR_KEY_DESCRIPTION)); + if (log) { + error.PutToLog(log, "%s", error.AsCString()); } - - return error; + } + + return error; #else - Error error; - return error; + Error error; + return error; #endif } -static bool -ShouldLaunchUsingXPC(ProcessLaunchInfo &launch_info) -{ - bool result = false; - -#if !NO_XPC_SERVICES - bool launchingAsRoot = launch_info.GetUserID() == 0; - bool currentUserIsRoot = HostInfo::GetEffectiveUserID() == 0; - - if (launchingAsRoot && !currentUserIsRoot) - { - // If current user is already root, we don't need XPC's help. - result = true; - } +static bool ShouldLaunchUsingXPC(ProcessLaunchInfo &launch_info) { + bool result = false; + +#if !NO_XPC_SERVICES + bool launchingAsRoot = launch_info.GetUserID() == 0; + bool currentUserIsRoot = HostInfo::GetEffectiveUserID() == 0; + + if (launchingAsRoot && !currentUserIsRoot) { + // If current user is already root, we don't need XPC's help. + result = true; + } #endif - - return result; + + return result; } -Error -Host::LaunchProcess (ProcessLaunchInfo &launch_info) -{ - Error error; - char exe_path[PATH_MAX]; - PlatformSP host_platform_sp (Platform::GetHostPlatform ()); - - ModuleSpec exe_module_spec(launch_info.GetExecutableFile(), launch_info.GetArchitecture()); - - FileSpec::FileType file_type = exe_module_spec.GetFileSpec().GetFileType(); - if (file_type != FileSpec::eFileTypeRegular) - { - lldb::ModuleSP exe_module_sp; - error = host_platform_sp->ResolveExecutable (exe_module_spec, - exe_module_sp, - NULL); - - if (error.Fail()) - return error; - - if (exe_module_sp) - exe_module_spec.GetFileSpec() = exe_module_sp->GetFileSpec(); +Error Host::LaunchProcess(ProcessLaunchInfo &launch_info) { + Error error; + char exe_path[PATH_MAX]; + PlatformSP host_platform_sp(Platform::GetHostPlatform()); + + ModuleSpec exe_module_spec(launch_info.GetExecutableFile(), + launch_info.GetArchitecture()); + + FileSpec::FileType file_type = exe_module_spec.GetFileSpec().GetFileType(); + if (file_type != FileSpec::eFileTypeRegular) { + lldb::ModuleSP exe_module_sp; + error = host_platform_sp->ResolveExecutable(exe_module_spec, exe_module_sp, + NULL); + + if (error.Fail()) + return error; + + if (exe_module_sp) + exe_module_spec.GetFileSpec() = exe_module_sp->GetFileSpec(); + } + + if (exe_module_spec.GetFileSpec().Exists()) { + exe_module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path)); + } else { + launch_info.GetExecutableFile().GetPath(exe_path, sizeof(exe_path)); + error.SetErrorStringWithFormat("executable doesn't exist: '%s'", exe_path); + return error; + } + + if (launch_info.GetFlags().Test(eLaunchFlagLaunchInTTY)) { +#if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) + return LaunchInNewTerminalWithAppleScript(exe_path, launch_info); +#else + error.SetErrorString("launching a process in a new terminal is not " + "supported on iOS devices"); + return error; +#endif + } + + lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; + + if (ShouldLaunchUsingXPC(launch_info)) { + error = LaunchProcessXPC(exe_path, launch_info, pid); + } else { + error = LaunchProcessPosixSpawn(exe_path, launch_info, pid); + } + + if (pid != LLDB_INVALID_PROCESS_ID) { + // If all went well, then set the process ID into the launch info + launch_info.SetProcessID(pid); + + // Make sure we reap any processes we spawn or we will have zombies. + if (!launch_info.MonitorProcess()) { + const bool monitor_signals = false; + Host::MonitorChildProcessCallback callback = nullptr; + + if (!launch_info.GetFlags().Test(lldb::eLaunchFlagDontSetExitStatus)) + callback = Process::SetProcessExitStatus; + + StartMonitoringChildProcess(callback, pid, monitor_signals); } - - if (exe_module_spec.GetFileSpec().Exists()) - { - exe_module_spec.GetFileSpec().GetPath (exe_path, sizeof(exe_path)); + } else { + // Invalid process ID, something didn't go well + if (error.Success()) + error.SetErrorString("process launch failed for unknown reasons"); + } + return error; +} + +Error Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) { + Error error; + if (launch_info.GetFlags().Test(eLaunchFlagShellExpandArguments)) { + FileSpec expand_tool_spec; + if (!HostInfo::GetLLDBPath(lldb::ePathTypeSupportExecutableDir, + expand_tool_spec)) { + error.SetErrorString( + "could not get support executable directory for lldb-argdumper tool"); + return error; } - else - { - launch_info.GetExecutableFile().GetPath (exe_path, sizeof(exe_path)); - error.SetErrorStringWithFormat ("executable doesn't exist: '%s'", exe_path); - return error; + expand_tool_spec.AppendPathComponent("lldb-argdumper"); + if (!expand_tool_spec.Exists()) { + error.SetErrorStringWithFormat( + "could not find the lldb-argdumper tool: %s", + expand_tool_spec.GetPath().c_str()); + return error; } - - if (launch_info.GetFlags().Test (eLaunchFlagLaunchInTTY)) - { -#if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) - return LaunchInNewTerminalWithAppleScript (exe_path, launch_info); -#else - error.SetErrorString ("launching a process in a new terminal is not supported on iOS devices"); + + StreamString expand_tool_spec_stream; + expand_tool_spec_stream.Printf("\"%s\"", + expand_tool_spec.GetPath().c_str()); + + Args expand_command(expand_tool_spec_stream.GetData()); + expand_command.AppendArguments(launch_info.GetArguments()); + + int status; + std::string output; + FileSpec cwd(launch_info.GetWorkingDirectory()); + if (!cwd.Exists()) { + char *wd = getcwd(nullptr, 0); + if (wd == nullptr) { + error.SetErrorStringWithFormat( + "cwd does not exist; cannot launch with shell argument expansion"); return error; -#endif + } else { + FileSpec working_dir(wd, false); + free(wd); + launch_info.SetWorkingDirectory(working_dir); + } } + RunShellCommand(expand_command, cwd, &status, nullptr, &output, 10); - lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; + if (status != 0) { + error.SetErrorStringWithFormat("lldb-argdumper exited with error %d", + status); + return error; + } - if (ShouldLaunchUsingXPC(launch_info)) - { - error = LaunchProcessXPC(exe_path, launch_info, pid); + auto data_sp = StructuredData::ParseJSON(output); + if (!data_sp) { + error.SetErrorString("invalid JSON"); + return error; } - else - { - error = LaunchProcessPosixSpawn(exe_path, launch_info, pid); + + auto dict_sp = data_sp->GetAsDictionary(); + if (!data_sp) { + error.SetErrorString("invalid JSON"); + return error; } - - if (pid != LLDB_INVALID_PROCESS_ID) - { - // If all went well, then set the process ID into the launch info - launch_info.SetProcessID(pid); - - // Make sure we reap any processes we spawn or we will have zombies. - if (!launch_info.MonitorProcess()) - { - const bool monitor_signals = false; - Host::MonitorChildProcessCallback callback = nullptr; - - if (!launch_info.GetFlags().Test(lldb::eLaunchFlagDontSetExitStatus)) - callback = Process::SetProcessExitStatus; - - StartMonitoringChildProcess (callback, - pid, - monitor_signals); - } + + auto args_sp = dict_sp->GetObjectForDotSeparatedPath("arguments"); + if (!args_sp) { + error.SetErrorString("invalid JSON"); + return error; } - else - { - // Invalid process ID, something didn't go well - if (error.Success()) - error.SetErrorString ("process launch failed for unknown reasons"); + + auto args_array_sp = args_sp->GetAsArray(); + if (!args_array_sp) { + error.SetErrorString("invalid JSON"); + return error; } - return error; -} -Error -Host::ShellExpandArguments (ProcessLaunchInfo &launch_info) -{ - Error error; - if (launch_info.GetFlags().Test(eLaunchFlagShellExpandArguments)) - { - FileSpec expand_tool_spec; - if (!HostInfo::GetLLDBPath(lldb::ePathTypeSupportExecutableDir, expand_tool_spec)) - { - error.SetErrorString("could not get support executable directory for lldb-argdumper tool"); - return error; - } - expand_tool_spec.AppendPathComponent("lldb-argdumper"); - if (!expand_tool_spec.Exists()) - { - error.SetErrorStringWithFormat("could not find the lldb-argdumper tool: %s", expand_tool_spec.GetPath().c_str()); - return error; - } - - StreamString expand_tool_spec_stream; - expand_tool_spec_stream.Printf("\"%s\"",expand_tool_spec.GetPath().c_str()); - - Args expand_command(expand_tool_spec_stream.GetData()); - expand_command.AppendArguments (launch_info.GetArguments()); - - int status; - std::string output; - FileSpec cwd(launch_info.GetWorkingDirectory()); - if (!cwd.Exists()) - { - char *wd = getcwd(nullptr, 0); - if (wd == nullptr) - { - error.SetErrorStringWithFormat("cwd does not exist; cannot launch with shell argument expansion"); - return error; - } - else - { - FileSpec working_dir(wd, false); - free(wd); - launch_info.SetWorkingDirectory(working_dir); + launch_info.GetArguments().Clear(); - } - } - RunShellCommand(expand_command, cwd, &status, nullptr, &output, 10); - - if (status != 0) - { - error.SetErrorStringWithFormat("lldb-argdumper exited with error %d", status); - return error; - } - - auto data_sp = StructuredData::ParseJSON(output); - if (!data_sp) - { - error.SetErrorString("invalid JSON"); - return error; - } - - auto dict_sp = data_sp->GetAsDictionary(); - if (!data_sp) - { - error.SetErrorString("invalid JSON"); - return error; - } - - auto args_sp = dict_sp->GetObjectForDotSeparatedPath("arguments"); - if (!args_sp) - { - error.SetErrorString("invalid JSON"); - return error; - } + for (size_t i = 0; i < args_array_sp->GetSize(); i++) { + auto item_sp = args_array_sp->GetItemAtIndex(i); + if (!item_sp) + continue; + auto str_sp = item_sp->GetAsString(); + if (!str_sp) + continue; - auto args_array_sp = args_sp->GetAsArray(); - if (!args_array_sp) - { - error.SetErrorString("invalid JSON"); - return error; - } - - launch_info.GetArguments().Clear(); - - for (size_t i = 0; - i < args_array_sp->GetSize(); - i++) - { - auto item_sp = args_array_sp->GetItemAtIndex(i); - if (!item_sp) - continue; - auto str_sp = item_sp->GetAsString(); - if (!str_sp) - continue; - - launch_info.GetArguments().AppendArgument(str_sp->GetValue().c_str()); - } + launch_info.GetArguments().AppendArgument(str_sp->GetValue().c_str()); } - - return error; -} + } -HostThread -Host::StartMonitoringChildProcess(const Host::MonitorChildProcessCallback &callback, lldb::pid_t pid, - bool monitor_signals) -{ - unsigned long mask = DISPATCH_PROC_EXIT; - if (monitor_signals) - mask |= DISPATCH_PROC_SIGNAL; + return error; +} - Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS)); +HostThread Host::StartMonitoringChildProcess( + const Host::MonitorChildProcessCallback &callback, lldb::pid_t pid, + bool monitor_signals) { + unsigned long mask = DISPATCH_PROC_EXIT; + if (monitor_signals) + mask |= DISPATCH_PROC_SIGNAL; + + Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_HOST | + LIBLLDB_LOG_PROCESS)); + + dispatch_source_t source = ::dispatch_source_create( + DISPATCH_SOURCE_TYPE_PROC, pid, mask, + ::dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)); + + if (log) + log->Printf("Host::StartMonitoringChildProcess " + "(callback, pid=%i, monitor_signals=%i) " + "source = %p\n", + static_cast<int>(pid), monitor_signals, + reinterpret_cast<void *>(source)); + + if (source) { + Host::MonitorChildProcessCallback callback_copy = callback; + ::dispatch_source_set_cancel_handler(source, ^{ + ::dispatch_release(source); + }); + ::dispatch_source_set_event_handler(source, ^{ + + int status = 0; + int wait_pid = 0; + bool cancel = false; + bool exited = false; + do { + wait_pid = ::waitpid(pid, &status, 0); + } while (wait_pid < 0 && errno == EINTR); + + if (wait_pid >= 0) { + int signal = 0; + int exit_status = 0; + const char *status_cstr = NULL; + if (WIFSTOPPED(status)) { + signal = WSTOPSIG(status); + status_cstr = "STOPPED"; + } else if (WIFEXITED(status)) { + exit_status = WEXITSTATUS(status); + status_cstr = "EXITED"; + exited = true; + } else if (WIFSIGNALED(status)) { + signal = WTERMSIG(status); + status_cstr = "SIGNALED"; + exited = true; + exit_status = -1; + } else { + status_cstr = "???"; + } + if (log) + log->Printf("::waitpid (pid = %llu, &status, 0) => pid = %i, status " + "= 0x%8.8x (%s), signal = %i, exit_status = %i", + pid, wait_pid, status, status_cstr, signal, exit_status); - dispatch_source_t source = ::dispatch_source_create (DISPATCH_SOURCE_TYPE_PROC, - pid, - mask, - ::dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT,0)); + if (callback_copy) + cancel = callback_copy(pid, exited, signal, exit_status); - if (log) - log->Printf("Host::StartMonitoringChildProcess " - "(callback, pid=%i, monitor_signals=%i) " - "source = %p\n", - static_cast<int>(pid), monitor_signals, reinterpret_cast<void *>(source)); - - if (source) - { - Host::MonitorChildProcessCallback callback_copy = callback; - ::dispatch_source_set_cancel_handler (source, ^{ - ::dispatch_release (source); - }); - ::dispatch_source_set_event_handler (source, ^{ - - int status= 0; - int wait_pid = 0; - bool cancel = false; - bool exited = false; - do - { - wait_pid = ::waitpid (pid, &status, 0); - } while (wait_pid < 0 && errno == EINTR); - - if (wait_pid >= 0) - { - int signal = 0; - int exit_status = 0; - const char *status_cstr = NULL; - if (WIFSTOPPED(status)) - { - signal = WSTOPSIG(status); - status_cstr = "STOPPED"; - } - else if (WIFEXITED(status)) - { - exit_status = WEXITSTATUS(status); - status_cstr = "EXITED"; - exited = true; - } - else if (WIFSIGNALED(status)) - { - signal = WTERMSIG(status); - status_cstr = "SIGNALED"; - exited = true; - exit_status = -1; - } - else - { - status_cstr = "???"; - } - - if (log) - log->Printf ("::waitpid (pid = %llu, &status, 0) => pid = %i, status = 0x%8.8x (%s), signal = %i, exit_status = %i", - pid, - wait_pid, - status, - status_cstr, - signal, - exit_status); - - if (callback_copy) - cancel = callback_copy(pid, exited, signal, exit_status); - - if (exited || cancel) - { - ::dispatch_source_cancel(source); - } - } - }); + if (exited || cancel) { + ::dispatch_source_cancel(source); + } + } + }); - ::dispatch_resume (source); - } - return HostThread(); + ::dispatch_resume(source); + } + return HostThread(); } //---------------------------------------------------------------------- // Log to both stderr and to ASL Logging when running on MacOSX. //---------------------------------------------------------------------- -void -Host::SystemLog (SystemLogType type, const char *format, va_list args) -{ - if (format && format[0]) - { - static aslmsg g_aslmsg = NULL; - if (g_aslmsg == NULL) - { - g_aslmsg = ::asl_new (ASL_TYPE_MSG); - char asl_key_sender[PATH_MAX]; - snprintf(asl_key_sender, sizeof(asl_key_sender), "com.apple.LLDB.framework"); - ::asl_set (g_aslmsg, ASL_KEY_SENDER, asl_key_sender); - } - - // Copy the va_list so we can log this message twice - va_list copy_args; - va_copy (copy_args, args); - // Log to stderr - ::vfprintf (stderr, format, copy_args); - va_end (copy_args); - - int asl_level; - switch (type) - { - case eSystemLogError: - asl_level = ASL_LEVEL_ERR; - break; - - case eSystemLogWarning: - asl_level = ASL_LEVEL_WARNING; - break; - } - - // Log to ASL - ::asl_vlog (NULL, g_aslmsg, asl_level, format, args); +void Host::SystemLog(SystemLogType type, const char *format, va_list args) { + if (format && format[0]) { + static aslmsg g_aslmsg = NULL; + if (g_aslmsg == NULL) { + g_aslmsg = ::asl_new(ASL_TYPE_MSG); + char asl_key_sender[PATH_MAX]; + snprintf(asl_key_sender, sizeof(asl_key_sender), + "com.apple.LLDB.framework"); + ::asl_set(g_aslmsg, ASL_KEY_SENDER, asl_key_sender); } + + // Copy the va_list so we can log this message twice + va_list copy_args; + va_copy(copy_args, args); + // Log to stderr + ::vfprintf(stderr, format, copy_args); + va_end(copy_args); + + int asl_level; + switch (type) { + case eSystemLogError: + asl_level = ASL_LEVEL_ERR; + break; + + case eSystemLogWarning: + asl_level = ASL_LEVEL_WARNING; + break; + } + + // Log to ASL + ::asl_vlog(NULL, g_aslmsg, asl_level, format, args); + } } -lldb::DataBufferSP -Host::GetAuxvData(lldb_private::Process *process) -{ - return lldb::DataBufferSP(); +lldb::DataBufferSP Host::GetAuxvData(lldb_private::Process *process) { + return lldb::DataBufferSP(); } diff --git a/lldb/source/Host/macosx/HostInfoMacOSX.mm b/lldb/source/Host/macosx/HostInfoMacOSX.mm index 8b664f0a44b..b79332dd02f 100644 --- a/lldb/source/Host/macosx/HostInfoMacOSX.mm +++ b/lldb/source/Host/macosx/HostInfoMacOSX.mm @@ -11,9 +11,9 @@ #include "Plugins/ScriptInterpreter/Python/lldb-python.h" #endif +#include "lldb/Core/Log.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/macosx/HostInfoMacOSX.h" -#include "lldb/Core/Log.h" #include "lldb/Interpreter/Args.h" #include "lldb/Utility/SafeMachO.h" @@ -42,337 +42,294 @@ #define CPU_SUBTYPE_X86_64_H ((cpu_subtype_t)8) #endif #ifndef CPU_TYPE_ARM64 -#define CPU_TYPE_ARM64 (CPU_TYPE_ARM|CPU_ARCH_ABI64) +#define CPU_TYPE_ARM64 (CPU_TYPE_ARM | CPU_ARCH_ABI64) #endif #include <TargetConditionals.h> // for TARGET_OS_TV, TARGET_OS_WATCH using namespace lldb_private; -bool -HostInfoMacOSX::GetOSBuildString(std::string &s) -{ - int mib[2] = {CTL_KERN, KERN_OSVERSION}; - char cstr[PATH_MAX]; - size_t cstr_len = sizeof(cstr); - if (::sysctl(mib, 2, cstr, &cstr_len, NULL, 0) == 0) - { - s.assign(cstr, cstr_len); - return true; - } +bool HostInfoMacOSX::GetOSBuildString(std::string &s) { + int mib[2] = {CTL_KERN, KERN_OSVERSION}; + char cstr[PATH_MAX]; + size_t cstr_len = sizeof(cstr); + if (::sysctl(mib, 2, cstr, &cstr_len, NULL, 0) == 0) { + s.assign(cstr, cstr_len); + return true; + } - s.clear(); - return false; + s.clear(); + return false; } -bool -HostInfoMacOSX::GetOSKernelDescription(std::string &s) -{ - int mib[2] = {CTL_KERN, KERN_VERSION}; - char cstr[PATH_MAX]; - size_t cstr_len = sizeof(cstr); - if (::sysctl(mib, 2, cstr, &cstr_len, NULL, 0) == 0) - { - s.assign(cstr, cstr_len); - return true; - } - s.clear(); - return false; +bool HostInfoMacOSX::GetOSKernelDescription(std::string &s) { + int mib[2] = {CTL_KERN, KERN_VERSION}; + char cstr[PATH_MAX]; + size_t cstr_len = sizeof(cstr); + if (::sysctl(mib, 2, cstr, &cstr_len, NULL, 0) == 0) { + s.assign(cstr, cstr_len); + return true; + } + s.clear(); + return false; } -bool -HostInfoMacOSX::GetOSVersion(uint32_t &major, uint32_t &minor, uint32_t &update) -{ - static uint32_t g_major = 0; - static uint32_t g_minor = 0; - static uint32_t g_update = 0; - - if (g_major == 0) - { - @autoreleasepool - { - NSDictionary *version_info = [NSDictionary dictionaryWithContentsOfFile:@"/System/Library/CoreServices/SystemVersion.plist"]; - NSString *version_value = [version_info objectForKey:@"ProductVersion"]; - const char *version_str = [version_value UTF8String]; - if (version_str) - Args::StringToVersion(version_str, g_major, g_minor, g_update); - } +bool HostInfoMacOSX::GetOSVersion(uint32_t &major, uint32_t &minor, + uint32_t &update) { + static uint32_t g_major = 0; + static uint32_t g_minor = 0; + static uint32_t g_update = 0; + + if (g_major == 0) { + @autoreleasepool { + NSDictionary *version_info = [NSDictionary + dictionaryWithContentsOfFile: + @"/System/Library/CoreServices/SystemVersion.plist"]; + NSString *version_value = [version_info objectForKey:@"ProductVersion"]; + const char *version_str = [version_value UTF8String]; + if (version_str) + Args::StringToVersion(version_str, g_major, g_minor, g_update); } + } - if (g_major != 0) - { - major = g_major; - minor = g_minor; - update = g_update; - return true; - } - return false; + if (g_major != 0) { + major = g_major; + minor = g_minor; + update = g_update; + return true; + } + return false; } -FileSpec -HostInfoMacOSX::GetProgramFileSpec() -{ - static FileSpec g_program_filespec; - if (!g_program_filespec) - { - char program_fullpath[PATH_MAX]; - // If DST is NULL, then return the number of bytes needed. - uint32_t len = sizeof(program_fullpath); - int err = _NSGetExecutablePath(program_fullpath, &len); - if (err == 0) - g_program_filespec.SetFile(program_fullpath, false); - else if (err == -1) - { - char *large_program_fullpath = (char *)::malloc(len + 1); - - err = _NSGetExecutablePath(large_program_fullpath, &len); - if (err == 0) - g_program_filespec.SetFile(large_program_fullpath, false); - - ::free(large_program_fullpath); - } +FileSpec HostInfoMacOSX::GetProgramFileSpec() { + static FileSpec g_program_filespec; + if (!g_program_filespec) { + char program_fullpath[PATH_MAX]; + // If DST is NULL, then return the number of bytes needed. + uint32_t len = sizeof(program_fullpath); + int err = _NSGetExecutablePath(program_fullpath, &len); + if (err == 0) + g_program_filespec.SetFile(program_fullpath, false); + else if (err == -1) { + char *large_program_fullpath = (char *)::malloc(len + 1); + + err = _NSGetExecutablePath(large_program_fullpath, &len); + if (err == 0) + g_program_filespec.SetFile(large_program_fullpath, false); + + ::free(large_program_fullpath); } - return g_program_filespec; + } + return g_program_filespec; } -bool -HostInfoMacOSX::ComputeSupportExeDirectory(FileSpec &file_spec) -{ - FileSpec lldb_file_spec; - if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec)) - return false; +bool HostInfoMacOSX::ComputeSupportExeDirectory(FileSpec &file_spec) { + FileSpec lldb_file_spec; + if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec)) + return false; - std::string raw_path = lldb_file_spec.GetPath(); + std::string raw_path = lldb_file_spec.GetPath(); - size_t framework_pos = raw_path.find("LLDB.framework"); - if (framework_pos != std::string::npos) - { - framework_pos += strlen("LLDB.framework"); + size_t framework_pos = raw_path.find("LLDB.framework"); + if (framework_pos != std::string::npos) { + framework_pos += strlen("LLDB.framework"); #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) - // Shallow bundle - raw_path.resize(framework_pos); + // Shallow bundle + raw_path.resize(framework_pos); #else - // Normal bundle - raw_path.resize(framework_pos); - raw_path.append("/Resources"); + // Normal bundle + raw_path.resize(framework_pos); + raw_path.append("/Resources"); #endif + } else { + // Find the bin path relative to the lib path where the cmake-based + // OS X .dylib lives. This is not going to work if the bin and lib + // dir are not both in the same dir. + // + // It is not going to work to do it by the executable path either, + // as in the case of a python script, the executable is python, not + // the lldb driver. + raw_path.append("/../bin"); + FileSpec support_dir_spec(raw_path, true); + if (!support_dir_spec.Exists() || !support_dir_spec.IsDirectory()) { + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + if (log) + log->Printf("HostInfoMacOSX::%s(): failed to find support directory", + __FUNCTION__); + return false; } - else - { - // Find the bin path relative to the lib path where the cmake-based - // OS X .dylib lives. This is not going to work if the bin and lib - // dir are not both in the same dir. - // - // It is not going to work to do it by the executable path either, - // as in the case of a python script, the executable is python, not - // the lldb driver. - raw_path.append("/../bin"); - FileSpec support_dir_spec(raw_path, true); - if (!support_dir_spec.Exists() || !support_dir_spec.IsDirectory()) - { - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); - if (log) - log->Printf("HostInfoMacOSX::%s(): failed to find support directory", - __FUNCTION__); - return false; - } - - // Get normalization from support_dir_spec. Note the FileSpec resolve - // does not remove '..' in the path. - char *const dir_realpath = realpath(support_dir_spec.GetPath().c_str(), NULL); - if (dir_realpath) - { - raw_path = dir_realpath; - free(dir_realpath); - } - else - { - raw_path = support_dir_spec.GetPath(); - } + + // Get normalization from support_dir_spec. Note the FileSpec resolve + // does not remove '..' in the path. + char *const dir_realpath = + realpath(support_dir_spec.GetPath().c_str(), NULL); + if (dir_realpath) { + raw_path = dir_realpath; + free(dir_realpath); + } else { + raw_path = support_dir_spec.GetPath(); } + } - file_spec.GetDirectory().SetString(llvm::StringRef(raw_path.c_str(), raw_path.size())); - return (bool)file_spec.GetDirectory(); + file_spec.GetDirectory().SetString( + llvm::StringRef(raw_path.c_str(), raw_path.size())); + return (bool)file_spec.GetDirectory(); } -bool -HostInfoMacOSX::ComputeHeaderDirectory(FileSpec &file_spec) -{ - FileSpec lldb_file_spec; - if (!HostInfo::GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec)) - return false; - - std::string raw_path = lldb_file_spec.GetPath(); - - size_t framework_pos = raw_path.find("LLDB.framework"); - if (framework_pos != std::string::npos) - { - framework_pos += strlen("LLDB.framework"); - raw_path.resize(framework_pos); - raw_path.append("/Headers"); - } - file_spec.GetDirectory().SetString(llvm::StringRef(raw_path.c_str(), raw_path.size())); - return true; +bool HostInfoMacOSX::ComputeHeaderDirectory(FileSpec &file_spec) { + FileSpec lldb_file_spec; + if (!HostInfo::GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec)) + return false; + + std::string raw_path = lldb_file_spec.GetPath(); + + size_t framework_pos = raw_path.find("LLDB.framework"); + if (framework_pos != std::string::npos) { + framework_pos += strlen("LLDB.framework"); + raw_path.resize(framework_pos); + raw_path.append("/Headers"); + } + file_spec.GetDirectory().SetString( + llvm::StringRef(raw_path.c_str(), raw_path.size())); + return true; } -bool -HostInfoMacOSX::ComputePythonDirectory(FileSpec &file_spec) -{ +bool HostInfoMacOSX::ComputePythonDirectory(FileSpec &file_spec) { #ifndef LLDB_DISABLE_PYTHON - FileSpec lldb_file_spec; - if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec)) - return false; - - std::string raw_path = lldb_file_spec.GetPath(); - - size_t framework_pos = raw_path.find("LLDB.framework"); - if (framework_pos != std::string::npos) - { - framework_pos += strlen("LLDB.framework"); - raw_path.resize(framework_pos); - raw_path.append("/Resources/Python"); - } - else - { - llvm::SmallString<256> python_version_dir; - llvm::raw_svector_ostream os(python_version_dir); - os << "/python" << PY_MAJOR_VERSION << '.' << PY_MINOR_VERSION << "/site-packages"; - - // We may get our string truncated. Should we protect this with an assert? - raw_path.append(python_version_dir.c_str()); - } - file_spec.GetDirectory().SetString(llvm::StringRef(raw_path.c_str(), raw_path.size())); - return true; -#else + FileSpec lldb_file_spec; + if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec)) return false; + + std::string raw_path = lldb_file_spec.GetPath(); + + size_t framework_pos = raw_path.find("LLDB.framework"); + if (framework_pos != std::string::npos) { + framework_pos += strlen("LLDB.framework"); + raw_path.resize(framework_pos); + raw_path.append("/Resources/Python"); + } else { + llvm::SmallString<256> python_version_dir; + llvm::raw_svector_ostream os(python_version_dir); + os << "/python" << PY_MAJOR_VERSION << '.' << PY_MINOR_VERSION + << "/site-packages"; + + // We may get our string truncated. Should we protect this with an assert? + raw_path.append(python_version_dir.c_str()); + } + file_spec.GetDirectory().SetString( + llvm::StringRef(raw_path.c_str(), raw_path.size())); + return true; +#else + return false; #endif } -bool -HostInfoMacOSX::ComputeClangDirectory(FileSpec &file_spec) -{ - FileSpec lldb_file_spec; - if (!GetLLDBPath (lldb::ePathTypeLLDBShlibDir, lldb_file_spec)) - return false; - - std::string raw_path = lldb_file_spec.GetPath(); - - size_t framework_pos = raw_path.find("LLDB.framework"); - if (framework_pos != std::string::npos) - { - framework_pos += strlen("LLDB.framework"); - raw_path.resize(framework_pos); - raw_path.append("/Resources/Clang"); - } - file_spec.SetFile (raw_path.c_str(), true); - return true; +bool HostInfoMacOSX::ComputeClangDirectory(FileSpec &file_spec) { + FileSpec lldb_file_spec; + if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec)) + return false; + + std::string raw_path = lldb_file_spec.GetPath(); + + size_t framework_pos = raw_path.find("LLDB.framework"); + if (framework_pos != std::string::npos) { + framework_pos += strlen("LLDB.framework"); + raw_path.resize(framework_pos); + raw_path.append("/Resources/Clang"); + } + file_spec.SetFile(raw_path.c_str(), true); + return true; } -bool -HostInfoMacOSX::ComputeSystemPluginsDirectory(FileSpec &file_spec) -{ - FileSpec lldb_file_spec; - if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec)) - return false; +bool HostInfoMacOSX::ComputeSystemPluginsDirectory(FileSpec &file_spec) { + FileSpec lldb_file_spec; + if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec)) + return false; - std::string raw_path = lldb_file_spec.GetPath(); + std::string raw_path = lldb_file_spec.GetPath(); - size_t framework_pos = raw_path.find("LLDB.framework"); - if (framework_pos == std::string::npos) - return false; + size_t framework_pos = raw_path.find("LLDB.framework"); + if (framework_pos == std::string::npos) + return false; - framework_pos += strlen("LLDB.framework"); - raw_path.resize(framework_pos); - raw_path.append("/Resources/PlugIns"); - file_spec.GetDirectory().SetString(llvm::StringRef(raw_path.c_str(), raw_path.size())); - return true; + framework_pos += strlen("LLDB.framework"); + raw_path.resize(framework_pos); + raw_path.append("/Resources/PlugIns"); + file_spec.GetDirectory().SetString( + llvm::StringRef(raw_path.c_str(), raw_path.size())); + return true; } -bool -HostInfoMacOSX::ComputeUserPluginsDirectory(FileSpec &file_spec) -{ - FileSpec temp_file("~/Library/Application Support/LLDB/PlugIns", true); - file_spec.GetDirectory().SetCString(temp_file.GetPath().c_str()); - return true; +bool HostInfoMacOSX::ComputeUserPluginsDirectory(FileSpec &file_spec) { + FileSpec temp_file("~/Library/Application Support/LLDB/PlugIns", true); + file_spec.GetDirectory().SetCString(temp_file.GetPath().c_str()); + return true; } -void -HostInfoMacOSX::ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_64) -{ - // All apple systems support 32 bit execution. - uint32_t cputype, cpusubtype; - uint32_t is_64_bit_capable = false; - size_t len = sizeof(cputype); - ArchSpec host_arch; - // These will tell us about the kernel architecture, which even on a 64 - // bit machine can be 32 bit... - if (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0) - { - len = sizeof(cpusubtype); - if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) != 0) - cpusubtype = CPU_TYPE_ANY; - - len = sizeof(is_64_bit_capable); - ::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0); - - if (is_64_bit_capable) - { - if (cputype & CPU_ARCH_ABI64) - { - // We have a 64 bit kernel on a 64 bit system - arch_64.SetArchitecture(eArchTypeMachO, cputype, cpusubtype); - } - else - { - // We have a 64 bit kernel that is returning a 32 bit cputype, the - // cpusubtype will be correct as if it were for a 64 bit architecture - arch_64.SetArchitecture(eArchTypeMachO, cputype | CPU_ARCH_ABI64, cpusubtype); - } - - // Now we need modify the cpusubtype for the 32 bit slices. - uint32_t cpusubtype32 = cpusubtype; +void HostInfoMacOSX::ComputeHostArchitectureSupport(ArchSpec &arch_32, + ArchSpec &arch_64) { + // All apple systems support 32 bit execution. + uint32_t cputype, cpusubtype; + uint32_t is_64_bit_capable = false; + size_t len = sizeof(cputype); + ArchSpec host_arch; + // These will tell us about the kernel architecture, which even on a 64 + // bit machine can be 32 bit... + if (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0) { + len = sizeof(cpusubtype); + if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) != 0) + cpusubtype = CPU_TYPE_ANY; + + len = sizeof(is_64_bit_capable); + ::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0); + + if (is_64_bit_capable) { + if (cputype & CPU_ARCH_ABI64) { + // We have a 64 bit kernel on a 64 bit system + arch_64.SetArchitecture(eArchTypeMachO, cputype, cpusubtype); + } else { + // We have a 64 bit kernel that is returning a 32 bit cputype, the + // cpusubtype will be correct as if it were for a 64 bit architecture + arch_64.SetArchitecture(eArchTypeMachO, cputype | CPU_ARCH_ABI64, + cpusubtype); + } + + // Now we need modify the cpusubtype for the 32 bit slices. + uint32_t cpusubtype32 = cpusubtype; #if defined(__i386__) || defined(__x86_64__) - if (cpusubtype == CPU_SUBTYPE_486 || cpusubtype == CPU_SUBTYPE_X86_64_H) - cpusubtype32 = CPU_SUBTYPE_I386_ALL; + if (cpusubtype == CPU_SUBTYPE_486 || cpusubtype == CPU_SUBTYPE_X86_64_H) + cpusubtype32 = CPU_SUBTYPE_I386_ALL; #elif defined(__arm__) || defined(__arm64__) || defined(__aarch64__) - if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64) - cpusubtype32 = CPU_SUBTYPE_ARM_V7S; + if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64) + cpusubtype32 = CPU_SUBTYPE_ARM_V7S; #endif - arch_32.SetArchitecture(eArchTypeMachO, cputype & ~(CPU_ARCH_MASK), cpusubtype32); - - if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64) - { - // When running on a watch or tv, report the host os correctly -#if defined (TARGET_OS_TV) && TARGET_OS_TV == 1 - arch_32.GetTriple().setOS(llvm::Triple::TvOS); - arch_64.GetTriple().setOS(llvm::Triple::TvOS); + arch_32.SetArchitecture(eArchTypeMachO, cputype & ~(CPU_ARCH_MASK), + cpusubtype32); + + if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64) { +// When running on a watch or tv, report the host os correctly +#if defined(TARGET_OS_TV) && TARGET_OS_TV == 1 + arch_32.GetTriple().setOS(llvm::Triple::TvOS); + arch_64.GetTriple().setOS(llvm::Triple::TvOS); #else - arch_32.GetTriple().setOS(llvm::Triple::IOS); - arch_64.GetTriple().setOS(llvm::Triple::IOS); + arch_32.GetTriple().setOS(llvm::Triple::IOS); + arch_64.GetTriple().setOS(llvm::Triple::IOS); #endif - } - else - { - arch_32.GetTriple().setOS(llvm::Triple::MacOSX); - arch_64.GetTriple().setOS(llvm::Triple::MacOSX); - } - } - else - { - // We have a 32 bit kernel on a 32 bit system - arch_32.SetArchitecture(eArchTypeMachO, cputype, cpusubtype); -#if defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 - arch_32.GetTriple().setOS(llvm::Triple::WatchOS); + } else { + arch_32.GetTriple().setOS(llvm::Triple::MacOSX); + arch_64.GetTriple().setOS(llvm::Triple::MacOSX); + } + } else { + // We have a 32 bit kernel on a 32 bit system + arch_32.SetArchitecture(eArchTypeMachO, cputype, cpusubtype); +#if defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 + arch_32.GetTriple().setOS(llvm::Triple::WatchOS); #else - arch_32.GetTriple().setOS(llvm::Triple::IOS); + arch_32.GetTriple().setOS(llvm::Triple::IOS); #endif - arch_64.Clear(); - } + arch_64.Clear(); } + } } -uint32_t -HostInfoMacOSX::GetMaxThreadNameLength() -{ - return 64; -} +uint32_t HostInfoMacOSX::GetMaxThreadNameLength() { return 64; } diff --git a/lldb/source/Host/macosx/HostThreadMacOSX.mm b/lldb/source/Host/macosx/HostThreadMacOSX.mm index 6fb498ce49b..c5051cdf30d 100644 --- a/lldb/source/Host/macosx/HostThreadMacOSX.mm +++ b/lldb/source/Host/macosx/HostThreadMacOSX.mm @@ -17,70 +17,54 @@ using namespace lldb_private; -namespace -{ +namespace { pthread_once_t g_thread_create_once = PTHREAD_ONCE_INIT; pthread_key_t g_thread_create_key = 0; -class MacOSXDarwinThread -{ - public: - MacOSXDarwinThread() - : m_pool(nil) - { - m_pool = [[NSAutoreleasePool alloc] init]; - } +class MacOSXDarwinThread { +public: + MacOSXDarwinThread() : m_pool(nil) { + m_pool = [[NSAutoreleasePool alloc] init]; + } - ~MacOSXDarwinThread() - { - if (m_pool) - { - [m_pool drain]; - m_pool = nil; - } + ~MacOSXDarwinThread() { + if (m_pool) { + [m_pool drain]; + m_pool = nil; } + } - static void - PThreadDestructor(void *v) - { - if (v) - delete static_cast<MacOSXDarwinThread *>(v); - ::pthread_setspecific(g_thread_create_key, NULL); - } + static void PThreadDestructor(void *v) { + if (v) + delete static_cast<MacOSXDarwinThread *>(v); + ::pthread_setspecific(g_thread_create_key, NULL); + } - protected: - NSAutoreleasePool *m_pool; +protected: + NSAutoreleasePool *m_pool; - private: - DISALLOW_COPY_AND_ASSIGN(MacOSXDarwinThread); +private: + DISALLOW_COPY_AND_ASSIGN(MacOSXDarwinThread); }; -void -InitThreadCreated() -{ - ::pthread_key_create(&g_thread_create_key, MacOSXDarwinThread::PThreadDestructor); +void InitThreadCreated() { + ::pthread_key_create(&g_thread_create_key, + MacOSXDarwinThread::PThreadDestructor); } } // namespace -HostThreadMacOSX::HostThreadMacOSX() - : HostThreadPosix() -{ -} +HostThreadMacOSX::HostThreadMacOSX() : HostThreadPosix() {} HostThreadMacOSX::HostThreadMacOSX(lldb::thread_t thread) - : HostThreadPosix(thread) -{ -} + : HostThreadPosix(thread) {} lldb::thread_result_t -HostThreadMacOSX::ThreadCreateTrampoline(lldb::thread_arg_t arg) -{ - ::pthread_once(&g_thread_create_once, InitThreadCreated); - if (g_thread_create_key) - { - ::pthread_setspecific(g_thread_create_key, new MacOSXDarwinThread()); - } +HostThreadMacOSX::ThreadCreateTrampoline(lldb::thread_arg_t arg) { + ::pthread_once(&g_thread_create_once, InitThreadCreated); + if (g_thread_create_key) { + ::pthread_setspecific(g_thread_create_key, new MacOSXDarwinThread()); + } - return HostThreadPosix::ThreadCreateTrampoline(arg); + return HostThreadPosix::ThreadCreateTrampoline(arg); } diff --git a/lldb/source/Host/macosx/Symbols.cpp b/lldb/source/Host/macosx/Symbols.cpp index 3eba3273fd4..e6b31c61837 100644 --- a/lldb/source/Host/macosx/Symbols.cpp +++ b/lldb/source/Host/macosx/Symbols.cpp @@ -10,15 +10,19 @@ #include "lldb/Host/Symbols.h" // C Includes +#include "lldb/Utility/SafeMachO.h" #include <dirent.h> #include <pwd.h> -#include "lldb/Utility/SafeMachO.h" // C++ Includes // Other libraries and framework includes #include <CoreFoundation/CoreFoundation.h> // Project includes +#include "Host/macosx/cfcpp/CFCBundle.h" +#include "Host/macosx/cfcpp/CFCData.h" +#include "Host/macosx/cfcpp/CFCReleaser.h" +#include "Host/macosx/cfcpp/CFCString.h" #include "lldb/Core/ArchSpec.h" #include "lldb/Core/DataBuffer.h" #include "lldb/Core/DataExtractor.h" @@ -32,590 +36,554 @@ #include "lldb/Host/Host.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Utility/CleanUp.h" -#include "Host/macosx/cfcpp/CFCBundle.h" -#include "Host/macosx/cfcpp/CFCData.h" -#include "Host/macosx/cfcpp/CFCReleaser.h" -#include "Host/macosx/cfcpp/CFCString.h" #include "mach/machine.h" using namespace lldb; using namespace lldb_private; using namespace llvm::MachO; -#if !defined (__arm__) && !defined (__arm64__) && !defined (__aarch64__) // No DebugSymbols on the iOS devices +#if !defined(__arm__) && !defined(__arm64__) && \ + !defined(__aarch64__) // No DebugSymbols on the iOS devices extern "C" { -CFURLRef DBGCopyFullDSYMURLForUUID (CFUUIDRef uuid, CFURLRef exec_url); -CFDictionaryRef DBGCopyDSYMPropertyLists (CFURLRef dsym_url); - +CFURLRef DBGCopyFullDSYMURLForUUID(CFUUIDRef uuid, CFURLRef exec_url); +CFDictionaryRef DBGCopyDSYMPropertyLists(CFURLRef dsym_url); } #endif -int -LocateMacOSXFilesUsingDebugSymbols -( - const ModuleSpec &module_spec, - ModuleSpec &return_module_spec -) -{ - return_module_spec = module_spec; - return_module_spec.GetFileSpec().Clear(); - return_module_spec.GetSymbolFileSpec().Clear(); - - int items_found = 0; - -#if !defined (__arm__) && !defined (__arm64__) && !defined (__aarch64__) // No DebugSymbols on the iOS devices - - const UUID *uuid = module_spec.GetUUIDPtr(); - const ArchSpec *arch = module_spec.GetArchitecturePtr(); - - if (uuid && uuid->IsValid()) - { - // Try and locate the dSYM file using DebugSymbols first - const UInt8 *module_uuid = (const UInt8 *)uuid->GetBytes(); - if (module_uuid != NULL) - { - CFCReleaser<CFUUIDRef> module_uuid_ref(::CFUUIDCreateWithBytes (NULL, - module_uuid[0], - module_uuid[1], - module_uuid[2], - module_uuid[3], - module_uuid[4], - module_uuid[5], - module_uuid[6], - module_uuid[7], - module_uuid[8], - module_uuid[9], - module_uuid[10], - module_uuid[11], - module_uuid[12], - module_uuid[13], - module_uuid[14], - module_uuid[15])); - - if (module_uuid_ref.get()) - { - CFCReleaser<CFURLRef> exec_url; - const FileSpec *exec_fspec = module_spec.GetFileSpecPtr(); - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); - if (exec_fspec) - { - char exec_cf_path[PATH_MAX]; - if (exec_fspec->GetPath(exec_cf_path, sizeof(exec_cf_path))) - exec_url.reset(::CFURLCreateFromFileSystemRepresentation (NULL, - (const UInt8 *)exec_cf_path, - strlen(exec_cf_path), - FALSE)); - } - - CFCReleaser<CFURLRef> dsym_url (::DBGCopyFullDSYMURLForUUID(module_uuid_ref.get(), exec_url.get())); - char path[PATH_MAX]; +int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec, + ModuleSpec &return_module_spec) { + return_module_spec = module_spec; + return_module_spec.GetFileSpec().Clear(); + return_module_spec.GetSymbolFileSpec().Clear(); + + int items_found = 0; + +#if !defined(__arm__) && !defined(__arm64__) && \ + !defined(__aarch64__) // No DebugSymbols on the iOS devices + + const UUID *uuid = module_spec.GetUUIDPtr(); + const ArchSpec *arch = module_spec.GetArchitecturePtr(); + + if (uuid && uuid->IsValid()) { + // Try and locate the dSYM file using DebugSymbols first + const UInt8 *module_uuid = (const UInt8 *)uuid->GetBytes(); + if (module_uuid != NULL) { + CFCReleaser<CFUUIDRef> module_uuid_ref(::CFUUIDCreateWithBytes( + NULL, module_uuid[0], module_uuid[1], module_uuid[2], module_uuid[3], + module_uuid[4], module_uuid[5], module_uuid[6], module_uuid[7], + module_uuid[8], module_uuid[9], module_uuid[10], module_uuid[11], + module_uuid[12], module_uuid[13], module_uuid[14], module_uuid[15])); + + if (module_uuid_ref.get()) { + CFCReleaser<CFURLRef> exec_url; + const FileSpec *exec_fspec = module_spec.GetFileSpecPtr(); + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + if (exec_fspec) { + char exec_cf_path[PATH_MAX]; + if (exec_fspec->GetPath(exec_cf_path, sizeof(exec_cf_path))) + exec_url.reset(::CFURLCreateFromFileSystemRepresentation( + NULL, (const UInt8 *)exec_cf_path, strlen(exec_cf_path), + FALSE)); + } - if (dsym_url.get()) + CFCReleaser<CFURLRef> dsym_url( + ::DBGCopyFullDSYMURLForUUID(module_uuid_ref.get(), exec_url.get())); + char path[PATH_MAX]; + + if (dsym_url.get()) { + if (::CFURLGetFileSystemRepresentation( + dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) { + if (log) { + log->Printf("DebugSymbols framework returned dSYM path of %s for " + "UUID %s -- looking for the dSYM", + path, uuid->GetAsString().c_str()); + } + FileSpec dsym_filespec(path, path[0] == '~'); + + if (dsym_filespec.GetFileType() == FileSpec::eFileTypeDirectory) { + dsym_filespec = + Symbols::FindSymbolFileInBundle(dsym_filespec, uuid, arch); + ++items_found; + } else { + ++items_found; + } + return_module_spec.GetSymbolFileSpec() = dsym_filespec; + } + + bool success = false; + if (log) { + if (::CFURLGetFileSystemRepresentation( + dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) { + log->Printf("DebugSymbols framework returned dSYM path of %s for " + "UUID %s -- looking for an exec file", + path, uuid->GetAsString().c_str()); + } + } + + CFCReleaser<CFDictionaryRef> dict( + ::DBGCopyDSYMPropertyLists(dsym_url.get())); + CFDictionaryRef uuid_dict = NULL; + if (dict.get()) { + CFCString uuid_cfstr(uuid->GetAsString().c_str()); + uuid_dict = static_cast<CFDictionaryRef>( + ::CFDictionaryGetValue(dict.get(), uuid_cfstr.get())); + } + if (uuid_dict) { + CFStringRef exec_cf_path = + static_cast<CFStringRef>(::CFDictionaryGetValue( + uuid_dict, CFSTR("DBGSymbolRichExecutable"))); + if (exec_cf_path && ::CFStringGetFileSystemRepresentation( + exec_cf_path, path, sizeof(path))) { + if (log) { + log->Printf("plist bundle has exec path of %s for UUID %s", + path, uuid->GetAsString().c_str()); + } + ++items_found; + FileSpec exec_filespec(path, path[0] == '~'); + if (exec_filespec.Exists()) { + success = true; + return_module_spec.GetFileSpec() = exec_filespec; + } + } + } + + if (!success) { + // No dictionary, check near the dSYM bundle for an executable that + // matches... + if (::CFURLGetFileSystemRepresentation( + dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) { + char *dsym_extension_pos = ::strstr(path, ".dSYM"); + if (dsym_extension_pos) { + *dsym_extension_pos = '\0'; + if (log) { + log->Printf("Looking for executable binary next to dSYM " + "bundle with name with name %s", + path); + } + FileSpec file_spec(path, true); + ModuleSpecList module_specs; + ModuleSpec matched_module_spec; + switch (file_spec.GetFileType()) { + case FileSpec::eFileTypeDirectory: // Bundle directory? { - if (::CFURLGetFileSystemRepresentation (dsym_url.get(), true, (UInt8*)path, sizeof(path)-1)) - { - if (log) - { - log->Printf ("DebugSymbols framework returned dSYM path of %s for UUID %s -- looking for the dSYM", path, uuid->GetAsString().c_str()); - } - FileSpec dsym_filespec(path, path[0] == '~'); - - if (dsym_filespec.GetFileType () == FileSpec::eFileTypeDirectory) - { - dsym_filespec = Symbols::FindSymbolFileInBundle (dsym_filespec, uuid, arch); - ++items_found; - } - else - { - ++items_found; + CFCBundle bundle(path); + CFCReleaser<CFURLRef> bundle_exe_url( + bundle.CopyExecutableURL()); + if (bundle_exe_url.get()) { + if (::CFURLGetFileSystemRepresentation(bundle_exe_url.get(), + true, (UInt8 *)path, + sizeof(path) - 1)) { + FileSpec bundle_exe_file_spec(path, true); + if (ObjectFile::GetModuleSpecifications( + bundle_exe_file_spec, 0, 0, module_specs) && + module_specs.FindMatchingModuleSpec( + module_spec, matched_module_spec)) + + { + ++items_found; + return_module_spec.GetFileSpec() = bundle_exe_file_spec; + if (log) { + log->Printf("Executable binary %s next to dSYM is " + "compatible; using", + path); } - return_module_spec.GetSymbolFileSpec() = dsym_filespec; + } } - - bool success = false; - if (log) - { - if (::CFURLGetFileSystemRepresentation (dsym_url.get(), true, (UInt8*)path, sizeof(path)-1)) - { - log->Printf ("DebugSymbols framework returned dSYM path of %s for UUID %s -- looking for an exec file", path, uuid->GetAsString().c_str()); - } - - } - - CFCReleaser<CFDictionaryRef> dict(::DBGCopyDSYMPropertyLists (dsym_url.get())); - CFDictionaryRef uuid_dict = NULL; - if (dict.get()) - { - CFCString uuid_cfstr (uuid->GetAsString().c_str()); - uuid_dict = static_cast<CFDictionaryRef>(::CFDictionaryGetValue (dict.get(), uuid_cfstr.get())); - } - if (uuid_dict) - { - CFStringRef exec_cf_path = static_cast<CFStringRef>(::CFDictionaryGetValue (uuid_dict, CFSTR("DBGSymbolRichExecutable"))); - if (exec_cf_path && ::CFStringGetFileSystemRepresentation (exec_cf_path, path, sizeof(path))) - { - if (log) - { - log->Printf ("plist bundle has exec path of %s for UUID %s", path, uuid->GetAsString().c_str()); - } - ++items_found; - FileSpec exec_filespec (path, path[0] == '~'); - if (exec_filespec.Exists()) - { - success = true; - return_module_spec.GetFileSpec() = exec_filespec; - } - } - } - - if (!success) - { - // No dictionary, check near the dSYM bundle for an executable that matches... - if (::CFURLGetFileSystemRepresentation (dsym_url.get(), true, (UInt8*)path, sizeof(path)-1)) - { - char *dsym_extension_pos = ::strstr (path, ".dSYM"); - if (dsym_extension_pos) - { - *dsym_extension_pos = '\0'; - if (log) - { - log->Printf ("Looking for executable binary next to dSYM bundle with name with name %s", path); - } - FileSpec file_spec (path, true); - ModuleSpecList module_specs; - ModuleSpec matched_module_spec; - switch (file_spec.GetFileType()) - { - case FileSpec::eFileTypeDirectory: // Bundle directory? - { - CFCBundle bundle (path); - CFCReleaser<CFURLRef> bundle_exe_url (bundle.CopyExecutableURL ()); - if (bundle_exe_url.get()) - { - if (::CFURLGetFileSystemRepresentation (bundle_exe_url.get(), true, (UInt8*)path, sizeof(path)-1)) - { - FileSpec bundle_exe_file_spec (path, true); - if (ObjectFile::GetModuleSpecifications(bundle_exe_file_spec, 0, 0, module_specs) && - module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec)) - - { - ++items_found; - return_module_spec.GetFileSpec() = bundle_exe_file_spec; - if (log) - { - log->Printf ("Executable binary %s next to dSYM is compatible; using", path); - } - } - } - } - } - break; - - case FileSpec::eFileTypePipe: // Forget pipes - case FileSpec::eFileTypeSocket: // We can't process socket files - case FileSpec::eFileTypeInvalid: // File doesn't exist... - break; - - case FileSpec::eFileTypeUnknown: - case FileSpec::eFileTypeRegular: - case FileSpec::eFileTypeSymbolicLink: - case FileSpec::eFileTypeOther: - if (ObjectFile::GetModuleSpecifications(file_spec, 0, 0, module_specs) && - module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec)) - - { - ++items_found; - return_module_spec.GetFileSpec() = file_spec; - if (log) - { - log->Printf ("Executable binary %s next to dSYM is compatible; using", path); - } - } - break; - } - } - } + } + } break; + + case FileSpec::eFileTypePipe: // Forget pipes + case FileSpec::eFileTypeSocket: // We can't process socket files + case FileSpec::eFileTypeInvalid: // File doesn't exist... + break; + + case FileSpec::eFileTypeUnknown: + case FileSpec::eFileTypeRegular: + case FileSpec::eFileTypeSymbolicLink: + case FileSpec::eFileTypeOther: + if (ObjectFile::GetModuleSpecifications(file_spec, 0, 0, + module_specs) && + module_specs.FindMatchingModuleSpec(module_spec, + matched_module_spec)) + + { + ++items_found; + return_module_spec.GetFileSpec() = file_spec; + if (log) { + log->Printf("Executable binary %s next to dSYM is " + "compatible; using", + path); } + } + break; } + } } + } } + } } -#endif // #if !defined (__arm__) && !defined (__arm64__) && !defined (__aarch64__) + } +#endif // #if !defined (__arm__) && !defined (__arm64__) && !defined + // (__aarch64__) - return items_found; + return items_found; } -FileSpec -Symbols::FindSymbolFileInBundle (const FileSpec& dsym_bundle_fspec, - const lldb_private::UUID *uuid, - const ArchSpec *arch) -{ - char path[PATH_MAX]; - - FileSpec dsym_fspec; - - if (dsym_bundle_fspec.GetPath(path, sizeof(path))) - { - ::strncat (path, "/Contents/Resources/DWARF", sizeof(path) - strlen(path) - 1); - - lldb_utility::CleanUp <DIR *, int> dirp (opendir(path), NULL, closedir); - if (dirp.is_valid()) - { - dsym_fspec.GetDirectory().SetCString(path); - struct dirent* dp; - while ((dp = readdir(dirp.get())) != NULL) - { - // Only search directories - if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN) - { - if (dp->d_namlen == 1 && dp->d_name[0] == '.') - continue; - - if (dp->d_namlen == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.') - continue; - } +FileSpec Symbols::FindSymbolFileInBundle(const FileSpec &dsym_bundle_fspec, + const lldb_private::UUID *uuid, + const ArchSpec *arch) { + char path[PATH_MAX]; + + FileSpec dsym_fspec; + + if (dsym_bundle_fspec.GetPath(path, sizeof(path))) { + ::strncat(path, "/Contents/Resources/DWARF", + sizeof(path) - strlen(path) - 1); + + lldb_utility::CleanUp<DIR *, int> dirp(opendir(path), NULL, closedir); + if (dirp.is_valid()) { + dsym_fspec.GetDirectory().SetCString(path); + struct dirent *dp; + while ((dp = readdir(dirp.get())) != NULL) { + // Only search directories + if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN) { + if (dp->d_namlen == 1 && dp->d_name[0] == '.') + continue; + + if (dp->d_namlen == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.') + continue; + } - if (dp->d_type == DT_REG || dp->d_type == DT_UNKNOWN) - { - dsym_fspec.GetFilename().SetCString(dp->d_name); - ModuleSpecList module_specs; - if (ObjectFile::GetModuleSpecifications(dsym_fspec, 0, 0, module_specs)) - { - ModuleSpec spec; - for (size_t i = 0; i < module_specs.GetSize(); ++i) - { - assert(module_specs.GetModuleSpecAtIndex(i, spec)); - if ((uuid == NULL || (spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) && - (arch == NULL || (spec.GetArchitecturePtr() && spec.GetArchitecture().IsCompatibleMatch(*arch)))) - { - return dsym_fspec; - } - } - } - } + if (dp->d_type == DT_REG || dp->d_type == DT_UNKNOWN) { + dsym_fspec.GetFilename().SetCString(dp->d_name); + ModuleSpecList module_specs; + if (ObjectFile::GetModuleSpecifications(dsym_fspec, 0, 0, + module_specs)) { + ModuleSpec spec; + for (size_t i = 0; i < module_specs.GetSize(); ++i) { + assert(module_specs.GetModuleSpecAtIndex(i, spec)); + if ((uuid == NULL || + (spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) && + (arch == NULL || + (spec.GetArchitecturePtr() && + spec.GetArchitecture().IsCompatibleMatch(*arch)))) { + return dsym_fspec; + } } + } } + } } - dsym_fspec.Clear(); - return dsym_fspec; + } + dsym_fspec.Clear(); + return dsym_fspec; } -static bool -GetModuleSpecInfoFromUUIDDictionary (CFDictionaryRef uuid_dict, ModuleSpec &module_spec) -{ - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); - bool success = false; - if (uuid_dict != NULL && CFGetTypeID (uuid_dict) == CFDictionaryGetTypeID ()) - { - std::string str; - CFStringRef cf_str; - CFDictionaryRef cf_dict; - - cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGSymbolRichExecutable")); - if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ()) - { - if (CFCString::FileSystemRepresentation(cf_str, str)) - { - module_spec.GetFileSpec().SetFile (str.c_str(), true); - if (log) - { - log->Printf ("From dsymForUUID plist: Symbol rich executable is at '%s'", str.c_str()); - } - } - } - - cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGDSYMPath")); - if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ()) - { - if (CFCString::FileSystemRepresentation(cf_str, str)) - { - module_spec.GetSymbolFileSpec().SetFile (str.c_str(), true); - success = true; - if (log) - { - log->Printf ("From dsymForUUID plist: dSYM is at '%s'", str.c_str()); - } - } +static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict, + ModuleSpec &module_spec) { + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + bool success = false; + if (uuid_dict != NULL && CFGetTypeID(uuid_dict) == CFDictionaryGetTypeID()) { + std::string str; + CFStringRef cf_str; + CFDictionaryRef cf_dict; + + cf_str = (CFStringRef)CFDictionaryGetValue( + (CFDictionaryRef)uuid_dict, CFSTR("DBGSymbolRichExecutable")); + if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) { + if (CFCString::FileSystemRepresentation(cf_str, str)) { + module_spec.GetFileSpec().SetFile(str.c_str(), true); + if (log) { + log->Printf( + "From dsymForUUID plist: Symbol rich executable is at '%s'", + str.c_str()); } - - cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGArchitecture")); - if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ()) - { - if (CFCString::FileSystemRepresentation(cf_str, str)) - module_spec.GetArchitecture().SetTriple(str.c_str()); + } + } + + cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict, + CFSTR("DBGDSYMPath")); + if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) { + if (CFCString::FileSystemRepresentation(cf_str, str)) { + module_spec.GetSymbolFileSpec().SetFile(str.c_str(), true); + success = true; + if (log) { + log->Printf("From dsymForUUID plist: dSYM is at '%s'", str.c_str()); } + } + } - std::string DBGBuildSourcePath; - std::string DBGSourcePath; + cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict, + CFSTR("DBGArchitecture")); + if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) { + if (CFCString::FileSystemRepresentation(cf_str, str)) + module_spec.GetArchitecture().SetTriple(str.c_str()); + } - cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGBuildSourcePath")); - if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ()) - { - CFCString::FileSystemRepresentation(cf_str, DBGBuildSourcePath); - } + std::string DBGBuildSourcePath; + std::string DBGSourcePath; - cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGSourcePath")); - if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ()) - { - CFCString::FileSystemRepresentation(cf_str, DBGSourcePath); - } - - if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) - { - if (DBGSourcePath[0] == '~') - { - FileSpec resolved_source_path(DBGSourcePath.c_str(), true); - DBGSourcePath = resolved_source_path.GetPath(); - } - module_spec.GetSourceMappingList().Append (ConstString(DBGBuildSourcePath.c_str()), ConstString(DBGSourcePath.c_str()), true); - } + cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict, + CFSTR("DBGBuildSourcePath")); + if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) { + CFCString::FileSystemRepresentation(cf_str, DBGBuildSourcePath); + } - cf_dict = (CFDictionaryRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGSourcePathRemapping")); - if (cf_dict && CFGetTypeID (cf_dict) == CFDictionaryGetTypeID ()) - { - // If we see DBGVersion with any kind of value, this is a new style DBGSourcePathRemapping dictionary - bool new_style_source_remapping_dictionary = false; - std::string original_DBGSourcePath_value = DBGSourcePath; - const void *version_value; - version_value = CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGVersion")); - if (version_value) - new_style_source_remapping_dictionary = true; - - CFIndex kv_pair_count = CFDictionaryGetCount ((CFDictionaryRef) uuid_dict); - if (kv_pair_count > 0) - { - CFStringRef *keys = (CFStringRef *) malloc (kv_pair_count * sizeof (CFStringRef)); - CFStringRef *values = (CFStringRef *) malloc (kv_pair_count * sizeof (CFStringRef)); - if (keys != nullptr && values != nullptr) - { - CFDictionaryGetKeysAndValues ((CFDictionaryRef) uuid_dict, (const void**)keys, (const void**)values); - } - for (CFIndex i = 0; i < kv_pair_count; i++) - { - DBGBuildSourcePath.clear(); - DBGSourcePath.clear(); - if (keys[i] && CFGetTypeID (keys[i]) == CFStringGetTypeID ()) - { - CFCString::FileSystemRepresentation(keys[i], DBGBuildSourcePath); - } - if (values[i] && CFGetTypeID (values[i]) == CFStringGetTypeID ()) - { - CFCString::FileSystemRepresentation(values[i], DBGSourcePath); - } - if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) - { - // In the "old style" DBGSourcePathRemapping dictionary, the DBGSourcePath values - // (the "values" half of key-value path pairs) were wrong. Ignore them and use the - // universal DBGSourcePath string from earlier. - if (new_style_source_remapping_dictionary == true && !original_DBGSourcePath_value.empty()) - { - DBGSourcePath = original_DBGSourcePath_value; - } - if (DBGSourcePath[0] == '~') - { - FileSpec resolved_source_path(DBGSourcePath.c_str(), true); - DBGSourcePath = resolved_source_path.GetPath(); - } - module_spec.GetSourceMappingList().Append (ConstString(DBGBuildSourcePath.c_str()), ConstString(DBGSourcePath.c_str()), true); - } - } - if (keys) - free (keys); - if (values) - free (values); - } - } + cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict, + CFSTR("DBGSourcePath")); + if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) { + CFCString::FileSystemRepresentation(cf_str, DBGSourcePath); } - return success; -} + if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) { + if (DBGSourcePath[0] == '~') { + FileSpec resolved_source_path(DBGSourcePath.c_str(), true); + DBGSourcePath = resolved_source_path.GetPath(); + } + module_spec.GetSourceMappingList().Append( + ConstString(DBGBuildSourcePath.c_str()), + ConstString(DBGSourcePath.c_str()), true); + } -bool -Symbols::DownloadObjectAndSymbolFile (ModuleSpec &module_spec, bool force_lookup) -{ - bool success = false; - const UUID *uuid_ptr = module_spec.GetUUIDPtr(); - const FileSpec *file_spec_ptr = module_spec.GetFileSpecPtr(); - - // It's expensive to check for the DBGShellCommands defaults setting, only do it once per - // lldb run and cache the result. - static bool g_have_checked_for_dbgshell_command = false; - static const char *g_dbgshell_command = NULL; - if (g_have_checked_for_dbgshell_command == false) - { - g_have_checked_for_dbgshell_command = true; - CFTypeRef defaults_setting = CFPreferencesCopyAppValue (CFSTR ("DBGShellCommands"), CFSTR ("com.apple.DebugSymbols")); - if (defaults_setting && CFGetTypeID (defaults_setting) == CFStringGetTypeID()) - { - char cstr_buf[PATH_MAX]; - if (CFStringGetCString ((CFStringRef) defaults_setting, cstr_buf, sizeof (cstr_buf), kCFStringEncodingUTF8)) - { - g_dbgshell_command = strdup (cstr_buf); // this malloc'ed memory will never be freed - } + cf_dict = (CFDictionaryRef)CFDictionaryGetValue( + (CFDictionaryRef)uuid_dict, CFSTR("DBGSourcePathRemapping")); + if (cf_dict && CFGetTypeID(cf_dict) == CFDictionaryGetTypeID()) { + // If we see DBGVersion with any kind of value, this is a new style + // DBGSourcePathRemapping dictionary + bool new_style_source_remapping_dictionary = false; + std::string original_DBGSourcePath_value = DBGSourcePath; + const void *version_value; + version_value = + CFDictionaryGetValue((CFDictionaryRef)uuid_dict, CFSTR("DBGVersion")); + if (version_value) + new_style_source_remapping_dictionary = true; + + CFIndex kv_pair_count = CFDictionaryGetCount((CFDictionaryRef)uuid_dict); + if (kv_pair_count > 0) { + CFStringRef *keys = + (CFStringRef *)malloc(kv_pair_count * sizeof(CFStringRef)); + CFStringRef *values = + (CFStringRef *)malloc(kv_pair_count * sizeof(CFStringRef)); + if (keys != nullptr && values != nullptr) { + CFDictionaryGetKeysAndValues((CFDictionaryRef)uuid_dict, + (const void **)keys, + (const void **)values); } - if (defaults_setting) - { - CFRelease (defaults_setting); + for (CFIndex i = 0; i < kv_pair_count; i++) { + DBGBuildSourcePath.clear(); + DBGSourcePath.clear(); + if (keys[i] && CFGetTypeID(keys[i]) == CFStringGetTypeID()) { + CFCString::FileSystemRepresentation(keys[i], DBGBuildSourcePath); + } + if (values[i] && CFGetTypeID(values[i]) == CFStringGetTypeID()) { + CFCString::FileSystemRepresentation(values[i], DBGSourcePath); + } + if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) { + // In the "old style" DBGSourcePathRemapping dictionary, the + // DBGSourcePath values + // (the "values" half of key-value path pairs) were wrong. Ignore + // them and use the + // universal DBGSourcePath string from earlier. + if (new_style_source_remapping_dictionary == true && + !original_DBGSourcePath_value.empty()) { + DBGSourcePath = original_DBGSourcePath_value; + } + if (DBGSourcePath[0] == '~') { + FileSpec resolved_source_path(DBGSourcePath.c_str(), true); + DBGSourcePath = resolved_source_path.GetPath(); + } + module_spec.GetSourceMappingList().Append( + ConstString(DBGBuildSourcePath.c_str()), + ConstString(DBGSourcePath.c_str()), true); + } } + if (keys) + free(keys); + if (values) + free(values); + } } + } + return success; +} - // When g_dbgshell_command is NULL, the user has not enabled the use of an external program - // to find the symbols, don't run it for them. - if (force_lookup == false && g_dbgshell_command == NULL) - { - return false; +bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec, + bool force_lookup) { + bool success = false; + const UUID *uuid_ptr = module_spec.GetUUIDPtr(); + const FileSpec *file_spec_ptr = module_spec.GetFileSpecPtr(); + + // It's expensive to check for the DBGShellCommands defaults setting, only do + // it once per + // lldb run and cache the result. + static bool g_have_checked_for_dbgshell_command = false; + static const char *g_dbgshell_command = NULL; + if (g_have_checked_for_dbgshell_command == false) { + g_have_checked_for_dbgshell_command = true; + CFTypeRef defaults_setting = CFPreferencesCopyAppValue( + CFSTR("DBGShellCommands"), CFSTR("com.apple.DebugSymbols")); + if (defaults_setting && + CFGetTypeID(defaults_setting) == CFStringGetTypeID()) { + char cstr_buf[PATH_MAX]; + if (CFStringGetCString((CFStringRef)defaults_setting, cstr_buf, + sizeof(cstr_buf), kCFStringEncodingUTF8)) { + g_dbgshell_command = + strdup(cstr_buf); // this malloc'ed memory will never be freed + } } - - if (uuid_ptr || (file_spec_ptr && file_spec_ptr->Exists())) - { - static bool g_located_dsym_for_uuid_exe = false; - static bool g_dsym_for_uuid_exe_exists = false; - static char g_dsym_for_uuid_exe_path[PATH_MAX]; - if (!g_located_dsym_for_uuid_exe) - { - g_located_dsym_for_uuid_exe = true; - const char *dsym_for_uuid_exe_path_cstr = getenv("LLDB_APPLE_DSYMFORUUID_EXECUTABLE"); - FileSpec dsym_for_uuid_exe_spec; - if (dsym_for_uuid_exe_path_cstr) - { - dsym_for_uuid_exe_spec.SetFile(dsym_for_uuid_exe_path_cstr, true); - g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists(); + if (defaults_setting) { + CFRelease(defaults_setting); + } + } + + // When g_dbgshell_command is NULL, the user has not enabled the use of an + // external program + // to find the symbols, don't run it for them. + if (force_lookup == false && g_dbgshell_command == NULL) { + return false; + } + + if (uuid_ptr || (file_spec_ptr && file_spec_ptr->Exists())) { + static bool g_located_dsym_for_uuid_exe = false; + static bool g_dsym_for_uuid_exe_exists = false; + static char g_dsym_for_uuid_exe_path[PATH_MAX]; + if (!g_located_dsym_for_uuid_exe) { + g_located_dsym_for_uuid_exe = true; + const char *dsym_for_uuid_exe_path_cstr = + getenv("LLDB_APPLE_DSYMFORUUID_EXECUTABLE"); + FileSpec dsym_for_uuid_exe_spec; + if (dsym_for_uuid_exe_path_cstr) { + dsym_for_uuid_exe_spec.SetFile(dsym_for_uuid_exe_path_cstr, true); + g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists(); + } + + if (!g_dsym_for_uuid_exe_exists) { + dsym_for_uuid_exe_spec.SetFile("/usr/local/bin/dsymForUUID", false); + g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists(); + if (!g_dsym_for_uuid_exe_exists) { + long bufsize; + if ((bufsize = sysconf(_SC_GETPW_R_SIZE_MAX)) != -1) { + char buffer[bufsize]; + struct passwd pwd; + struct passwd *tilde_rc = NULL; + // we are a library so we need to use the reentrant version of + // getpwnam() + if (getpwnam_r("rc", &pwd, buffer, bufsize, &tilde_rc) == 0 && + tilde_rc && tilde_rc->pw_dir) { + std::string dsymforuuid_path(tilde_rc->pw_dir); + dsymforuuid_path += "/bin/dsymForUUID"; + dsym_for_uuid_exe_spec.SetFile(dsymforuuid_path.c_str(), false); + g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists(); } - - if (!g_dsym_for_uuid_exe_exists) - { - dsym_for_uuid_exe_spec.SetFile("/usr/local/bin/dsymForUUID", false); - g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists(); - if (!g_dsym_for_uuid_exe_exists) - { - long bufsize; - if ((bufsize = sysconf(_SC_GETPW_R_SIZE_MAX)) != -1) - { - char buffer[bufsize]; - struct passwd pwd; - struct passwd *tilde_rc = NULL; - // we are a library so we need to use the reentrant version of getpwnam() - if (getpwnam_r ("rc", &pwd, buffer, bufsize, &tilde_rc) == 0 - && tilde_rc - && tilde_rc->pw_dir) - { - std::string dsymforuuid_path(tilde_rc->pw_dir); - dsymforuuid_path += "/bin/dsymForUUID"; - dsym_for_uuid_exe_spec.SetFile(dsymforuuid_path.c_str(), false); - g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists(); - } + } + } + } + if (!g_dsym_for_uuid_exe_exists && g_dbgshell_command != NULL) { + dsym_for_uuid_exe_spec.SetFile(g_dbgshell_command, true); + g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists(); + } + + if (g_dsym_for_uuid_exe_exists) + dsym_for_uuid_exe_spec.GetPath(g_dsym_for_uuid_exe_path, + sizeof(g_dsym_for_uuid_exe_path)); + } + if (g_dsym_for_uuid_exe_exists) { + std::string uuid_str; + char file_path[PATH_MAX]; + file_path[0] = '\0'; + + if (uuid_ptr) + uuid_str = uuid_ptr->GetAsString(); + + if (file_spec_ptr) + file_spec_ptr->GetPath(file_path, sizeof(file_path)); + + StreamString command; + if (!uuid_str.empty()) + command.Printf("%s --ignoreNegativeCache --copyExecutable %s", + g_dsym_for_uuid_exe_path, uuid_str.c_str()); + else if (file_path[0] != '\0') + command.Printf("%s --ignoreNegativeCache --copyExecutable %s", + g_dsym_for_uuid_exe_path, file_path); + + if (!command.GetString().empty()) { + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + int exit_status = -1; + int signo = -1; + std::string command_output; + if (log) { + if (!uuid_str.empty()) + log->Printf("Calling %s with UUID %s to find dSYM", + g_dsym_for_uuid_exe_path, uuid_str.c_str()); + else if (file_path[0] != '\0') + log->Printf("Calling %s with file %s to find dSYM", + g_dsym_for_uuid_exe_path, file_path); + } + Error error = Host::RunShellCommand( + command.GetData(), + NULL, // current working directory + &exit_status, // Exit status + &signo, // Signal int * + &command_output, // Command output + 30, // Large timeout to allow for long dsym download times + false); // Don't run in a shell (we don't need shell expansion) + if (error.Success() && exit_status == 0 && !command_output.empty()) { + CFCData data(CFDataCreateWithBytesNoCopy( + NULL, (const UInt8 *)command_output.data(), command_output.size(), + kCFAllocatorNull)); + + CFCReleaser<CFDictionaryRef> plist( + (CFDictionaryRef)::CFPropertyListCreateFromXMLData( + NULL, data.get(), kCFPropertyListImmutable, NULL)); + + if (plist.get() && + CFGetTypeID(plist.get()) == CFDictionaryGetTypeID()) { + if (!uuid_str.empty()) { + CFCString uuid_cfstr(uuid_str.c_str()); + CFDictionaryRef uuid_dict = (CFDictionaryRef)CFDictionaryGetValue( + plist.get(), uuid_cfstr.get()); + success = + GetModuleSpecInfoFromUUIDDictionary(uuid_dict, module_spec); + } else { + const CFIndex num_values = ::CFDictionaryGetCount(plist.get()); + if (num_values > 0) { + std::vector<CFStringRef> keys(num_values, NULL); + std::vector<CFDictionaryRef> values(num_values, NULL); + ::CFDictionaryGetKeysAndValues(plist.get(), NULL, + (const void **)&values[0]); + if (num_values == 1) { + return GetModuleSpecInfoFromUUIDDictionary(values[0], + module_spec); + } else { + for (CFIndex i = 0; i < num_values; ++i) { + ModuleSpec curr_module_spec; + if (GetModuleSpecInfoFromUUIDDictionary(values[i], + curr_module_spec)) { + if (module_spec.GetArchitecture().IsCompatibleMatch( + curr_module_spec.GetArchitecture())) { + module_spec = curr_module_spec; + return true; + } } + } } + } } - if (!g_dsym_for_uuid_exe_exists && g_dbgshell_command != NULL) - { - dsym_for_uuid_exe_spec.SetFile(g_dbgshell_command, true); - g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists(); - } - - if (g_dsym_for_uuid_exe_exists) - dsym_for_uuid_exe_spec.GetPath (g_dsym_for_uuid_exe_path, sizeof(g_dsym_for_uuid_exe_path)); - } - if (g_dsym_for_uuid_exe_exists) - { - std::string uuid_str; - char file_path[PATH_MAX]; - file_path[0] = '\0'; - - if (uuid_ptr) - uuid_str = uuid_ptr->GetAsString(); - - if (file_spec_ptr) - file_spec_ptr->GetPath(file_path, sizeof(file_path)); - - StreamString command; + } + } else { + if (log) { if (!uuid_str.empty()) - command.Printf("%s --ignoreNegativeCache --copyExecutable %s", g_dsym_for_uuid_exe_path, uuid_str.c_str()); + log->Printf("Called %s on %s, no matches", + g_dsym_for_uuid_exe_path, uuid_str.c_str()); else if (file_path[0] != '\0') - command.Printf("%s --ignoreNegativeCache --copyExecutable %s", g_dsym_for_uuid_exe_path, file_path); - - if (!command.GetString().empty()) - { - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); - int exit_status = -1; - int signo = -1; - std::string command_output; - if (log) - { - if (!uuid_str.empty()) - log->Printf("Calling %s with UUID %s to find dSYM", g_dsym_for_uuid_exe_path, uuid_str.c_str()); - else if (file_path[0] != '\0') - log->Printf("Calling %s with file %s to find dSYM", g_dsym_for_uuid_exe_path, file_path); - } - Error error = Host::RunShellCommand (command.GetData(), - NULL, // current working directory - &exit_status, // Exit status - &signo, // Signal int * - &command_output, // Command output - 30, // Large timeout to allow for long dsym download times - false); // Don't run in a shell (we don't need shell expansion) - if (error.Success() && exit_status == 0 && !command_output.empty()) - { - CFCData data (CFDataCreateWithBytesNoCopy (NULL, - (const UInt8 *)command_output.data(), - command_output.size(), - kCFAllocatorNull)); - - CFCReleaser<CFDictionaryRef> plist((CFDictionaryRef)::CFPropertyListCreateFromXMLData (NULL, data.get(), kCFPropertyListImmutable, NULL)); - - if (plist.get() && CFGetTypeID (plist.get()) == CFDictionaryGetTypeID ()) - { - if (!uuid_str.empty()) - { - CFCString uuid_cfstr(uuid_str.c_str()); - CFDictionaryRef uuid_dict = (CFDictionaryRef)CFDictionaryGetValue (plist.get(), uuid_cfstr.get()); - success = GetModuleSpecInfoFromUUIDDictionary (uuid_dict, module_spec); - } - else - { - const CFIndex num_values = ::CFDictionaryGetCount(plist.get()); - if (num_values > 0) - { - std::vector<CFStringRef> keys (num_values, NULL); - std::vector<CFDictionaryRef> values (num_values, NULL); - ::CFDictionaryGetKeysAndValues(plist.get(), NULL, (const void **)&values[0]); - if (num_values == 1) - { - return GetModuleSpecInfoFromUUIDDictionary (values[0], module_spec); - } - else - { - for (CFIndex i=0; i<num_values; ++i) - { - ModuleSpec curr_module_spec; - if (GetModuleSpecInfoFromUUIDDictionary (values[i], curr_module_spec)) - { - if (module_spec.GetArchitecture().IsCompatibleMatch(curr_module_spec.GetArchitecture())) - { - module_spec = curr_module_spec; - return true; - } - } - } - } - } - } - } - } - else - { - if (log) - { - if (!uuid_str.empty()) - log->Printf("Called %s on %s, no matches", g_dsym_for_uuid_exe_path, uuid_str.c_str()); - else if (file_path[0] != '\0') - log->Printf("Called %s on %s, no matches", g_dsym_for_uuid_exe_path, file_path); - } - } - } + log->Printf("Called %s on %s, no matches", + g_dsym_for_uuid_exe_path, file_path); + } } + } } - return success; + } + return success; } - diff --git a/lldb/source/Host/macosx/ThisThread.cpp b/lldb/source/Host/macosx/ThisThread.cpp index 6f1c88f6730..5244ba01412 100644 --- a/lldb/source/Host/macosx/ThisThread.cpp +++ b/lldb/source/Host/macosx/ThisThread.cpp @@ -9,21 +9,17 @@ #include "lldb/Host/ThisThread.h" -#include <pthread.h> #include "llvm/ADT/SmallVector.h" +#include <pthread.h> using namespace lldb_private; -void -ThisThread::SetName(llvm::StringRef name) -{ -#if defined (__APPLE__) - ::pthread_setname_np(name.str().c_str()); +void ThisThread::SetName(llvm::StringRef name) { +#if defined(__APPLE__) + ::pthread_setname_np(name.str().c_str()); #endif } -void -ThisThread::GetName(llvm::SmallVectorImpl<char> &name) -{ - // FIXME - implement this. +void ThisThread::GetName(llvm::SmallVectorImpl<char> &name) { + // FIXME - implement this. } diff --git a/lldb/source/Host/macosx/cfcpp/CFCBundle.cpp b/lldb/source/Host/macosx/cfcpp/CFCBundle.cpp index 71b07499366..08f16701c36 100644 --- a/lldb/source/Host/macosx/cfcpp/CFCBundle.cpp +++ b/lldb/source/Host/macosx/cfcpp/CFCBundle.cpp @@ -13,87 +13,71 @@ //---------------------------------------------------------------------- // CFCBundle constructor //---------------------------------------------------------------------- -CFCBundle::CFCBundle(const char *path) : - CFCReleaser<CFBundleRef>() -{ - if (path && path[0]) - SetPath(path); +CFCBundle::CFCBundle(const char *path) : CFCReleaser<CFBundleRef>() { + if (path && path[0]) + SetPath(path); } -CFCBundle::CFCBundle(CFURLRef url) : - CFCReleaser<CFBundleRef>(url ? CFBundleCreate(NULL, url) : NULL) -{ -} +CFCBundle::CFCBundle(CFURLRef url) + : CFCReleaser<CFBundleRef>(url ? CFBundleCreate(NULL, url) : NULL) {} //---------------------------------------------------------------------- // Destructor //---------------------------------------------------------------------- -CFCBundle::~CFCBundle() -{ -} +CFCBundle::~CFCBundle() {} //---------------------------------------------------------------------- // Set the path for a bundle by supplying a //---------------------------------------------------------------------- -bool -CFCBundle::SetPath (const char *path) -{ - CFAllocatorRef alloc = kCFAllocatorDefault; - // Release our old bundle and URL - reset(); +bool CFCBundle::SetPath(const char *path) { + CFAllocatorRef alloc = kCFAllocatorDefault; + // Release our old bundle and URL + reset(); - // Make a CFStringRef from the supplied path - CFCString cf_path; - cf_path.SetFileSystemRepresentation(path); - if (cf_path.get()) - { - // Make our Bundle URL - CFCReleaser<CFURLRef> bundle_url (::CFURLCreateWithFileSystemPath (alloc, cf_path.get(), kCFURLPOSIXPathStyle, true)); - if (bundle_url.get()) - reset (::CFBundleCreate (alloc, bundle_url.get())); - } - return get() != NULL; + // Make a CFStringRef from the supplied path + CFCString cf_path; + cf_path.SetFileSystemRepresentation(path); + if (cf_path.get()) { + // Make our Bundle URL + CFCReleaser<CFURLRef> bundle_url(::CFURLCreateWithFileSystemPath( + alloc, cf_path.get(), kCFURLPOSIXPathStyle, true)); + if (bundle_url.get()) + reset(::CFBundleCreate(alloc, bundle_url.get())); + } + return get() != NULL; } -bool -CFCBundle::GetPath (char *dst, size_t dst_len) -{ - CFBundleRef bundle = get(); - if (bundle) - { - CFCReleaser<CFURLRef> bundle_url (CFBundleCopyBundleURL (bundle)); - if (bundle_url.get()) - { - Boolean resolveAgainstBase = 0; - return ::CFURLGetFileSystemRepresentation (bundle_url.get(), resolveAgainstBase, (UInt8 *)dst, dst_len) != 0; - } +bool CFCBundle::GetPath(char *dst, size_t dst_len) { + CFBundleRef bundle = get(); + if (bundle) { + CFCReleaser<CFURLRef> bundle_url(CFBundleCopyBundleURL(bundle)); + if (bundle_url.get()) { + Boolean resolveAgainstBase = 0; + return ::CFURLGetFileSystemRepresentation(bundle_url.get(), + resolveAgainstBase, + (UInt8 *)dst, dst_len) != 0; } - return false; -} + } + return false; +} -CFStringRef -CFCBundle::GetIdentifier () const -{ - CFBundleRef bundle = get(); - if (bundle != NULL) - return ::CFBundleGetIdentifier (bundle); - return NULL; +CFStringRef CFCBundle::GetIdentifier() const { + CFBundleRef bundle = get(); + if (bundle != NULL) + return ::CFBundleGetIdentifier(bundle); + return NULL; } -CFTypeRef -CFCBundle::GetValueForInfoDictionaryKey(CFStringRef key) const -{ - CFBundleRef bundle = get(); - if (bundle != NULL) - return ::CFBundleGetValueForInfoDictionaryKey(bundle, key); - return NULL; +CFTypeRef CFCBundle::GetValueForInfoDictionaryKey(CFStringRef key) const { + CFBundleRef bundle = get(); + if (bundle != NULL) + return ::CFBundleGetValueForInfoDictionaryKey(bundle, key); + return NULL; } -CFURLRef -CFCBundle::CopyExecutableURL () const -{ - CFBundleRef bundle = get(); - if (bundle != NULL) - return CFBundleCopyExecutableURL(bundle); - return NULL; +CFURLRef CFCBundle::CopyExecutableURL() const { + CFBundleRef bundle = get(); + if (bundle != NULL) + return CFBundleCopyExecutableURL(bundle); + return NULL; } diff --git a/lldb/source/Host/macosx/cfcpp/CFCBundle.h b/lldb/source/Host/macosx/cfcpp/CFCBundle.h index 1cd1b681af8..9506b93f653 100644 --- a/lldb/source/Host/macosx/cfcpp/CFCBundle.h +++ b/lldb/source/Host/macosx/cfcpp/CFCBundle.h @@ -12,39 +12,31 @@ #include "CFCReleaser.h" -class CFCBundle : public CFCReleaser<CFBundleRef> -{ +class CFCBundle : public CFCReleaser<CFBundleRef> { public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - CFCBundle (const char *path = NULL); - CFCBundle (CFURLRef url); + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + CFCBundle(const char *path = NULL); + CFCBundle(CFURLRef url); - virtual - ~CFCBundle(); + virtual ~CFCBundle(); - CFURLRef - CopyExecutableURL () const; + CFURLRef CopyExecutableURL() const; - CFStringRef - GetIdentifier () const; + CFStringRef GetIdentifier() const; - CFTypeRef - GetValueForInfoDictionaryKey(CFStringRef key) const; + CFTypeRef GetValueForInfoDictionaryKey(CFStringRef key) const; - bool - GetPath (char *dst, size_t dst_len); + bool GetPath(char *dst, size_t dst_len); - bool - SetPath (const char *path); + bool SetPath(const char *path); private: - // Disallow copy and assignment constructors - CFCBundle(const CFCBundle&); + // Disallow copy and assignment constructors + CFCBundle(const CFCBundle &); - const CFCBundle& - operator=(const CFCBundle&); + const CFCBundle &operator=(const CFCBundle &); }; #endif // #ifndef CoreFoundationCPP_CFBundle_h_ diff --git a/lldb/source/Host/macosx/cfcpp/CFCData.cpp b/lldb/source/Host/macosx/cfcpp/CFCData.cpp index 4f49368ad8a..95cadede8ff 100644 --- a/lldb/source/Host/macosx/cfcpp/CFCData.cpp +++ b/lldb/source/Host/macosx/cfcpp/CFCData.cpp @@ -12,71 +12,55 @@ //---------------------------------------------------------------------- // CFCData constructor //---------------------------------------------------------------------- -CFCData::CFCData(CFDataRef data) : - CFCReleaser<CFDataRef>(data) -{ - -} +CFCData::CFCData(CFDataRef data) : CFCReleaser<CFDataRef>(data) {} //---------------------------------------------------------------------- // CFCData copy constructor //---------------------------------------------------------------------- -CFCData::CFCData(const CFCData& rhs) : - CFCReleaser<CFDataRef>(rhs) -{ - -} +CFCData::CFCData(const CFCData &rhs) : CFCReleaser<CFDataRef>(rhs) {} //---------------------------------------------------------------------- // CFCData copy constructor //---------------------------------------------------------------------- -CFCData& -CFCData::operator=(const CFCData& rhs) +CFCData &CFCData::operator=(const CFCData &rhs) { - if (this != &rhs) - *this = rhs; - return *this; + if (this != &rhs) + *this = rhs; + return *this; } //---------------------------------------------------------------------- // Destructor //---------------------------------------------------------------------- -CFCData::~CFCData() -{ -} - +CFCData::~CFCData() {} -CFIndex -CFCData::GetLength() const -{ - CFDataRef data = get(); - if (data) - return CFDataGetLength (data); - return 0; +CFIndex CFCData::GetLength() const { + CFDataRef data = get(); + if (data) + return CFDataGetLength(data); + return 0; } - -const uint8_t* -CFCData::GetBytePtr() const -{ - CFDataRef data = get(); - if (data) - return CFDataGetBytePtr (data); - return NULL; +const uint8_t *CFCData::GetBytePtr() const { + CFDataRef data = get(); + if (data) + return CFDataGetBytePtr(data); + return NULL; } -CFDataRef -CFCData::Serialize(CFPropertyListRef plist, CFPropertyListFormat format) -{ - CFAllocatorRef alloc = kCFAllocatorDefault; - reset(); - CFCReleaser<CFWriteStreamRef> stream (::CFWriteStreamCreateWithAllocatedBuffers (alloc, alloc)); - ::CFWriteStreamOpen (stream.get()); - CFIndex len = ::CFPropertyListWriteToStream (plist, stream.get(), format, NULL); - if (len > 0) - reset((CFDataRef)::CFWriteStreamCopyProperty (stream.get(), kCFStreamPropertyDataWritten)); - ::CFWriteStreamClose (stream.get()); - return get(); +CFDataRef CFCData::Serialize(CFPropertyListRef plist, + CFPropertyListFormat format) { + CFAllocatorRef alloc = kCFAllocatorDefault; + reset(); + CFCReleaser<CFWriteStreamRef> stream( + ::CFWriteStreamCreateWithAllocatedBuffers(alloc, alloc)); + ::CFWriteStreamOpen(stream.get()); + CFIndex len = + ::CFPropertyListWriteToStream(plist, stream.get(), format, NULL); + if (len > 0) + reset((CFDataRef)::CFWriteStreamCopyProperty(stream.get(), + kCFStreamPropertyDataWritten)); + ::CFWriteStreamClose(stream.get()); + return get(); } - diff --git a/lldb/source/Host/macosx/cfcpp/CFCData.h b/lldb/source/Host/macosx/cfcpp/CFCData.h index 6a718f54c05..e89d7bec783 100644 --- a/lldb/source/Host/macosx/cfcpp/CFCData.h +++ b/lldb/source/Host/macosx/cfcpp/CFCData.h @@ -12,24 +12,24 @@ #include "CFCReleaser.h" -class CFCData : public CFCReleaser<CFDataRef> -{ +class CFCData : public CFCReleaser<CFDataRef> { public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - CFCData(CFDataRef data = NULL); - CFCData(const CFCData& rhs); - CFCData& operator=(const CFCData& rhs); - virtual ~CFCData(); + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + CFCData(CFDataRef data = NULL); + CFCData(const CFCData &rhs); + CFCData &operator=(const CFCData &rhs); + virtual ~CFCData(); + + CFDataRef Serialize(CFPropertyListRef plist, CFPropertyListFormat format); + const uint8_t *GetBytePtr() const; + CFIndex GetLength() const; - CFDataRef Serialize(CFPropertyListRef plist, CFPropertyListFormat format); - const uint8_t* GetBytePtr () const; - CFIndex GetLength () const; protected: - //------------------------------------------------------------------ - // Classes that inherit from CFCData can see and modify these - //------------------------------------------------------------------ + //------------------------------------------------------------------ + // Classes that inherit from CFCData can see and modify these + //------------------------------------------------------------------ }; #endif // #ifndef CoreFoundationCPP_CFData_h_ diff --git a/lldb/source/Host/macosx/cfcpp/CFCMutableArray.cpp b/lldb/source/Host/macosx/cfcpp/CFCMutableArray.cpp index c3c0a11193a..0b6258315eb 100644 --- a/lldb/source/Host/macosx/cfcpp/CFCMutableArray.cpp +++ b/lldb/source/Host/macosx/cfcpp/CFCMutableArray.cpp @@ -13,154 +13,128 @@ //---------------------------------------------------------------------- // CFCString constructor //---------------------------------------------------------------------- -CFCMutableArray::CFCMutableArray(CFMutableArrayRef s) : - CFCReleaser<CFMutableArrayRef> (s) -{ -} +CFCMutableArray::CFCMutableArray(CFMutableArrayRef s) + : CFCReleaser<CFMutableArrayRef>(s) {} //---------------------------------------------------------------------- // CFCMutableArray copy constructor //---------------------------------------------------------------------- -CFCMutableArray::CFCMutableArray(const CFCMutableArray& rhs) : - CFCReleaser<CFMutableArrayRef> (rhs) // NOTE: this won't make a copy of the array, just add a new reference to it -{ -} +CFCMutableArray::CFCMutableArray(const CFCMutableArray &rhs) + : CFCReleaser<CFMutableArrayRef>(rhs) // NOTE: this won't make a copy of the + // array, just add a new reference to + // it +{} //---------------------------------------------------------------------- // CFCMutableArray copy constructor //---------------------------------------------------------------------- -CFCMutableArray& -CFCMutableArray::operator=(const CFCMutableArray& rhs) -{ - if (this != &rhs) - *this = rhs; // NOTE: this operator won't make a copy of the array, just add a new reference to it - return *this; +CFCMutableArray &CFCMutableArray::operator=(const CFCMutableArray &rhs) { + if (this != &rhs) + *this = rhs; // NOTE: this operator won't make a copy of the array, just add + // a new reference to it + return *this; } //---------------------------------------------------------------------- // Destructor //---------------------------------------------------------------------- -CFCMutableArray::~CFCMutableArray() -{ -} +CFCMutableArray::~CFCMutableArray() {} - -CFIndex -CFCMutableArray::GetCount() const -{ - CFMutableArrayRef array = get(); - if (array) - return ::CFArrayGetCount (array); - return 0; +CFIndex CFCMutableArray::GetCount() const { + CFMutableArrayRef array = get(); + if (array) + return ::CFArrayGetCount(array); + return 0; } -CFIndex -CFCMutableArray::GetCountOfValue(CFRange range, const void *value) const -{ - CFMutableArrayRef array = get(); - if (array) - return ::CFArrayGetCountOfValue (array, range, value); - return 0; +CFIndex CFCMutableArray::GetCountOfValue(CFRange range, + const void *value) const { + CFMutableArrayRef array = get(); + if (array) + return ::CFArrayGetCountOfValue(array, range, value); + return 0; } -CFIndex -CFCMutableArray::GetCountOfValue(const void *value) const -{ - CFMutableArrayRef array = get(); - if (array) - return ::CFArrayGetCountOfValue (array, CFRangeMake(0, GetCount()), value); - return 0; +CFIndex CFCMutableArray::GetCountOfValue(const void *value) const { + CFMutableArrayRef array = get(); + if (array) + return ::CFArrayGetCountOfValue(array, CFRangeMake(0, GetCount()), value); + return 0; } -const void * -CFCMutableArray::GetValueAtIndex(CFIndex idx) const -{ - CFMutableArrayRef array = get(); - if (array) - { - const CFIndex num_array_items = ::CFArrayGetCount (array); - if (0 <= idx && idx < num_array_items) - { - return ::CFArrayGetValueAtIndex (array, idx); - } +const void *CFCMutableArray::GetValueAtIndex(CFIndex idx) const { + CFMutableArrayRef array = get(); + if (array) { + const CFIndex num_array_items = ::CFArrayGetCount(array); + if (0 <= idx && idx < num_array_items) { + return ::CFArrayGetValueAtIndex(array, idx); } - return NULL; + } + return NULL; } -bool -CFCMutableArray::SetValueAtIndex(CFIndex idx, const void *value) -{ - CFMutableArrayRef array = get(); - if (array != NULL) - { - const CFIndex num_array_items = ::CFArrayGetCount (array); - if (0 <= idx && idx < num_array_items) - { - ::CFArraySetValueAtIndex (array, idx, value); - return true; - } +bool CFCMutableArray::SetValueAtIndex(CFIndex idx, const void *value) { + CFMutableArrayRef array = get(); + if (array != NULL) { + const CFIndex num_array_items = ::CFArrayGetCount(array); + if (0 <= idx && idx < num_array_items) { + ::CFArraySetValueAtIndex(array, idx, value); + return true; } - return false; + } + return false; } - -bool -CFCMutableArray::AppendValue(const void *value, bool can_create) -{ - CFMutableArrayRef array = get(); - if (array == NULL) - { - if (can_create == false) - return false; - array = ::CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - reset ( array ); - } - if (array != NULL) - { - ::CFArrayAppendValue(array, value); - return true; - } - return false; +bool CFCMutableArray::AppendValue(const void *value, bool can_create) { + CFMutableArrayRef array = get(); + if (array == NULL) { + if (can_create == false) + return false; + array = + ::CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); + reset(array); + } + if (array != NULL) { + ::CFArrayAppendValue(array, value); + return true; + } + return false; } - -bool -CFCMutableArray::AppendCStringAsCFString (const char *s, CFStringEncoding encoding, bool can_create) -{ - CFMutableArrayRef array = get(); - if (array == NULL) - { - if (can_create == false) - return false; - array = ::CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - reset ( array ); - } - if (array != NULL) - { - CFCString cf_str (s, encoding); - ::CFArrayAppendValue (array, cf_str.get()); - return true; - } - return false; +bool CFCMutableArray::AppendCStringAsCFString(const char *s, + CFStringEncoding encoding, + bool can_create) { + CFMutableArrayRef array = get(); + if (array == NULL) { + if (can_create == false) + return false; + array = + ::CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); + reset(array); + } + if (array != NULL) { + CFCString cf_str(s, encoding); + ::CFArrayAppendValue(array, cf_str.get()); + return true; + } + return false; } -bool -CFCMutableArray::AppendFileSystemRepresentationAsCFString (const char *s, bool can_create) -{ - CFMutableArrayRef array = get(); - if (array == NULL) - { - if (can_create == false) - return false; - array = ::CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - reset ( array ); - } - if (array != NULL) - { - CFCString cf_path; - cf_path.SetFileSystemRepresentation(s); - ::CFArrayAppendValue (array, cf_path.get()); - return true; - } - return false; +bool CFCMutableArray::AppendFileSystemRepresentationAsCFString( + const char *s, bool can_create) { + CFMutableArrayRef array = get(); + if (array == NULL) { + if (can_create == false) + return false; + array = + ::CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); + reset(array); + } + if (array != NULL) { + CFCString cf_path; + cf_path.SetFileSystemRepresentation(s); + ::CFArrayAppendValue(array, cf_path.get()); + return true; + } + return false; } diff --git a/lldb/source/Host/macosx/cfcpp/CFCMutableArray.h b/lldb/source/Host/macosx/cfcpp/CFCMutableArray.h index f78cd92ffab..23d1f932bfc 100644 --- a/lldb/source/Host/macosx/cfcpp/CFCMutableArray.h +++ b/lldb/source/Host/macosx/cfcpp/CFCMutableArray.h @@ -12,28 +12,35 @@ #include "CFCReleaser.h" -class CFCMutableArray : public CFCReleaser<CFMutableArrayRef> -{ +class CFCMutableArray : public CFCReleaser<CFMutableArrayRef> { public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - CFCMutableArray(CFMutableArrayRef array = NULL); - CFCMutableArray(const CFCMutableArray& rhs); // This will copy the array contents into a new array - CFCMutableArray& operator=(const CFCMutableArray& rhs); // This will re-use the same array and just bump the ref count - virtual ~CFCMutableArray(); + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + CFCMutableArray(CFMutableArrayRef array = NULL); + CFCMutableArray(const CFCMutableArray &rhs); // This will copy the array + // contents into a new array + CFCMutableArray &operator=(const CFCMutableArray &rhs); // This will re-use + // the same array and + // just bump the ref + // count + virtual ~CFCMutableArray(); - CFIndex GetCount() const; - CFIndex GetCountOfValue(const void *value) const; - CFIndex GetCountOfValue(CFRange range, const void *value) const; - const void * GetValueAtIndex(CFIndex idx) const; - bool SetValueAtIndex(CFIndex idx, const void *value); - bool AppendValue(const void *value, bool can_create = true); // Appends value and optionally creates a CFCMutableArray if this class doesn't contain one - bool AppendCStringAsCFString (const char *cstr, - CFStringEncoding encoding = kCFStringEncodingUTF8, - bool can_create = true); - bool AppendFileSystemRepresentationAsCFString (const char *s, - bool can_create = true); + CFIndex GetCount() const; + CFIndex GetCountOfValue(const void *value) const; + CFIndex GetCountOfValue(CFRange range, const void *value) const; + const void *GetValueAtIndex(CFIndex idx) const; + bool SetValueAtIndex(CFIndex idx, const void *value); + bool AppendValue(const void *value, + bool can_create = true); // Appends value and optionally + // creates a CFCMutableArray if this + // class doesn't contain one + bool + AppendCStringAsCFString(const char *cstr, + CFStringEncoding encoding = kCFStringEncodingUTF8, + bool can_create = true); + bool AppendFileSystemRepresentationAsCFString(const char *s, + bool can_create = true); }; #endif // #ifndef CoreFoundationCPP_CFMutableArray_h_ diff --git a/lldb/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp b/lldb/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp index bce023bfd61..201ec9a8f5c 100644 --- a/lldb/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp +++ b/lldb/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp @@ -12,518 +12,458 @@ //---------------------------------------------------------------------- // CFCString constructor //---------------------------------------------------------------------- -CFCMutableDictionary::CFCMutableDictionary(CFMutableDictionaryRef s) : - CFCReleaser<CFMutableDictionaryRef> (s) -{ -} +CFCMutableDictionary::CFCMutableDictionary(CFMutableDictionaryRef s) + : CFCReleaser<CFMutableDictionaryRef>(s) {} //---------------------------------------------------------------------- // CFCMutableDictionary copy constructor //---------------------------------------------------------------------- -CFCMutableDictionary::CFCMutableDictionary(const CFCMutableDictionary& rhs) : - CFCReleaser<CFMutableDictionaryRef> (rhs) -{ -} +CFCMutableDictionary::CFCMutableDictionary(const CFCMutableDictionary &rhs) + : CFCReleaser<CFMutableDictionaryRef>(rhs) {} //---------------------------------------------------------------------- // CFCMutableDictionary copy constructor //---------------------------------------------------------------------- -const CFCMutableDictionary& -CFCMutableDictionary::operator=(const CFCMutableDictionary& rhs) -{ - if (this != &rhs) - *this = rhs; - return *this; +const CFCMutableDictionary &CFCMutableDictionary:: +operator=(const CFCMutableDictionary &rhs) { + if (this != &rhs) + *this = rhs; + return *this; } //---------------------------------------------------------------------- // Destructor //---------------------------------------------------------------------- -CFCMutableDictionary::~CFCMutableDictionary() -{ -} - +CFCMutableDictionary::~CFCMutableDictionary() {} -CFIndex -CFCMutableDictionary::GetCount() const -{ - CFMutableDictionaryRef dict = get(); - if (dict) - return ::CFDictionaryGetCount (dict); - return 0; +CFIndex CFCMutableDictionary::GetCount() const { + CFMutableDictionaryRef dict = get(); + if (dict) + return ::CFDictionaryGetCount(dict); + return 0; } -CFIndex -CFCMutableDictionary::GetCountOfKey(const void *key) const +CFIndex CFCMutableDictionary::GetCountOfKey(const void *key) const { - CFMutableDictionaryRef dict = get(); - if (dict) - return ::CFDictionaryGetCountOfKey (dict, key); - return 0; + CFMutableDictionaryRef dict = get(); + if (dict) + return ::CFDictionaryGetCountOfKey(dict, key); + return 0; } -CFIndex -CFCMutableDictionary::GetCountOfValue(const void *value) const +CFIndex CFCMutableDictionary::GetCountOfValue(const void *value) const { - CFMutableDictionaryRef dict = get(); - if (dict) - return ::CFDictionaryGetCountOfValue (dict, value); - return 0; + CFMutableDictionaryRef dict = get(); + if (dict) + return ::CFDictionaryGetCountOfValue(dict, value); + return 0; } -void -CFCMutableDictionary::GetKeysAndValues(const void **keys, const void **values) const -{ - CFMutableDictionaryRef dict = get(); - if (dict) - ::CFDictionaryGetKeysAndValues (dict, keys, values); +void CFCMutableDictionary::GetKeysAndValues(const void **keys, + const void **values) const { + CFMutableDictionaryRef dict = get(); + if (dict) + ::CFDictionaryGetKeysAndValues(dict, keys, values); } - -const void * -CFCMutableDictionary::GetValue(const void *key) const +const void *CFCMutableDictionary::GetValue(const void *key) const { - CFMutableDictionaryRef dict = get(); - if (dict) - return ::CFDictionaryGetValue (dict, key); - return NULL; + CFMutableDictionaryRef dict = get(); + if (dict) + return ::CFDictionaryGetValue(dict, key); + return NULL; } Boolean -CFCMutableDictionary::GetValueIfPresent(const void *key, const void **value_handle) const -{ - CFMutableDictionaryRef dict = get(); - if (dict) - return ::CFDictionaryGetValueIfPresent (dict, key, value_handle); - return false; -} - - -CFMutableDictionaryRef -CFCMutableDictionary::Dictionary(bool can_create) -{ - CFMutableDictionaryRef dict = get(); - if (can_create && dict == NULL) - { - dict = ::CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - reset ( dict ); +CFCMutableDictionary::GetValueIfPresent(const void *key, + const void **value_handle) const { + CFMutableDictionaryRef dict = get(); + if (dict) + return ::CFDictionaryGetValueIfPresent(dict, key, value_handle); + return false; +} + +CFMutableDictionaryRef CFCMutableDictionary::Dictionary(bool can_create) { + CFMutableDictionaryRef dict = get(); + if (can_create && dict == NULL) { + dict = ::CFDictionaryCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + reset(dict); + } + return dict; +} + +bool CFCMutableDictionary::AddValue(CFStringRef key, const void *value, + bool can_create) { + CFMutableDictionaryRef dict = Dictionary(can_create); + if (dict != NULL) { + // Let the dictionary own the CFNumber + ::CFDictionaryAddValue(dict, key, value); + return true; + } + return false; +} + +bool CFCMutableDictionary::SetValue(CFStringRef key, const void *value, + bool can_create) { + CFMutableDictionaryRef dict = Dictionary(can_create); + if (dict != NULL) { + // Let the dictionary own the CFNumber + ::CFDictionarySetValue(dict, key, value); + return true; + } + return false; +} + +bool CFCMutableDictionary::AddValueSInt8(CFStringRef key, int8_t value, + bool can_create) { + CFMutableDictionaryRef dict = Dictionary(can_create); + if (dict != NULL) { + CFCReleaser<CFNumberRef> cf_number( + ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt8Type, &value)); + if (cf_number.get()) { + // Let the dictionary own the CFNumber + ::CFDictionaryAddValue(dict, key, cf_number.get()); + return true; } - return dict; -} - -bool -CFCMutableDictionary::AddValue(CFStringRef key, const void *value, bool can_create) -{ - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) - { - // Let the dictionary own the CFNumber - ::CFDictionaryAddValue (dict, key, value); - return true; + } + return false; +} + +bool CFCMutableDictionary::SetValueSInt8(CFStringRef key, int8_t value, + bool can_create) { + CFMutableDictionaryRef dict = Dictionary(can_create); + if (dict != NULL) { + CFCReleaser<CFNumberRef> cf_number( + ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt8Type, &value)); + if (cf_number.get()) { + // Let the dictionary own the CFNumber + ::CFDictionarySetValue(dict, key, cf_number.get()); + return true; } - return false; -} - -bool -CFCMutableDictionary::SetValue(CFStringRef key, const void *value, bool can_create) -{ - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) - { - // Let the dictionary own the CFNumber - ::CFDictionarySetValue (dict, key, value); - return true; + } + return false; +} + +bool CFCMutableDictionary::AddValueSInt16(CFStringRef key, int16_t value, + bool can_create) { + CFMutableDictionaryRef dict = Dictionary(can_create); + if (dict != NULL) { + CFCReleaser<CFNumberRef> cf_number( + ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &value)); + if (cf_number.get()) { + // Let the dictionary own the CFNumber + ::CFDictionaryAddValue(dict, key, cf_number.get()); + return true; } - return false; -} - -bool -CFCMutableDictionary::AddValueSInt8(CFStringRef key, int8_t value, bool can_create) -{ - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) - { - CFCReleaser<CFNumberRef> cf_number(::CFNumberCreate (kCFAllocatorDefault, kCFNumberSInt8Type, &value)); - if (cf_number.get()) - { - // Let the dictionary own the CFNumber - ::CFDictionaryAddValue (dict, key, cf_number.get()); - return true; - } + } + return false; +} + +bool CFCMutableDictionary::SetValueSInt16(CFStringRef key, int16_t value, + bool can_create) { + CFMutableDictionaryRef dict = Dictionary(can_create); + if (dict != NULL) { + CFCReleaser<CFNumberRef> cf_number( + ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &value)); + if (cf_number.get()) { + // Let the dictionary own the CFNumber + ::CFDictionarySetValue(dict, key, cf_number.get()); + return true; } - return false; -} - -bool -CFCMutableDictionary::SetValueSInt8(CFStringRef key, int8_t value, bool can_create) -{ - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) - { - CFCReleaser<CFNumberRef> cf_number(::CFNumberCreate (kCFAllocatorDefault, kCFNumberSInt8Type, &value)); - if (cf_number.get()) - { - // Let the dictionary own the CFNumber - ::CFDictionarySetValue (dict, key, cf_number.get()); - return true; - } + } + return false; +} + +bool CFCMutableDictionary::AddValueSInt32(CFStringRef key, int32_t value, + bool can_create) { + CFMutableDictionaryRef dict = Dictionary(can_create); + if (dict != NULL) { + CFCReleaser<CFNumberRef> cf_number( + ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value)); + if (cf_number.get()) { + // Let the dictionary own the CFNumber + ::CFDictionaryAddValue(dict, key, cf_number.get()); + return true; } - return false; -} - -bool -CFCMutableDictionary::AddValueSInt16(CFStringRef key, int16_t value, bool can_create) -{ - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) - { - CFCReleaser<CFNumberRef> cf_number(::CFNumberCreate (kCFAllocatorDefault, kCFNumberSInt16Type, &value)); - if (cf_number.get()) - { - // Let the dictionary own the CFNumber - ::CFDictionaryAddValue (dict, key, cf_number.get()); - return true; - } + } + return false; +} + +bool CFCMutableDictionary::SetValueSInt32(CFStringRef key, int32_t value, + bool can_create) { + CFMutableDictionaryRef dict = Dictionary(can_create); + if (dict != NULL) { + CFCReleaser<CFNumberRef> cf_number( + ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value)); + if (cf_number.get()) { + // Let the dictionary own the CFNumber + ::CFDictionarySetValue(dict, key, cf_number.get()); + return true; } - return false; -} - -bool -CFCMutableDictionary::SetValueSInt16(CFStringRef key, int16_t value, bool can_create) -{ - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) - { - CFCReleaser<CFNumberRef> cf_number(::CFNumberCreate (kCFAllocatorDefault, kCFNumberSInt16Type, &value)); - if (cf_number.get()) - { - // Let the dictionary own the CFNumber - ::CFDictionarySetValue (dict, key, cf_number.get()); - return true; - } + } + return false; +} + +bool CFCMutableDictionary::AddValueSInt64(CFStringRef key, int64_t value, + bool can_create) { + CFMutableDictionaryRef dict = Dictionary(can_create); + if (dict != NULL) { + CFCReleaser<CFNumberRef> cf_number( + ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &value)); + if (cf_number.get()) { + // Let the dictionary own the CFNumber + ::CFDictionaryAddValue(dict, key, cf_number.get()); + return true; } - return false; -} - -bool -CFCMutableDictionary::AddValueSInt32(CFStringRef key, int32_t value, bool can_create) -{ - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) - { - CFCReleaser<CFNumberRef> cf_number(::CFNumberCreate (kCFAllocatorDefault, kCFNumberSInt32Type, &value)); - if (cf_number.get()) - { - // Let the dictionary own the CFNumber - ::CFDictionaryAddValue (dict, key, cf_number.get()); - return true; - } + } + return false; +} + +bool CFCMutableDictionary::SetValueSInt64(CFStringRef key, int64_t value, + bool can_create) { + CFMutableDictionaryRef dict = Dictionary(can_create); + if (dict != NULL) { + CFCReleaser<CFNumberRef> cf_number( + ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &value)); + if (cf_number.get()) { + // Let the dictionary own the CFNumber + ::CFDictionarySetValue(dict, key, cf_number.get()); + return true; } - return false; -} - -bool -CFCMutableDictionary::SetValueSInt32(CFStringRef key, int32_t value, bool can_create) -{ - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) - { - CFCReleaser<CFNumberRef> cf_number(::CFNumberCreate (kCFAllocatorDefault, kCFNumberSInt32Type, &value)); - if (cf_number.get()) - { - // Let the dictionary own the CFNumber - ::CFDictionarySetValue (dict, key, cf_number.get()); - return true; - } + } + return false; +} + +bool CFCMutableDictionary::AddValueUInt8(CFStringRef key, uint8_t value, + bool can_create) { + CFMutableDictionaryRef dict = Dictionary(can_create); + if (dict != NULL) { + // Have to promote to the next size type so things don't appear negative of + // the MSBit is set... + int16_t sval = value; + CFCReleaser<CFNumberRef> cf_number( + ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &sval)); + if (cf_number.get()) { + // Let the dictionary own the CFNumber + ::CFDictionaryAddValue(dict, key, cf_number.get()); + return true; } - return false; -} - -bool -CFCMutableDictionary::AddValueSInt64(CFStringRef key, int64_t value, bool can_create) -{ - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) - { - CFCReleaser<CFNumberRef> cf_number(::CFNumberCreate (kCFAllocatorDefault, kCFNumberSInt64Type, &value)); - if (cf_number.get()) - { - // Let the dictionary own the CFNumber - ::CFDictionaryAddValue (dict, key, cf_number.get()); - return true; - } + } + return false; +} + +bool CFCMutableDictionary::SetValueUInt8(CFStringRef key, uint8_t value, + bool can_create) { + CFMutableDictionaryRef dict = Dictionary(can_create); + if (dict != NULL) { + // Have to promote to the next size type so things don't appear negative of + // the MSBit is set... + int16_t sval = value; + CFCReleaser<CFNumberRef> cf_number( + ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &sval)); + if (cf_number.get()) { + // Let the dictionary own the CFNumber + ::CFDictionarySetValue(dict, key, cf_number.get()); + return true; } - return false; -} - -bool -CFCMutableDictionary::SetValueSInt64(CFStringRef key, int64_t value, bool can_create) -{ - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) - { - CFCReleaser<CFNumberRef> cf_number(::CFNumberCreate (kCFAllocatorDefault, kCFNumberSInt64Type, &value)); - if (cf_number.get()) - { - // Let the dictionary own the CFNumber - ::CFDictionarySetValue (dict, key, cf_number.get()); - return true; - } + } + return false; +} + +bool CFCMutableDictionary::AddValueUInt16(CFStringRef key, uint16_t value, + bool can_create) { + CFMutableDictionaryRef dict = Dictionary(can_create); + if (dict != NULL) { + // Have to promote to the next size type so things don't appear negative of + // the MSBit is set... + int32_t sval = value; + CFCReleaser<CFNumberRef> cf_number( + ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &sval)); + if (cf_number.get()) { + // Let the dictionary own the CFNumber + ::CFDictionaryAddValue(dict, key, cf_number.get()); + return true; } - return false; -} - -bool -CFCMutableDictionary::AddValueUInt8(CFStringRef key, uint8_t value, bool can_create) -{ - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) - { - // Have to promote to the next size type so things don't appear negative of the MSBit is set... - int16_t sval = value; - CFCReleaser<CFNumberRef> cf_number(::CFNumberCreate (kCFAllocatorDefault, kCFNumberSInt16Type, &sval)); - if (cf_number.get()) - { - // Let the dictionary own the CFNumber - ::CFDictionaryAddValue (dict, key, cf_number.get()); - return true; - } + } + return false; +} + +bool CFCMutableDictionary::SetValueUInt16(CFStringRef key, uint16_t value, + bool can_create) { + CFMutableDictionaryRef dict = Dictionary(can_create); + if (dict != NULL) { + // Have to promote to the next size type so things don't appear negative of + // the MSBit is set... + int32_t sval = value; + CFCReleaser<CFNumberRef> cf_number( + ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &sval)); + if (cf_number.get()) { + // Let the dictionary own the CFNumber + ::CFDictionarySetValue(dict, key, cf_number.get()); + return true; } - return false; -} - -bool -CFCMutableDictionary::SetValueUInt8(CFStringRef key, uint8_t value, bool can_create) -{ - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) - { - // Have to promote to the next size type so things don't appear negative of the MSBit is set... - int16_t sval = value; - CFCReleaser<CFNumberRef> cf_number(::CFNumberCreate (kCFAllocatorDefault, kCFNumberSInt16Type, &sval)); - if (cf_number.get()) - { - // Let the dictionary own the CFNumber - ::CFDictionarySetValue (dict, key, cf_number.get()); - return true; - } + } + return false; +} + +bool CFCMutableDictionary::AddValueUInt32(CFStringRef key, uint32_t value, + bool can_create) { + CFMutableDictionaryRef dict = Dictionary(can_create); + if (dict != NULL) { + // Have to promote to the next size type so things don't appear negative of + // the MSBit is set... + int64_t sval = value; + CFCReleaser<CFNumberRef> cf_number( + ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &sval)); + if (cf_number.get()) { + // Let the dictionary own the CFNumber + ::CFDictionaryAddValue(dict, key, cf_number.get()); + return true; } - return false; -} - - -bool -CFCMutableDictionary::AddValueUInt16(CFStringRef key, uint16_t value, bool can_create) -{ - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) - { - // Have to promote to the next size type so things don't appear negative of the MSBit is set... - int32_t sval = value; - CFCReleaser<CFNumberRef> cf_number(::CFNumberCreate (kCFAllocatorDefault, kCFNumberSInt32Type, &sval)); - if (cf_number.get()) - { - // Let the dictionary own the CFNumber - ::CFDictionaryAddValue (dict, key, cf_number.get()); - return true; - } + } + return false; +} + +bool CFCMutableDictionary::SetValueUInt32(CFStringRef key, uint32_t value, + bool can_create) { + CFMutableDictionaryRef dict = Dictionary(can_create); + if (dict != NULL) { + // Have to promote to the next size type so things don't appear negative of + // the MSBit is set... + int64_t sval = value; + CFCReleaser<CFNumberRef> cf_number( + ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &sval)); + if (cf_number.get()) { + // Let the dictionary own the CFNumber + ::CFDictionarySetValue(dict, key, cf_number.get()); + return true; } - return false; -} - -bool -CFCMutableDictionary::SetValueUInt16(CFStringRef key, uint16_t value, bool can_create) -{ - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) - { - // Have to promote to the next size type so things don't appear negative of the MSBit is set... - int32_t sval = value; - CFCReleaser<CFNumberRef> cf_number(::CFNumberCreate (kCFAllocatorDefault, kCFNumberSInt32Type, &sval)); - if (cf_number.get()) - { - // Let the dictionary own the CFNumber - ::CFDictionarySetValue (dict, key, cf_number.get()); - return true; - } - } - return false; -} - -bool -CFCMutableDictionary::AddValueUInt32(CFStringRef key, uint32_t value, bool can_create) -{ - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) - { - // Have to promote to the next size type so things don't appear negative of the MSBit is set... - int64_t sval = value; - CFCReleaser<CFNumberRef> cf_number(::CFNumberCreate (kCFAllocatorDefault, kCFNumberSInt64Type, &sval)); - if (cf_number.get()) - { - // Let the dictionary own the CFNumber - ::CFDictionaryAddValue (dict, key, cf_number.get()); - return true; - } - } - return false; -} - -bool -CFCMutableDictionary::SetValueUInt32(CFStringRef key, uint32_t value, bool can_create) -{ - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) - { - // Have to promote to the next size type so things don't appear negative of the MSBit is set... - int64_t sval = value; - CFCReleaser<CFNumberRef> cf_number(::CFNumberCreate (kCFAllocatorDefault, kCFNumberSInt64Type, &sval)); - if (cf_number.get()) - { - // Let the dictionary own the CFNumber - ::CFDictionarySetValue (dict, key, cf_number.get()); - return true; - } - } - return false; -} - - -bool -CFCMutableDictionary::AddValueUInt64(CFStringRef key, uint64_t value, bool can_create) -{ - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) - { - // The number may appear negative if the MSBit is set in "value". Due to a limitation of - // CFNumber, there isn't a way to have it show up otherwise as of this writing. - CFCReleaser<CFNumberRef> cf_number(::CFNumberCreate (kCFAllocatorDefault, kCFNumberSInt64Type, &value)); - if (cf_number.get()) - { - // Let the dictionary own the CFNumber - ::CFDictionaryAddValue (dict, key, cf_number.get()); - return true; - } + } + return false; +} + +bool CFCMutableDictionary::AddValueUInt64(CFStringRef key, uint64_t value, + bool can_create) { + CFMutableDictionaryRef dict = Dictionary(can_create); + if (dict != NULL) { + // The number may appear negative if the MSBit is set in "value". Due to a + // limitation of + // CFNumber, there isn't a way to have it show up otherwise as of this + // writing. + CFCReleaser<CFNumberRef> cf_number( + ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &value)); + if (cf_number.get()) { + // Let the dictionary own the CFNumber + ::CFDictionaryAddValue(dict, key, cf_number.get()); + return true; } - return false; -} - - -bool -CFCMutableDictionary::SetValueUInt64(CFStringRef key, uint64_t value, bool can_create) -{ - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) - { - // The number may appear negative if the MSBit is set in "value". Due to a limitation of - // CFNumber, there isn't a way to have it show up otherwise as of this writing. - CFCReleaser<CFNumberRef> cf_number(::CFNumberCreate (kCFAllocatorDefault, kCFNumberSInt64Type, &value)); - if (cf_number.get()) - { - // Let the dictionary own the CFNumber - ::CFDictionarySetValue (dict, key, cf_number.get()); - return true; - } + } + return false; +} + +bool CFCMutableDictionary::SetValueUInt64(CFStringRef key, uint64_t value, + bool can_create) { + CFMutableDictionaryRef dict = Dictionary(can_create); + if (dict != NULL) { + // The number may appear negative if the MSBit is set in "value". Due to a + // limitation of + // CFNumber, there isn't a way to have it show up otherwise as of this + // writing. + CFCReleaser<CFNumberRef> cf_number( + ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &value)); + if (cf_number.get()) { + // Let the dictionary own the CFNumber + ::CFDictionarySetValue(dict, key, cf_number.get()); + return true; } - return false; -} - -bool -CFCMutableDictionary::AddValueDouble(CFStringRef key, double value, bool can_create) -{ - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) - { - // The number may appear negative if the MSBit is set in "value". Due to a limitation of - // CFNumber, there isn't a way to have it show up otherwise as of this writing. - CFCReleaser<CFNumberRef> cf_number(::CFNumberCreate (kCFAllocatorDefault, kCFNumberDoubleType, &value)); - if (cf_number.get()) - { - // Let the dictionary own the CFNumber - ::CFDictionaryAddValue (dict, key, cf_number.get()); - return true; - } + } + return false; +} + +bool CFCMutableDictionary::AddValueDouble(CFStringRef key, double value, + bool can_create) { + CFMutableDictionaryRef dict = Dictionary(can_create); + if (dict != NULL) { + // The number may appear negative if the MSBit is set in "value". Due to a + // limitation of + // CFNumber, there isn't a way to have it show up otherwise as of this + // writing. + CFCReleaser<CFNumberRef> cf_number( + ::CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &value)); + if (cf_number.get()) { + // Let the dictionary own the CFNumber + ::CFDictionaryAddValue(dict, key, cf_number.get()); + return true; } - return false; -} - -bool -CFCMutableDictionary::SetValueDouble(CFStringRef key, double value, bool can_create) -{ - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) - { - // The number may appear negative if the MSBit is set in "value". Due to a limitation of - // CFNumber, there isn't a way to have it show up otherwise as of this writing. - CFCReleaser<CFNumberRef> cf_number(::CFNumberCreate (kCFAllocatorDefault, kCFNumberDoubleType, &value)); - if (cf_number.get()) - { - // Let the dictionary own the CFNumber - ::CFDictionarySetValue (dict, key, cf_number.get()); - return true; - } + } + return false; +} + +bool CFCMutableDictionary::SetValueDouble(CFStringRef key, double value, + bool can_create) { + CFMutableDictionaryRef dict = Dictionary(can_create); + if (dict != NULL) { + // The number may appear negative if the MSBit is set in "value". Due to a + // limitation of + // CFNumber, there isn't a way to have it show up otherwise as of this + // writing. + CFCReleaser<CFNumberRef> cf_number( + ::CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &value)); + if (cf_number.get()) { + // Let the dictionary own the CFNumber + ::CFDictionarySetValue(dict, key, cf_number.get()); + return true; } - return false; -} - -bool -CFCMutableDictionary::AddValueCString(CFStringRef key, const char *cstr, bool can_create) -{ - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) - { - CFCString cf_str(cstr, kCFStringEncodingUTF8); - if (cf_str.get()) - { - // Let the dictionary own the CFNumber - ::CFDictionaryAddValue (dict, key, cf_str.get()); - return true; - } + } + return false; +} + +bool CFCMutableDictionary::AddValueCString(CFStringRef key, const char *cstr, + bool can_create) { + CFMutableDictionaryRef dict = Dictionary(can_create); + if (dict != NULL) { + CFCString cf_str(cstr, kCFStringEncodingUTF8); + if (cf_str.get()) { + // Let the dictionary own the CFNumber + ::CFDictionaryAddValue(dict, key, cf_str.get()); + return true; } - return false; -} - -bool -CFCMutableDictionary::SetValueCString(CFStringRef key, const char *cstr, bool can_create) -{ - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) - { - CFCString cf_str(cstr, kCFStringEncodingUTF8); - if (cf_str.get()) - { - // Let the dictionary own the CFNumber - ::CFDictionarySetValue (dict, key, cf_str.get()); - return true; - } + } + return false; +} + +bool CFCMutableDictionary::SetValueCString(CFStringRef key, const char *cstr, + bool can_create) { + CFMutableDictionaryRef dict = Dictionary(can_create); + if (dict != NULL) { + CFCString cf_str(cstr, kCFStringEncodingUTF8); + if (cf_str.get()) { + // Let the dictionary own the CFNumber + ::CFDictionarySetValue(dict, key, cf_str.get()); + return true; } - return false; + } + return false; } - -void -CFCMutableDictionary::RemoveAllValues() -{ - CFMutableDictionaryRef dict = get(); - if (dict) - ::CFDictionaryRemoveAllValues(dict); +void CFCMutableDictionary::RemoveAllValues() { + CFMutableDictionaryRef dict = get(); + if (dict) + ::CFDictionaryRemoveAllValues(dict); } -void -CFCMutableDictionary::RemoveValue(const void *value) -{ - CFMutableDictionaryRef dict = get(); - if (dict) - ::CFDictionaryRemoveValue(dict, value); +void CFCMutableDictionary::RemoveValue(const void *value) { + CFMutableDictionaryRef dict = get(); + if (dict) + ::CFDictionaryRemoveValue(dict, value); } -void -CFCMutableDictionary::ReplaceValue(const void *key, const void *value) -{ - CFMutableDictionaryRef dict = get(); - if (dict) - ::CFDictionaryReplaceValue (dict, key, value); +void CFCMutableDictionary::ReplaceValue(const void *key, const void *value) { + CFMutableDictionaryRef dict = get(); + if (dict) + ::CFDictionaryReplaceValue(dict, key, value); } - diff --git a/lldb/source/Host/macosx/cfcpp/CFCMutableDictionary.h b/lldb/source/Host/macosx/cfcpp/CFCMutableDictionary.h index a1cfb68f569..b30a2e616cd 100644 --- a/lldb/source/Host/macosx/cfcpp/CFCMutableDictionary.h +++ b/lldb/source/Host/macosx/cfcpp/CFCMutableDictionary.h @@ -12,68 +12,64 @@ #include "CFCReleaser.h" -class CFCMutableDictionary : public CFCReleaser<CFMutableDictionaryRef> -{ +class CFCMutableDictionary : public CFCReleaser<CFMutableDictionaryRef> { public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - CFCMutableDictionary(CFMutableDictionaryRef s = NULL); - CFCMutableDictionary(const CFCMutableDictionary& rhs); - virtual ~CFCMutableDictionary(); + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + CFCMutableDictionary(CFMutableDictionaryRef s = NULL); + CFCMutableDictionary(const CFCMutableDictionary &rhs); + virtual ~CFCMutableDictionary(); - //------------------------------------------------------------------ - // Operators - //------------------------------------------------------------------ - const CFCMutableDictionary& - operator=(const CFCMutableDictionary& rhs); - - - CFIndex GetCount() const; - CFIndex GetCountOfKey(const void *value) const; - CFIndex GetCountOfValue(const void *value) const; - void GetKeysAndValues(const void **keys, const void **values) const; - const void * GetValue(const void *key) const; - Boolean GetValueIfPresent(const void *key, const void **value_handle) const; - bool AddValue(CFStringRef key, const void *value, bool can_create = false); - bool SetValue(CFStringRef key, const void *value, bool can_create = false); - bool AddValueSInt8(CFStringRef key, int8_t value, bool can_create = false); - bool SetValueSInt8(CFStringRef key, int8_t value, bool can_create = false); - bool AddValueSInt16(CFStringRef key, int16_t value, bool can_create = false); - bool SetValueSInt16(CFStringRef key, int16_t value, bool can_create = false); - bool AddValueSInt32(CFStringRef key, int32_t value, bool can_create = false); - bool SetValueSInt32(CFStringRef key, int32_t value, bool can_create = false); - bool AddValueSInt64(CFStringRef key, int64_t value, bool can_create = false); - bool SetValueSInt64(CFStringRef key, int64_t value, bool can_create = false); - bool AddValueUInt8(CFStringRef key, uint8_t value, bool can_create = false); - bool SetValueUInt8(CFStringRef key, uint8_t value, bool can_create = false); - bool AddValueUInt16(CFStringRef key, uint16_t value, bool can_create = false); - bool SetValueUInt16(CFStringRef key, uint16_t value, bool can_create = false); - bool AddValueUInt32(CFStringRef key, uint32_t value, bool can_create = false); - bool SetValueUInt32(CFStringRef key, uint32_t value, bool can_create = false); - bool AddValueUInt64(CFStringRef key, uint64_t value, bool can_create = false); - bool SetValueUInt64(CFStringRef key, uint64_t value, bool can_create = false); - bool AddValueDouble(CFStringRef key, double value, bool can_create = false); - bool SetValueDouble(CFStringRef key, double value, bool can_create = false); - bool AddValueCString(CFStringRef key, const char *cstr, bool can_create = false); - bool SetValueCString(CFStringRef key, const char *cstr, bool can_create = false); - void RemoveValue(const void *value); - void ReplaceValue(const void *key, const void *value); - void RemoveAllValues(); - CFMutableDictionaryRef Dictionary(bool can_create); + //------------------------------------------------------------------ + // Operators + //------------------------------------------------------------------ + const CFCMutableDictionary &operator=(const CFCMutableDictionary &rhs); + CFIndex GetCount() const; + CFIndex GetCountOfKey(const void *value) const; + CFIndex GetCountOfValue(const void *value) const; + void GetKeysAndValues(const void **keys, const void **values) const; + const void *GetValue(const void *key) const; + Boolean GetValueIfPresent(const void *key, const void **value_handle) const; + bool AddValue(CFStringRef key, const void *value, bool can_create = false); + bool SetValue(CFStringRef key, const void *value, bool can_create = false); + bool AddValueSInt8(CFStringRef key, int8_t value, bool can_create = false); + bool SetValueSInt8(CFStringRef key, int8_t value, bool can_create = false); + bool AddValueSInt16(CFStringRef key, int16_t value, bool can_create = false); + bool SetValueSInt16(CFStringRef key, int16_t value, bool can_create = false); + bool AddValueSInt32(CFStringRef key, int32_t value, bool can_create = false); + bool SetValueSInt32(CFStringRef key, int32_t value, bool can_create = false); + bool AddValueSInt64(CFStringRef key, int64_t value, bool can_create = false); + bool SetValueSInt64(CFStringRef key, int64_t value, bool can_create = false); + bool AddValueUInt8(CFStringRef key, uint8_t value, bool can_create = false); + bool SetValueUInt8(CFStringRef key, uint8_t value, bool can_create = false); + bool AddValueUInt16(CFStringRef key, uint16_t value, bool can_create = false); + bool SetValueUInt16(CFStringRef key, uint16_t value, bool can_create = false); + bool AddValueUInt32(CFStringRef key, uint32_t value, bool can_create = false); + bool SetValueUInt32(CFStringRef key, uint32_t value, bool can_create = false); + bool AddValueUInt64(CFStringRef key, uint64_t value, bool can_create = false); + bool SetValueUInt64(CFStringRef key, uint64_t value, bool can_create = false); + bool AddValueDouble(CFStringRef key, double value, bool can_create = false); + bool SetValueDouble(CFStringRef key, double value, bool can_create = false); + bool AddValueCString(CFStringRef key, const char *cstr, + bool can_create = false); + bool SetValueCString(CFStringRef key, const char *cstr, + bool can_create = false); + void RemoveValue(const void *value); + void ReplaceValue(const void *key, const void *value); + void RemoveAllValues(); + CFMutableDictionaryRef Dictionary(bool can_create); protected: - //------------------------------------------------------------------ - // Classes that inherit from CFCMutableDictionary can see and modify these - //------------------------------------------------------------------ + //------------------------------------------------------------------ + // Classes that inherit from CFCMutableDictionary can see and modify these + //------------------------------------------------------------------ private: - //------------------------------------------------------------------ - // For CFCMutableDictionary only - //------------------------------------------------------------------ - + //------------------------------------------------------------------ + // For CFCMutableDictionary only + //------------------------------------------------------------------ }; - -#endif // CoreFoundationCPP_CFMutableDictionary_h_ +#endif // CoreFoundationCPP_CFMutableDictionary_h_ diff --git a/lldb/source/Host/macosx/cfcpp/CFCMutableSet.cpp b/lldb/source/Host/macosx/cfcpp/CFCMutableSet.cpp index afc09e180b6..c339e950674 100644 --- a/lldb/source/Host/macosx/cfcpp/CFCMutableSet.cpp +++ b/lldb/source/Host/macosx/cfcpp/CFCMutableSet.cpp @@ -17,98 +17,73 @@ //---------------------------------------------------------------------- // CFCString constructor //---------------------------------------------------------------------- -CFCMutableSet::CFCMutableSet(CFMutableSetRef s) : - CFCReleaser<CFMutableSetRef> (s) -{ -} +CFCMutableSet::CFCMutableSet(CFMutableSetRef s) + : CFCReleaser<CFMutableSetRef>(s) {} //---------------------------------------------------------------------- // CFCMutableSet copy constructor //---------------------------------------------------------------------- -CFCMutableSet::CFCMutableSet(const CFCMutableSet& rhs) : - CFCReleaser<CFMutableSetRef> (rhs) -{ -} +CFCMutableSet::CFCMutableSet(const CFCMutableSet &rhs) + : CFCReleaser<CFMutableSetRef>(rhs) {} //---------------------------------------------------------------------- // CFCMutableSet copy constructor //---------------------------------------------------------------------- -const CFCMutableSet& -CFCMutableSet::operator=(const CFCMutableSet& rhs) -{ - if (this != &rhs) - *this = rhs; - return *this; +const CFCMutableSet &CFCMutableSet::operator=(const CFCMutableSet &rhs) { + if (this != &rhs) + *this = rhs; + return *this; } //---------------------------------------------------------------------- // Destructor //---------------------------------------------------------------------- -CFCMutableSet::~CFCMutableSet() -{ -} +CFCMutableSet::~CFCMutableSet() {} - -CFIndex -CFCMutableSet::GetCount() const -{ - CFMutableSetRef set = get(); - if (set) - return ::CFSetGetCount (set); - return 0; +CFIndex CFCMutableSet::GetCount() const { + CFMutableSetRef set = get(); + if (set) + return ::CFSetGetCount(set); + return 0; } -CFIndex -CFCMutableSet::GetCountOfValue(const void *value) const -{ - CFMutableSetRef set = get(); - if (set) - return ::CFSetGetCountOfValue (set, value); - return 0; +CFIndex CFCMutableSet::GetCountOfValue(const void *value) const { + CFMutableSetRef set = get(); + if (set) + return ::CFSetGetCountOfValue(set, value); + return 0; } -const void * -CFCMutableSet::GetValue(const void *value) const -{ - CFMutableSetRef set = get(); - if (set) - return ::CFSetGetValue(set, value); - return NULL; +const void *CFCMutableSet::GetValue(const void *value) const { + CFMutableSetRef set = get(); + if (set) + return ::CFSetGetValue(set, value); + return NULL; } - -const void * -CFCMutableSet::AddValue(const void *value, bool can_create) -{ - CFMutableSetRef set = get(); - if (set == NULL) - { - if (can_create == false) - return NULL; - set = ::CFSetCreateMutable(kCFAllocatorDefault, 0, &kCFTypeSetCallBacks); - reset ( set ); - } - if (set != NULL) - { - ::CFSetAddValue(set, value); - return value; - } - return NULL; +const void *CFCMutableSet::AddValue(const void *value, bool can_create) { + CFMutableSetRef set = get(); + if (set == NULL) { + if (can_create == false) + return NULL; + set = ::CFSetCreateMutable(kCFAllocatorDefault, 0, &kCFTypeSetCallBacks); + reset(set); + } + if (set != NULL) { + ::CFSetAddValue(set, value); + return value; + } + return NULL; } -void -CFCMutableSet::RemoveValue(const void *value) -{ - CFMutableSetRef set = get(); - if (set) - ::CFSetRemoveValue(set, value); +void CFCMutableSet::RemoveValue(const void *value) { + CFMutableSetRef set = get(); + if (set) + ::CFSetRemoveValue(set, value); } -void -CFCMutableSet::RemoveAllValues() -{ - CFMutableSetRef set = get(); - if (set) - ::CFSetRemoveAllValues(set); +void CFCMutableSet::RemoveAllValues() { + CFMutableSetRef set = get(); + if (set) + ::CFSetRemoveAllValues(set); } - diff --git a/lldb/source/Host/macosx/cfcpp/CFCMutableSet.h b/lldb/source/Host/macosx/cfcpp/CFCMutableSet.h index 78f7a8be81d..1459b7e4632 100644 --- a/lldb/source/Host/macosx/cfcpp/CFCMutableSet.h +++ b/lldb/source/Host/macosx/cfcpp/CFCMutableSet.h @@ -12,42 +12,36 @@ #include "CFCReleaser.h" -class CFCMutableSet : public CFCReleaser<CFMutableSetRef> -{ +class CFCMutableSet : public CFCReleaser<CFMutableSetRef> { public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - CFCMutableSet(CFMutableSetRef s = NULL); - CFCMutableSet(const CFCMutableSet& rhs); - virtual ~CFCMutableSet(); - - //------------------------------------------------------------------ - // Operators - //------------------------------------------------------------------ - const CFCMutableSet& - operator=(const CFCMutableSet& rhs); - - - CFIndex GetCount() const; - CFIndex GetCountOfValue(const void *value) const; - const void * GetValue(const void *value) const; - const void * AddValue(const void *value, bool can_create); - void RemoveValue(const void *value); - void RemoveAllValues(); - - + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + CFCMutableSet(CFMutableSetRef s = NULL); + CFCMutableSet(const CFCMutableSet &rhs); + virtual ~CFCMutableSet(); + + //------------------------------------------------------------------ + // Operators + //------------------------------------------------------------------ + const CFCMutableSet &operator=(const CFCMutableSet &rhs); + + CFIndex GetCount() const; + CFIndex GetCountOfValue(const void *value) const; + const void *GetValue(const void *value) const; + const void *AddValue(const void *value, bool can_create); + void RemoveValue(const void *value); + void RemoveAllValues(); protected: - //------------------------------------------------------------------ - // Classes that inherit from CFCMutableSet can see and modify these - //------------------------------------------------------------------ + //------------------------------------------------------------------ + // Classes that inherit from CFCMutableSet can see and modify these + //------------------------------------------------------------------ private: - //------------------------------------------------------------------ - // For CFCMutableSet only - //------------------------------------------------------------------ - + //------------------------------------------------------------------ + // For CFCMutableSet only + //------------------------------------------------------------------ }; -#endif // CoreFoundationCPP_CFMutableSet_h_ +#endif // CoreFoundationCPP_CFMutableSet_h_ diff --git a/lldb/source/Host/macosx/cfcpp/CFCReleaser.h b/lldb/source/Host/macosx/cfcpp/CFCReleaser.h index 67dd2ead579..c596d1e1e7e 100644 --- a/lldb/source/Host/macosx/cfcpp/CFCReleaser.h +++ b/lldb/source/Host/macosx/cfcpp/CFCReleaser.h @@ -26,133 +26,103 @@ // pointer, it is designed to relinquish ownership of the pointer just // like std:auto_ptr<T>::release() does. //---------------------------------------------------------------------- -template <class T> -class CFCReleaser -{ +template <class T> class CFCReleaser { public: - //---------------------------------------------------------- - // Constructor that takes a pointer to a CF object that is - // to be released when this object goes out of scope - //---------------------------------------------------------- - CFCReleaser(T ptr = NULL) : - _ptr(ptr) - { - } - - //---------------------------------------------------------- - // Copy constructor - // - // Note that copying a CFCReleaser will not transfer - // ownership of the contained pointer, but it will bump its - // reference count. This is where this class differs from - // std::auto_ptr. - //---------------------------------------------------------- - CFCReleaser(const CFCReleaser& rhs) : - _ptr(rhs.get()) - { - if (get()) - ::CFRetain(get()); - } - - - //---------------------------------------------------------- - // The destructor will release the pointer that it contains - // if it has a valid pointer. - //---------------------------------------------------------- - virtual ~CFCReleaser() - { - reset(); - } - - //---------------------------------------------------------- - // Assignment operator. - // - // Note that assigning one CFCReleaser to another will - // not transfer ownership of the contained pointer, but it - // will bump its reference count. This is where this class - // differs from std::auto_ptr. - //---------------------------------------------------------- - CFCReleaser& - operator= (const CFCReleaser<T>& rhs) - { - if (this != &rhs) - { - // Replace our owned pointer with the new one - reset(rhs.get()); - // Retain the current pointer that we own - if (get()) - ::CFRetain(get()); - } - return *this; - } - - //---------------------------------------------------------- - // Get the address of the contained type in case it needs - // to be passed to a function that will fill in a pointer - // value. The function currently will assert if _ptr is not - // NULL because the only time this method should be used is - // if another function will modify the contents, and we - // could leak a pointer if this is not NULL. If the - // assertion fires, check the offending code, or call - // reset() prior to using the "ptr_address()" member to make - // sure any owned objects has CFRelease called on it. - // I had to add the "enforce_null" bool here because some - // API's require the pointer address even though they don't change it. - //---------------------------------------------------------- - T* - ptr_address(bool enforce_null = true) - { - if (enforce_null) - assert (_ptr == NULL); - return &_ptr; - } - - //---------------------------------------------------------- - // Access the pointer itself - //---------------------------------------------------------- - T - get() - { - return _ptr; - } - - const T - get() const - { - return _ptr; - } - - - //---------------------------------------------------------- - // Set a new value for the pointer and CFRelease our old - // value if we had a valid one. - //---------------------------------------------------------- - void - reset(T ptr = NULL) - { - if ((_ptr != NULL) && (ptr != _ptr)) - ::CFRelease(_ptr); - _ptr = ptr; - } - - //---------------------------------------------------------- - // Release ownership without calling CFRelease. This class - // is designed to mimic std::auto_ptr<T>, so the release - // method releases ownership of the contained pointer - // and does NOT call CFRelease. - //---------------------------------------------------------- - T - release() - { - T tmp = _ptr; - _ptr = NULL; - return tmp; + //---------------------------------------------------------- + // Constructor that takes a pointer to a CF object that is + // to be released when this object goes out of scope + //---------------------------------------------------------- + CFCReleaser(T ptr = NULL) : _ptr(ptr) {} + + //---------------------------------------------------------- + // Copy constructor + // + // Note that copying a CFCReleaser will not transfer + // ownership of the contained pointer, but it will bump its + // reference count. This is where this class differs from + // std::auto_ptr. + //---------------------------------------------------------- + CFCReleaser(const CFCReleaser &rhs) : _ptr(rhs.get()) { + if (get()) + ::CFRetain(get()); + } + + //---------------------------------------------------------- + // The destructor will release the pointer that it contains + // if it has a valid pointer. + //---------------------------------------------------------- + virtual ~CFCReleaser() { reset(); } + + //---------------------------------------------------------- + // Assignment operator. + // + // Note that assigning one CFCReleaser to another will + // not transfer ownership of the contained pointer, but it + // will bump its reference count. This is where this class + // differs from std::auto_ptr. + //---------------------------------------------------------- + CFCReleaser &operator=(const CFCReleaser<T> &rhs) { + if (this != &rhs) { + // Replace our owned pointer with the new one + reset(rhs.get()); + // Retain the current pointer that we own + if (get()) + ::CFRetain(get()); } + return *this; + } + + //---------------------------------------------------------- + // Get the address of the contained type in case it needs + // to be passed to a function that will fill in a pointer + // value. The function currently will assert if _ptr is not + // NULL because the only time this method should be used is + // if another function will modify the contents, and we + // could leak a pointer if this is not NULL. If the + // assertion fires, check the offending code, or call + // reset() prior to using the "ptr_address()" member to make + // sure any owned objects has CFRelease called on it. + // I had to add the "enforce_null" bool here because some + // API's require the pointer address even though they don't change it. + //---------------------------------------------------------- + T *ptr_address(bool enforce_null = true) { + if (enforce_null) + assert(_ptr == NULL); + return &_ptr; + } + + //---------------------------------------------------------- + // Access the pointer itself + //---------------------------------------------------------- + T get() { return _ptr; } + + const T get() const { return _ptr; } + + //---------------------------------------------------------- + // Set a new value for the pointer and CFRelease our old + // value if we had a valid one. + //---------------------------------------------------------- + void reset(T ptr = NULL) { + if ((_ptr != NULL) && (ptr != _ptr)) + ::CFRelease(_ptr); + _ptr = ptr; + } + + //---------------------------------------------------------- + // Release ownership without calling CFRelease. This class + // is designed to mimic std::auto_ptr<T>, so the release + // method releases ownership of the contained pointer + // and does NOT call CFRelease. + //---------------------------------------------------------- + T release() { + T tmp = _ptr; + _ptr = NULL; + return tmp; + } private: - T _ptr; + T _ptr; }; -#endif // #ifdef __cplusplus -#endif // #ifndef CoreFoundationCPP_CFReleaser_h_ - +#endif // #ifdef __cplusplus +#endif // #ifndef CoreFoundationCPP_CFReleaser_h_ diff --git a/lldb/source/Host/macosx/cfcpp/CFCString.cpp b/lldb/source/Host/macosx/cfcpp/CFCString.cpp index 81a96b82499..0d3853c60a7 100644 --- a/lldb/source/Host/macosx/cfcpp/CFCString.cpp +++ b/lldb/source/Host/macosx/cfcpp/CFCString.cpp @@ -8,151 +8,123 @@ //===----------------------------------------------------------------------===// #include "CFCString.h" -#include <string> #include <glob.h> +#include <string> //---------------------------------------------------------------------- // CFCString constructor //---------------------------------------------------------------------- -CFCString::CFCString(CFStringRef s) : - CFCReleaser<CFStringRef> (s) -{ -} +CFCString::CFCString(CFStringRef s) : CFCReleaser<CFStringRef>(s) {} //---------------------------------------------------------------------- // CFCString copy constructor //---------------------------------------------------------------------- -CFCString::CFCString(const CFCString& rhs) : - CFCReleaser<CFStringRef> (rhs) -{ - -} +CFCString::CFCString(const CFCString &rhs) : CFCReleaser<CFStringRef>(rhs) {} //---------------------------------------------------------------------- // CFCString copy constructor //---------------------------------------------------------------------- -CFCString& -CFCString::operator=(const CFCString& rhs) -{ - if (this != &rhs) - *this = rhs; - return *this; +CFCString &CFCString::operator=(const CFCString &rhs) { + if (this != &rhs) + *this = rhs; + return *this; } -CFCString::CFCString (const char *cstr, CFStringEncoding cstr_encoding) : - CFCReleaser<CFStringRef> () -{ - if (cstr && cstr[0]) - { - reset(::CFStringCreateWithCString(kCFAllocatorDefault, cstr, cstr_encoding)); - } +CFCString::CFCString(const char *cstr, CFStringEncoding cstr_encoding) + : CFCReleaser<CFStringRef>() { + if (cstr && cstr[0]) { + reset( + ::CFStringCreateWithCString(kCFAllocatorDefault, cstr, cstr_encoding)); + } } //---------------------------------------------------------------------- // Destructor //---------------------------------------------------------------------- -CFCString::~CFCString() -{ -} +CFCString::~CFCString() {} -const char * -CFCString::GetFileSystemRepresentation(std::string& s) -{ - return CFCString::FileSystemRepresentation(get(), s); +const char *CFCString::GetFileSystemRepresentation(std::string &s) { + return CFCString::FileSystemRepresentation(get(), s); } -CFStringRef -CFCString::SetFileSystemRepresentation (const char *path) -{ - CFStringRef new_value = NULL; - if (path && path[0]) - new_value = ::CFStringCreateWithFileSystemRepresentation (kCFAllocatorDefault, path); - reset(new_value); - return get(); +CFStringRef CFCString::SetFileSystemRepresentation(const char *path) { + CFStringRef new_value = NULL; + if (path && path[0]) + new_value = + ::CFStringCreateWithFileSystemRepresentation(kCFAllocatorDefault, path); + reset(new_value); + return get(); } - CFStringRef -CFCString::SetFileSystemRepresentationFromCFType (CFTypeRef cf_type) -{ - CFStringRef new_value = NULL; - if (cf_type != NULL) - { - CFTypeID cf_type_id = ::CFGetTypeID(cf_type); - - if (cf_type_id == ::CFStringGetTypeID()) - { - // Retain since we are using the existing object - new_value = (CFStringRef)::CFRetain(cf_type); - } - else if (cf_type_id == ::CFURLGetTypeID()) - { - new_value = ::CFURLCopyFileSystemPath((CFURLRef)cf_type, kCFURLPOSIXPathStyle); - } +CFCString::SetFileSystemRepresentationFromCFType(CFTypeRef cf_type) { + CFStringRef new_value = NULL; + if (cf_type != NULL) { + CFTypeID cf_type_id = ::CFGetTypeID(cf_type); + + if (cf_type_id == ::CFStringGetTypeID()) { + // Retain since we are using the existing object + new_value = (CFStringRef)::CFRetain(cf_type); + } else if (cf_type_id == ::CFURLGetTypeID()) { + new_value = + ::CFURLCopyFileSystemPath((CFURLRef)cf_type, kCFURLPOSIXPathStyle); } - reset(new_value); - return get(); + } + reset(new_value); + return get(); } CFStringRef -CFCString::SetFileSystemRepresentationAndExpandTilde (const char *path) -{ - std::string expanded_path; - if (CFCString::ExpandTildeInPath(path, expanded_path)) - SetFileSystemRepresentation(expanded_path.c_str()); - else - reset(); - return get(); +CFCString::SetFileSystemRepresentationAndExpandTilde(const char *path) { + std::string expanded_path; + if (CFCString::ExpandTildeInPath(path, expanded_path)) + SetFileSystemRepresentation(expanded_path.c_str()); + else + reset(); + return get(); } -const char * -CFCString::UTF8(std::string& str) -{ - return CFCString::UTF8(get(), str); +const char *CFCString::UTF8(std::string &str) { + return CFCString::UTF8(get(), str); } // Static function that puts a copy of the UTF8 contents of CF_STR into STR -// and returns the C string pointer that is contained in STR when successful, else -// NULL is returned. This allows the std::string parameter to own the extracted string, -// and also allows that string to be returned as a C string pointer that can be used. - -const char * -CFCString::UTF8 (CFStringRef cf_str, std::string& str) -{ - if (cf_str) - { - const CFStringEncoding encoding = kCFStringEncodingUTF8; - CFIndex max_utf8_str_len = CFStringGetLength (cf_str); - max_utf8_str_len = CFStringGetMaximumSizeForEncoding (max_utf8_str_len, encoding); - if (max_utf8_str_len > 0) - { - str.resize(max_utf8_str_len); - if (!str.empty()) - { - if (CFStringGetCString (cf_str, &str[0], str.size(), encoding)) - { - str.resize(strlen(str.c_str())); - return str.c_str(); - } - } +// and returns the C string pointer that is contained in STR when successful, +// else +// NULL is returned. This allows the std::string parameter to own the extracted +// string, +// and also allows that string to be returned as a C string pointer that can be +// used. + +const char *CFCString::UTF8(CFStringRef cf_str, std::string &str) { + if (cf_str) { + const CFStringEncoding encoding = kCFStringEncodingUTF8; + CFIndex max_utf8_str_len = CFStringGetLength(cf_str); + max_utf8_str_len = + CFStringGetMaximumSizeForEncoding(max_utf8_str_len, encoding); + if (max_utf8_str_len > 0) { + str.resize(max_utf8_str_len); + if (!str.empty()) { + if (CFStringGetCString(cf_str, &str[0], str.size(), encoding)) { + str.resize(strlen(str.c_str())); + return str.c_str(); } + } } - return NULL; + } + return NULL; } -const char* -CFCString::ExpandTildeInPath(const char* path, std::string &expanded_path) -{ - glob_t globbuf; - if (::glob (path, GLOB_TILDE, NULL, &globbuf) == 0) - { - expanded_path = globbuf.gl_pathv[0]; - ::globfree (&globbuf); - } - else - expanded_path.clear(); +const char *CFCString::ExpandTildeInPath(const char *path, + std::string &expanded_path) { + glob_t globbuf; + if (::glob(path, GLOB_TILDE, NULL, &globbuf) == 0) { + expanded_path = globbuf.gl_pathv[0]; + ::globfree(&globbuf); + } else + expanded_path.clear(); - return expanded_path.c_str(); + return expanded_path.c_str(); } // Static function that puts a copy of the file system representation of CF_STR @@ -161,35 +133,29 @@ CFCString::ExpandTildeInPath(const char* path, std::string &expanded_path) // to own the extracted string, and also allows that string to be returned as // a C string pointer that can be used. -const char * -CFCString::FileSystemRepresentation (CFStringRef cf_str, std::string& str) -{ - if (cf_str) - { - CFIndex max_length = ::CFStringGetMaximumSizeOfFileSystemRepresentation (cf_str); - if (max_length > 0) - { - str.resize(max_length); - if (!str.empty()) - { - if (::CFStringGetFileSystemRepresentation (cf_str, &str[0], str.size())) - { - str.erase(::strlen(str.c_str())); - return str.c_str(); - } - } +const char *CFCString::FileSystemRepresentation(CFStringRef cf_str, + std::string &str) { + if (cf_str) { + CFIndex max_length = + ::CFStringGetMaximumSizeOfFileSystemRepresentation(cf_str); + if (max_length > 0) { + str.resize(max_length); + if (!str.empty()) { + if (::CFStringGetFileSystemRepresentation(cf_str, &str[0], + str.size())) { + str.erase(::strlen(str.c_str())); + return str.c_str(); } + } } - str.erase(); - return NULL; + } + str.erase(); + return NULL; } - -CFIndex -CFCString::GetLength() const -{ - CFStringRef str = get(); - if (str) - return CFStringGetLength (str); - return 0; +CFIndex CFCString::GetLength() const { + CFStringRef str = get(); + if (str) + return CFStringGetLength(str); + return 0; } diff --git a/lldb/source/Host/macosx/cfcpp/CFCString.h b/lldb/source/Host/macosx/cfcpp/CFCString.h index 27c090313ec..a7bb029408f 100644 --- a/lldb/source/Host/macosx/cfcpp/CFCString.h +++ b/lldb/source/Host/macosx/cfcpp/CFCString.h @@ -14,28 +14,28 @@ #include "CFCReleaser.h" -class CFCString : public CFCReleaser<CFStringRef> -{ +class CFCString : public CFCReleaser<CFStringRef> { public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - CFCString (CFStringRef cf_str = NULL); - CFCString (const char *s, CFStringEncoding encoding = kCFStringEncodingUTF8); - CFCString (const CFCString& rhs); - CFCString& operator= (const CFCString& rhs); - virtual ~CFCString (); - - const char * GetFileSystemRepresentation (std::string& str); - CFStringRef SetFileSystemRepresentation (const char *path); - CFStringRef SetFileSystemRepresentationFromCFType (CFTypeRef cf_type); - CFStringRef SetFileSystemRepresentationAndExpandTilde (const char *path); - const char * UTF8 (std::string& str); - CFIndex GetLength() const; - static const char *UTF8 (CFStringRef cf_str, std::string& str); - static const char *FileSystemRepresentation (CFStringRef cf_str, std::string& str); - static const char *ExpandTildeInPath(const char* path, std::string &expanded_path); + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + CFCString(CFStringRef cf_str = NULL); + CFCString(const char *s, CFStringEncoding encoding = kCFStringEncodingUTF8); + CFCString(const CFCString &rhs); + CFCString &operator=(const CFCString &rhs); + virtual ~CFCString(); + const char *GetFileSystemRepresentation(std::string &str); + CFStringRef SetFileSystemRepresentation(const char *path); + CFStringRef SetFileSystemRepresentationFromCFType(CFTypeRef cf_type); + CFStringRef SetFileSystemRepresentationAndExpandTilde(const char *path); + const char *UTF8(std::string &str); + CFIndex GetLength() const; + static const char *UTF8(CFStringRef cf_str, std::string &str); + static const char *FileSystemRepresentation(CFStringRef cf_str, + std::string &str); + static const char *ExpandTildeInPath(const char *path, + std::string &expanded_path); }; #endif // #ifndef CoreFoundationCPP_CFString_h_ diff --git a/lldb/source/Host/macosx/cfcpp/CoreFoundationCPP.h b/lldb/source/Host/macosx/cfcpp/CoreFoundationCPP.h index 6843e2649cd..88d0f5a23f8 100644 --- a/lldb/source/Host/macosx/cfcpp/CoreFoundationCPP.h +++ b/lldb/source/Host/macosx/cfcpp/CoreFoundationCPP.h @@ -21,10 +21,10 @@ #include <CoreFoundationCPP/CFCBundle.h> #include <CoreFoundationCPP/CFCData.h> -#include <CoreFoundationCPP/CFCReleaser.h> #include <CoreFoundationCPP/CFCMutableArray.h> #include <CoreFoundationCPP/CFCMutableDictionary.h> #include <CoreFoundationCPP/CFCMutableSet.h> +#include <CoreFoundationCPP/CFCReleaser.h> #include <CoreFoundationCPP/CFCString.h> -#endif // CoreFoundationCPP_CoreFoundationCPP_H_ +#endif // CoreFoundationCPP_CoreFoundationCPP_H_ |