Exemplo n.º 1
0
bool
MachTask::StartExceptionThread(DNBError &err)
{
    DNBLogThreadedIf(LOG_EXCEPTIONS, "MachTask::%s ( )", __FUNCTION__);
    task_t task = TaskPortForProcessID(err);
    if (MachTask::IsValid(task))
    {
        // Got the mach port for the current process
        mach_port_t task_self = mach_task_self ();

        // Allocate an exception port that we will use to track our child process
        err = ::mach_port_allocate (task_self, MACH_PORT_RIGHT_RECEIVE, &m_exception_port);
        if (err.Fail())
            return false;

        // Add the ability to send messages on the new exception port
        err = ::mach_port_insert_right (task_self, m_exception_port, m_exception_port, MACH_MSG_TYPE_MAKE_SEND);
        if (err.Fail())
            return false;

        // Save the original state of the exception ports for our child process
        SaveExceptionPortInfo();

        // We weren't able to save the info for our exception ports, we must stop...
        if (m_exc_port_info.mask == 0)
        {
            err.SetErrorString("failed to get exception port info");
            return false;
        }

        // Set the ability to get all exceptions on this port
        err = ::task_set_exception_ports (task, m_exc_port_info.mask, m_exception_port, EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES, THREAD_STATE_NONE);
        if (DNBLogCheckLogBit(LOG_EXCEPTIONS) || err.Fail())
        {
            err.LogThreaded("::task_set_exception_ports ( task = 0x%4.4x, exception_mask = 0x%8.8x, new_port = 0x%4.4x, behavior = 0x%8.8x, new_flavor = 0x%8.8x )",
                            task,
                            m_exc_port_info.mask,
                            m_exception_port,
                            (EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES),
                            THREAD_STATE_NONE);
        }

        if (err.Fail())
            return false;

        // Create the exception thread
        err = ::pthread_create (&m_exception_thread, NULL, MachTask::ExceptionThread, this);
        return err.Success();
    }
    else
    {
        DNBLogError("MachTask::%s (): task invalid, exception thread start failed.", __FUNCTION__);
    }
    return false;
}
Exemplo n.º 2
0
bool
MachTask::StartExceptionThread(DNBError &err)
{
    DNBLogThreadedIf(LOG_EXCEPTIONS, "MachTask::%s ( )", __FUNCTION__);
    task_t task = TaskPortForProcessID(err);
    if (MachTask::IsValid(task))
    {
        // Got the mach port for the current process
        mach_port_t task_self = mach_task_self ();

        // Allocate an exception port that we will use to track our child process
        err = ::mach_port_allocate (task_self, MACH_PORT_RIGHT_RECEIVE, &m_exception_port);
        if (err.Fail())
            return false;

        // Add the ability to send messages on the new exception port
        err = ::mach_port_insert_right (task_self, m_exception_port, m_exception_port, MACH_MSG_TYPE_MAKE_SEND);
        if (err.Fail())
            return false;

        // Save the original state of the exception ports for our child process
        SaveExceptionPortInfo();

        // Set the ability to get all exceptions on this port
        err = ::task_set_exception_ports (task, EXC_MASK_ALL, m_exception_port, EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES, THREAD_STATE_NONE);
        if (err.Fail())
            return false;

        // Create the exception thread
        err = ::pthread_create (&m_exception_thread, NULL, MachTask::ExceptionThread, this);
        return err.Success();
    }
    else
    {
        DNBLogError("MachTask::%s (): task invalid, exception thread start failed.", __FUNCTION__);
    }
    return false;
}
Exemplo n.º 3
0
int
ListApplications(std::string& plist, bool opt_runningApps, bool opt_debuggable)
{
#ifdef WITH_SPRINGBOARD
    int result = -1;

    CFAllocatorRef alloc = kCFAllocatorDefault;

    // Create a mutable array that we can populate. Specify zero so it can be of any size.
    CFReleaser<CFMutableArrayRef> plistMutableArray (::CFArrayCreateMutable (alloc, 0, &kCFTypeArrayCallBacks));

    CFReleaser<CFStringRef> sbsFrontAppID (::SBSCopyFrontmostApplicationDisplayIdentifier ());
    CFReleaser<CFArrayRef> sbsAppIDs (::SBSCopyApplicationDisplayIdentifiers (opt_runningApps, opt_debuggable));

    // Need to check the return value from SBSCopyApplicationDisplayIdentifiers.
    CFIndex count = sbsAppIDs.get() ? ::CFArrayGetCount (sbsAppIDs.get()) : 0;
    CFIndex i = 0;
    for (i = 0; i < count; i++)
    {
        CFStringRef displayIdentifier = (CFStringRef)::CFArrayGetValueAtIndex (sbsAppIDs.get(), i);

        // Create a new mutable dictionary for each application
        CFReleaser<CFMutableDictionaryRef> appInfoDict (::CFDictionaryCreateMutable (alloc, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));

        // Get the process id for the app (if there is one)
        pid_t pid = INVALID_NUB_PROCESS;
        if (::SBSProcessIDForDisplayIdentifier ((CFStringRef)displayIdentifier, &pid) == true)
        {
            CFReleaser<CFNumberRef> pidCFNumber (::CFNumberCreate (alloc,  kCFNumberSInt32Type, &pid));
            ::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_PID_KEY, pidCFNumber.get());
        }

        // Set the a boolean to indicate if this is the front most
        if (sbsFrontAppID.get() && displayIdentifier && (::CFStringCompare (sbsFrontAppID.get(), displayIdentifier, 0) == kCFCompareEqualTo))
            ::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_FRONTMOST_KEY, kCFBooleanTrue);
        else
            ::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_FRONTMOST_KEY, kCFBooleanFalse);


        CFReleaser<CFStringRef> executablePath (::SBSCopyExecutablePathForDisplayIdentifier (displayIdentifier));
        if (executablePath.get() != NULL)
        {
            ::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_PATH_KEY, executablePath.get());
        }

        CFReleaser<CFStringRef> iconImagePath (::SBSCopyIconImagePathForDisplayIdentifier (displayIdentifier)) ;
        if (iconImagePath.get() != NULL)
        {
            ::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_ICON_PATH_KEY, iconImagePath.get());
        }

        CFReleaser<CFStringRef> localizedDisplayName (::SBSCopyLocalizedApplicationNameForDisplayIdentifier (displayIdentifier));
        if (localizedDisplayName.get() != NULL)
        {
            ::CFDictionarySetValue (appInfoDict.get(), DTSERVICES_APP_DISPLAY_NAME_KEY, localizedDisplayName.get());
        }

        // Append the application info to the plist array
        ::CFArrayAppendValue (plistMutableArray.get(), appInfoDict.get());
    }

    CFReleaser<CFDataRef> plistData (::CFPropertyListCreateXMLData (alloc, plistMutableArray.get()));

    // write plist to service port
    if (plistData.get() != NULL)
    {
        CFIndex size = ::CFDataGetLength (plistData.get());
        const UInt8 *bytes = ::CFDataGetBytePtr (plistData.get());
        if (bytes != NULL && size > 0)
        {
            plist.assign((char *)bytes, size);
            return 0;   // Success
        }
        else
        {
            DNBLogError("empty application property list.");
            result = -2;
        }
    }
    else
    {
        DNBLogError("serializing task list.");
        result = -3;
    }

    return result;
#else
    // TODO: list all current processes
    DNBLogError("SBS doesn't support getting application list.");
    return -1;
#endif
}