Exemplo n.º 1
0
status_t
Architecture::CreateStackTrace(Team* team,
                               ImageDebugInfoProvider* imageInfoProvider, CpuState* cpuState,
                               StackTrace*& _stackTrace, int32 maxStackDepth, bool useExistingTrace)
{
    BReference<CpuState> cpuStateReference(cpuState);

    StackTrace* stackTrace = NULL;
    ObjectDeleter<StackTrace> stackTraceDeleter;
    StackFrame* frame = NULL;

    if (useExistingTrace)
        stackTrace = _stackTrace;
    else {
        // create the object
        stackTrace = new(std::nothrow) StackTrace;
        if (stackTrace == NULL)
            return B_NO_MEMORY;
        stackTraceDeleter.SetTo(stackTrace);
    }

    // if we're passed an already existing partial stack trace,
    // attempt to continue building it from where it left off.
    if (stackTrace->CountFrames() > 0) {
        frame = stackTrace->FrameAt(stackTrace->CountFrames() - 1);
        cpuState = frame->GetCpuState();
    }

    while (cpuState != NULL) {
        // get the instruction pointer
        target_addr_t instructionPointer = cpuState->InstructionPointer();
        if (instructionPointer == 0)
            break;

        // get the image for the instruction pointer
        AutoLocker<Team> teamLocker(team);
        Image* image = team->ImageByAddress(instructionPointer);
        BReference<Image> imageReference(image);
        teamLocker.Unlock();

        // get the image debug info
        ImageDebugInfo* imageDebugInfo = NULL;
        if (image != NULL)
            imageInfoProvider->GetImageDebugInfo(image, imageDebugInfo);
        BReference<ImageDebugInfo> imageDebugInfoReference(imageDebugInfo,
                true);

        // get the function
        teamLocker.Lock();
        FunctionInstance* function = NULL;
        FunctionDebugInfo* functionDebugInfo = NULL;
        if (imageDebugInfo != NULL) {
            function = imageDebugInfo->FunctionAtAddress(instructionPointer);
            if (function != NULL)
                functionDebugInfo = function->GetFunctionDebugInfo();
        }
        BReference<FunctionInstance> functionReference(function);
        teamLocker.Unlock();

        // If the CPU state's instruction pointer is actually the return address
        // of the next frame, we let the architecture fix that.
        if (frame != NULL
                && frame->ReturnAddress() == cpuState->InstructionPointer()) {
            UpdateStackFrameCpuState(frame, image,
                                     functionDebugInfo, cpuState);
        }

        // create the frame using the debug info
        StackFrame* previousFrame = NULL;
        CpuState* previousCpuState = NULL;
        if (function != NULL) {
            status_t error = functionDebugInfo->GetSpecificImageDebugInfo()
                             ->CreateFrame(image, function, cpuState, previousFrame,
                                           previousCpuState);
            if (error != B_OK && error != B_UNSUPPORTED)
                break;
        }

        // If we have no frame yet, let the architecture create it.
        if (previousFrame == NULL) {
            status_t error = CreateStackFrame(image, functionDebugInfo,
                                              cpuState, frame == NULL, previousFrame, previousCpuState);
            if (error != B_OK)
                break;
        }

        cpuStateReference.SetTo(previousCpuState, true);

        previousFrame->SetImage(image);
        previousFrame->SetFunction(function);

        if (!stackTrace->AddFrame(previousFrame)) {
            delete previousFrame;
            return B_NO_MEMORY;
        }

        frame = previousFrame;
        cpuState = previousCpuState;
        if (--maxStackDepth == 0)
            break;
    }

    stackTraceDeleter.Detach();
    _stackTrace = stackTrace;
    return B_OK;
}
Exemplo n.º 2
0
int CreateGeneralBridge(void **BridgePointer, void *fn, unsigned char *fill, int fill_len, int alignment, int create_stackframe)
{
	HANDLE ProcessHeap;
	unsigned long OldProtection;
	unsigned char unused[5];
	int offset;
	unsigned char *c_bridge;
	int size_desired;
	int i;

	size_desired = 5;
	if(create_stackframe) {
		size_desired += 5;
	}
	if(fill != NULL) {
		size_desired += 5;
	}


	// Create the bridge
	ProcessHeap = GetProcessHeap();
	if (!ProcessHeap)
		return 0;

	*BridgePointer = HeapAlloc(ProcessHeap, HEAP_ZERO_MEMORY, size_desired);
	if (!*BridgePointer)
		return 0;

	// Make it executable
	if (!VirtualProtect(*BridgePointer, size_desired, PAGE_EXECUTE_READWRITE, &OldProtection)) {
		return 0;
	}
	
	offset = 0;

	// Restore the stackframe code
	if(create_stackframe && CREATE_FRAME_FIRST) {
		if (!CreateStackFrame(*BridgePointer, (alignment == WINDOWS_LIBRARY) )) {
			return 0;
		}
		offset += 5;
	}

	c_bridge = (unsigned char *)*BridgePointer;
	if(fill != NULL && alignment != WINDOWS_LIBRARY) {
		for(i=0; i < fill_len;i++) {
			c_bridge[offset+i] = fill[i];
		}
		offset += fill_len;
	}

	if(create_stackframe && !CREATE_FRAME_FIRST) {
		if (!CreateStackFrame(&(c_bridge[offset]), (alignment == WINDOWS_LIBRARY))) {
			return 0;
		}
		offset += 5;
	}

	if(alignment == WINDOWS_LIBRARY) {
		if (!make_jmp(  &(c_bridge[offset]) , ((unsigned char *) fn) + 5, unused, 5)) {
			return 0;
		}
	} 
	else {
	
		if (!make_jmp(  &(c_bridge[offset]) , ((unsigned char *) fn)  + alignment + 5, unused, 5)) {
			return 0;
		}
	}

	return 1;
}