Source Level Debugger: initialization & notify new device

- add source level debugger to device
- load isDebuggerActive function from library
- rename interface to sourceLevelDebuggerInterface in SLD
- add DebugData to KernelInfo with kernel debug data

Change-Id: I2643ee633f8dc5c97e8bbdc9d4e7977ddcbf440d
This commit is contained in:
Hoppe, Mateusz
2018-04-23 14:26:03 +02:00
committed by sys_ocldev
parent c8c2832068
commit 2e46129d53
14 changed files with 413 additions and 50 deletions

View File

@ -22,6 +22,7 @@
#include "hw_cmds.h"
#include "runtime/built_ins/built_ins.h"
#include "runtime/built_ins/sip.h"
#include "runtime/command_stream/command_stream_receiver.h"
#include "runtime/command_stream/device_command_stream.h"
#include "runtime/command_stream/preemption.h"
@ -33,7 +34,9 @@
#include "runtime/helpers/debug_helpers.h"
#include "runtime/helpers/options.h"
#include "runtime/memory_manager/memory_manager.h"
#include "runtime/os_interface/os_interface.h"
#include "runtime/os_interface/os_time.h"
#include "runtime/source_level_debugger/source_level_debugger.h"
#include <cstring>
#include <map>
@ -84,6 +87,12 @@ Device::Device(const HardwareInfo &hwInfo,
engineType = DebugManager.flags.NodeOrdinal.get() == -1
? hwInfo.capabilityTable.defaultEngineType
: static_cast<EngineType>(DebugManager.flags.NodeOrdinal.get());
sourceLevelDebugger.reset(SourceLevelDebugger::create());
if (sourceLevelDebugger) {
bool localMemorySipAvailable = (SipKernelType::DbgCsrLocal == SipKernel::getSipKernelType(hwInfo.pPlatform->eRenderCoreFamily, true));
sourceLevelDebugger->initialize(localMemorySipAvailable);
}
}
Device::~Device() {
@ -163,6 +172,15 @@ bool Device::createDeviceImpl(const HardwareInfo *pHwInfo,
}
}
uint32_t deviceHandle = 0;
if (commandStreamReceiver->getOSInterface()) {
deviceHandle = commandStreamReceiver->getOSInterface()->getDeviceHandle();
}
if (pDevice->deviceInfo.sourceLevelDebuggerActive) {
pDevice->sourceLevelDebugger->notifyNewDevice(deviceHandle);
}
outDevice.memoryManager->setForce32BitAllocations(pDevice->getDeviceInfo().force32BitAddressess);
outDevice.memoryManager->device = pDevice;

View File

@ -37,6 +37,7 @@ class MemoryManager;
class OSTime;
class DriverInfo;
struct HardwareInfo;
class SourceLevelDebugger;
template <>
struct OpenCLObjectMapper<_cl_device_id> {
@ -169,6 +170,7 @@ class Device : public BaseObject<_cl_device_id> {
PreemptionMode preemptionMode;
EngineType engineType;
std::unique_ptr<SourceLevelDebugger> sourceLevelDebugger;
};
template <cl_device_info Param>

View File

@ -30,6 +30,7 @@
#include "runtime/os_interface/os_interface.h"
#include "runtime/platform/extensions.h"
#include "runtime/sharings/sharing_factory.h"
#include "runtime/source_level_debugger/source_level_debugger.h"
#include "CL/cl_ext_intel.h"
#include "driver_version.h"
@ -361,6 +362,6 @@ void Device::initializeCaps() {
deviceInfo.preferredLocalAtomicAlignment = MemoryConstants::cacheLineSize;
deviceInfo.preferredPlatformAtomicAlignment = MemoryConstants::cacheLineSize;
deviceInfo.sourceLevelDebuggerActive = false;
deviceInfo.sourceLevelDebuggerActive = sourceLevelDebugger ? sourceLevelDebugger->isDebuggerActive() : false;
}
} // namespace OCLRT

View File

@ -117,6 +117,13 @@ struct WorkSizeInfo {
void checkRatio(const size_t workItems[3]);
};
struct DebugData {
uint32_t vIsaSize = 0;
uint32_t genIsaSize = 0;
const char *vIsa = nullptr;
const char *genIsa = nullptr;
};
struct KernelInfo {
public:
static KernelInfo *create();
@ -243,5 +250,6 @@ struct KernelInfo {
uint64_t kernelId = 0;
bool isKernelHeapSubstituted = false;
GraphicsAllocation *kernelAllocation = nullptr;
DebugData debugData;
};
} // namespace OCLRT

View File

@ -28,7 +28,9 @@ else()
set(RUNTIME_SRCS_SOURCE_LEVEL_DEBUGGER
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/source_level_debugger.h
${CMAKE_CURRENT_SOURCE_DIR}/source_level_debugger_stubs.cpp
)
endif()
target_sources(${NEO_STATIC_LIB_NAME} PRIVATE ${RUNTIME_SRCS_SOURCE_LEVEL_DEBUGGER})
set_property(GLOBAL PROPERTY RUNTIME_SRCS_SOURCE_LEVEL_DEBUGGER ${RUNTIME_SRCS_SOURCE_LEVEL_DEBUGGER})

View File

@ -23,6 +23,7 @@
#include "igfx_debug_interchange_types.h"
#include "runtime/helpers/debug_helpers.h"
#include "runtime/program/kernel_info.h"
#include "runtime/source_level_debugger/source_level_debugger.h"
#include "runtime/os_interface/os_interface.h"
@ -32,39 +33,68 @@ const char *SourceLevelDebugger::notifySourceCodeSymbol = "notifySourceCode";
const char *SourceLevelDebugger::getDebuggerOptionSymbol = "getDebuggerOption";
const char *SourceLevelDebugger::notifyKernelDebugDataSymbol = "notifyKernelDebugData";
const char *SourceLevelDebugger::initSymbol = "init";
const char *SourceLevelDebugger::isDebuggerActiveSymbol = "isDebuggerActive";
class SourceLevelDebugger::SourceLevelDebuggerInterface {
public:
SourceLevelDebuggerInterface() = default;
~SourceLevelDebuggerInterface() = default;
typedef int (*pfNotifyNewDevice)(GfxDbgNewDeviceData *data);
typedef int (*pfNotifySourceCode)(GfxDbgSourceCode *data);
typedef int (*pfGetDebuggerOption)(GfxDbgOption *);
typedef int (*pfNotifyKernelDebugData)(GfxDbgKernelDebugData *data);
typedef int (*pfInit)(GfxDbgTargetCaps *data);
typedef int (*NotifyNewDeviceFunction)(GfxDbgNewDeviceData *data);
typedef int (*NotifySourceCodeFunction)(GfxDbgSourceCode *data);
typedef int (*GetDebuggerOptionFunction)(GfxDbgOption *);
typedef int (*NotifyKernelDebugDataFunction)(GfxDbgKernelDebugData *data);
typedef int (*InitFunction)(GfxDbgTargetCaps *data);
typedef int (*IsDebuggerActiveFunction)(void);
pfNotifyNewDevice fNotifyNewDevice = nullptr;
pfNotifySourceCode fNotifySourceCode = nullptr;
pfGetDebuggerOption fGetDebuggerOption = nullptr;
pfNotifyKernelDebugData fNotifyKernelDebugData = nullptr;
pfInit fInit = nullptr;
NotifyNewDeviceFunction notifyNewDeviceFunc = nullptr;
NotifySourceCodeFunction notifySourceCodeFunc = nullptr;
GetDebuggerOptionFunction getDebuggerOptionFunc = nullptr;
NotifyKernelDebugDataFunction notifyKernelDebugDataFunc = nullptr;
InitFunction initFunc = nullptr;
IsDebuggerActiveFunction isDebuggerActive = nullptr;
};
SourceLevelDebugger::SourceLevelDebugger() {
debuggerLibrary.reset(SourceLevelDebugger::loadDebugger());
SourceLevelDebugger *SourceLevelDebugger::create() {
auto library = SourceLevelDebugger::loadDebugger();
if (library) {
auto isActiveFunc = reinterpret_cast<SourceLevelDebuggerInterface::IsDebuggerActiveFunction>(library->getProcAddress(isDebuggerActiveSymbol));
int result = isActiveFunc();
if (result == 1) {
// pass library ownership to Source Level Debugger
return new SourceLevelDebugger(library);
}
delete library;
}
return nullptr;
}
SourceLevelDebugger::SourceLevelDebugger(OsLibrary *library) {
debuggerLibrary.reset(library);
if (debuggerLibrary.get() == nullptr) {
return;
}
interface = new SourceLevelDebuggerInterface;
sourceLevelDebuggerInterface = new SourceLevelDebuggerInterface;
getFunctions();
isActive = true;
if (sourceLevelDebuggerInterface->isDebuggerActive == nullptr) {
return;
}
int result = sourceLevelDebuggerInterface->isDebuggerActive();
if (result == 1) {
UNRECOVERABLE_IF(sourceLevelDebuggerInterface->getDebuggerOptionFunc == nullptr);
UNRECOVERABLE_IF(sourceLevelDebuggerInterface->initFunc == nullptr);
UNRECOVERABLE_IF(sourceLevelDebuggerInterface->notifyKernelDebugDataFunc == nullptr);
UNRECOVERABLE_IF(sourceLevelDebuggerInterface->notifyNewDeviceFunc == nullptr);
UNRECOVERABLE_IF(sourceLevelDebuggerInterface->notifySourceCodeFunc == nullptr);
isActive = true;
}
}
SourceLevelDebugger::~SourceLevelDebugger() {
if (interface) {
delete interface;
if (sourceLevelDebuggerInterface) {
delete sourceLevelDebuggerInterface;
}
}
@ -75,11 +105,12 @@ bool SourceLevelDebugger::isDebuggerActive() {
void SourceLevelDebugger::getFunctions() {
UNRECOVERABLE_IF(debuggerLibrary.get() == nullptr);
interface->fNotifyNewDevice = reinterpret_cast<SourceLevelDebuggerInterface::pfNotifyNewDevice>(debuggerLibrary->getProcAddress(notifyNewDeviceSymbol));
interface->fNotifySourceCode = reinterpret_cast<SourceLevelDebuggerInterface::pfNotifySourceCode>(debuggerLibrary->getProcAddress(notifySourceCodeSymbol));
interface->fGetDebuggerOption = reinterpret_cast<SourceLevelDebuggerInterface::pfGetDebuggerOption>(debuggerLibrary->getProcAddress(getDebuggerOptionSymbol));
interface->fNotifyKernelDebugData = reinterpret_cast<SourceLevelDebuggerInterface::pfNotifyKernelDebugData>(debuggerLibrary->getProcAddress(notifyKernelDebugDataSymbol));
interface->fInit = reinterpret_cast<SourceLevelDebuggerInterface::pfInit>(debuggerLibrary->getProcAddress(initSymbol));
sourceLevelDebuggerInterface->notifyNewDeviceFunc = reinterpret_cast<SourceLevelDebuggerInterface::NotifyNewDeviceFunction>(debuggerLibrary->getProcAddress(notifyNewDeviceSymbol));
sourceLevelDebuggerInterface->notifySourceCodeFunc = reinterpret_cast<SourceLevelDebuggerInterface::NotifySourceCodeFunction>(debuggerLibrary->getProcAddress(notifySourceCodeSymbol));
sourceLevelDebuggerInterface->getDebuggerOptionFunc = reinterpret_cast<SourceLevelDebuggerInterface::GetDebuggerOptionFunction>(debuggerLibrary->getProcAddress(getDebuggerOptionSymbol));
sourceLevelDebuggerInterface->notifyKernelDebugDataFunc = reinterpret_cast<SourceLevelDebuggerInterface::NotifyKernelDebugDataFunction>(debuggerLibrary->getProcAddress(notifyKernelDebugDataSymbol));
sourceLevelDebuggerInterface->initFunc = reinterpret_cast<SourceLevelDebuggerInterface::InitFunction>(debuggerLibrary->getProcAddress(initSymbol));
sourceLevelDebuggerInterface->isDebuggerActive = reinterpret_cast<SourceLevelDebuggerInterface::IsDebuggerActiveFunction>(debuggerLibrary->getProcAddress(isDebuggerActiveSymbol));
}
void SourceLevelDebugger::notifyNewDevice(uint32_t deviceHandle) const {
@ -88,7 +119,7 @@ void SourceLevelDebugger::notifyNewDevice(uint32_t deviceHandle) const {
newDevice.version = IGFXDBG_CURRENT_VERSION;
newDevice.dh = reinterpret_cast<GfxDeviceHandle>(static_cast<uint64_t>(deviceHandle));
newDevice.udh = GfxDeviceHandle(0);
interface->fNotifyNewDevice(&newDevice);
sourceLevelDebuggerInterface->notifyNewDeviceFunc(&newDevice);
}
}
void SourceLevelDebugger::notifySourceCode(uint32_t deviceHandle, const char *source, size_t sourceSize) const {
@ -103,7 +134,7 @@ void SourceLevelDebugger::notifySourceCode(uint32_t deviceHandle, const char *so
sourceCode.sourceName = &fileName[0];
sourceCode.sourceNameMaxLen = sizeof(fileName);
interface->fNotifySourceCode(&sourceCode);
sourceLevelDebuggerInterface->notifySourceCodeFunc(&sourceCode);
}
}
@ -116,7 +147,7 @@ bool SourceLevelDebugger::isOptimizationDisabled() const {
option.valueLen = sizeof(value);
option.value = &value;
int result = interface->fGetDebuggerOption(&option);
int result = sourceLevelDebuggerInterface->getDebuggerOptionFunc(&option);
if (result == 1) {
if (option.value[0] == '1') {
return true;
@ -126,8 +157,33 @@ bool SourceLevelDebugger::isOptimizationDisabled() const {
return false;
}
void SourceLevelDebugger::notifyKernelDebugData() const {
GfxDbgKernelDebugData kernelDebugData;
interface->fNotifyKernelDebugData(&kernelDebugData);
void SourceLevelDebugger::notifyKernelDebugData(uint32_t deviceHandle, const KernelInfo *kernelInfo) const {
if (isActive) {
GfxDbgKernelDebugData kernelDebugData;
kernelDebugData.hDevice = reinterpret_cast<GfxDeviceHandle>(static_cast<uint64_t>(deviceHandle));
kernelDebugData.version = IGFXDBG_CURRENT_VERSION;
kernelDebugData.hProgram = reinterpret_cast<GenRtProgramHandle>(0);
kernelDebugData.kernelName = kernelInfo->name.c_str();
kernelDebugData.kernelBinBuffer = const_cast<void *>(kernelInfo->heapInfo.pKernelHeap);
kernelDebugData.KernelBinSize = kernelInfo->heapInfo.pKernelHeader->KernelHeapSize;
kernelDebugData.dbgVisaBuffer = kernelInfo->debugData.vIsa;
kernelDebugData.dbgVisaSize = kernelInfo->debugData.vIsaSize;
kernelDebugData.dbgGenIsaBuffer = kernelInfo->debugData.genIsa;
kernelDebugData.dbgGenIsaSize = kernelInfo->debugData.genIsaSize;
sourceLevelDebuggerInterface->notifyKernelDebugDataFunc(&kernelDebugData);
}
}
void SourceLevelDebugger::initialize(bool useLocalMemory) {
if (isActive) {
GfxDbgTargetCaps caps = {IGFXDBG_CURRENT_VERSION, useLocalMemory};
int result = sourceLevelDebuggerInterface->initFunc(&caps);
if (static_cast<IgfxdbgRetVal>(result) != IgfxdbgRetVal::IGFXDBG_SUCCESS) {
isActive = false;
}
}
}
} // namespace OCLRT

View File

@ -25,22 +25,26 @@
#include <memory>
namespace OCLRT {
struct KernelInfo;
class SourceLevelDebugger {
public:
SourceLevelDebugger();
SourceLevelDebugger(OsLibrary *library);
~SourceLevelDebugger();
SourceLevelDebugger(const SourceLevelDebugger &ref) = delete;
SourceLevelDebugger &operator=(const SourceLevelDebugger &) = delete;
static SourceLevelDebugger *create();
bool isDebuggerActive();
void notifyNewDevice(uint32_t deviceHandle) const;
void notifySourceCode(uint32_t deviceHandle, const char *sourceCode, size_t size) const;
bool isOptimizationDisabled() const;
void notifyKernelDebugData() const;
void notifyKernelDebugData(uint32_t deviceHandle, const KernelInfo *kernelInfo) const;
void initialize(bool useLocalMemory);
protected:
class SourceLevelDebuggerInterface;
SourceLevelDebuggerInterface *interface = nullptr;
SourceLevelDebuggerInterface *sourceLevelDebuggerInterface = nullptr;
static OsLibrary *loadDebugger();
void getFunctions();
@ -53,6 +57,7 @@ class SourceLevelDebugger {
static const char *getDebuggerOptionSymbol;
static const char *notifyKernelDebugDataSymbol;
static const char *initSymbol;
static const char *isDebuggerActiveSymbol;
// OS specific library name
static const char *dllName;
};

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2018, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "runtime/source_level_debugger/source_level_debugger.h"
namespace OCLRT {
SourceLevelDebugger::SourceLevelDebugger(OsLibrary *library) {
debuggerLibrary.reset(library);
}
SourceLevelDebugger::~SourceLevelDebugger() {
}
SourceLevelDebugger *SourceLevelDebugger::create() {
return nullptr;
}
bool SourceLevelDebugger::isDebuggerActive() {
return false;
}
void SourceLevelDebugger::notifyNewDevice(uint32_t deviceHandle) const {
}
void SourceLevelDebugger::notifySourceCode(uint32_t deviceHandle, const char *sourceCode, size_t size) const {
}
bool SourceLevelDebugger::isOptimizationDisabled() const {
return false;
}
void SourceLevelDebugger::notifyKernelDebugData(uint32_t deviceHandle, const KernelInfo *kernelInfo) const {
}
void SourceLevelDebugger::initialize(bool useLocalMemory) {
}
} // namespace OCLRT

View File

@ -25,7 +25,7 @@
using namespace OCLRT;
bool DebuggerLibrary::isDebuggerActive = false;
bool DebuggerLibrary::debuggerActive = false;
bool DebuggerLibrary::isLibraryAvailable = false;
DebuggerLibraryInterceptor *DebuggerLibrary::interceptor = nullptr;
@ -40,6 +40,8 @@ void *DebuggerLibrary::getProcAddress(const std::string &procName) {
return reinterpret_cast<void *>(notifyKernelDebugData);
} else if (procName == "init") {
return reinterpret_cast<void *>(init);
} else if (procName == "isDebuggerActive") {
return reinterpret_cast<void *>(isDebuggerActive);
}
return nullptr;
}
@ -55,16 +57,18 @@ int DebuggerLibrary::notifyNewDevice(GfxDbgNewDeviceData *newDevice) {
if (interceptor) {
interceptor->newDeviceArgIn = *newDevice;
interceptor->newDeviceCalled = true;
return interceptor->newDeviceRetVal;
}
return 0;
return IgfxdbgRetVal::IGFXDBG_SUCCESS;
}
int DebuggerLibrary::notifySourceCode(GfxDbgSourceCode *sourceCode) {
if (interceptor) {
interceptor->sourceCodeArgIn = *sourceCode;
interceptor->sourceCodeCalled = true;
return interceptor->sourceCodeRetVal;
}
return 0;
return IgfxdbgRetVal::IGFXDBG_SUCCESS;
}
int DebuggerLibrary::getDebuggerOption(GfxDbgOption *option) {
@ -77,21 +81,27 @@ int DebuggerLibrary::getDebuggerOption(GfxDbgOption *option) {
}
return interceptor->optionRetVal;
}
return true;
return IgfxdbgRetVal::IGFXDBG_SUCCESS;
}
int DebuggerLibrary::notifyKernelDebugData(GfxDbgKernelDebugData *kernelDebugData) {
if (interceptor) {
interceptor->kernelDebugDataArgIn = *kernelDebugData;
interceptor->kernelDebugDataCalled = true;
return interceptor->kernelDebugDataRetVal;
}
return 0;
return IgfxdbgRetVal::IGFXDBG_SUCCESS;
}
int DebuggerLibrary::init(GfxDbgTargetCaps *targetCaps) {
if (interceptor) {
interceptor->targetCapsArgIn = *targetCaps;
interceptor->targetCapsCalled = true;
interceptor->initCalled = true;
return interceptor->initRetVal;
}
return 0;
return IgfxdbgRetVal::IGFXDBG_SUCCESS;
}
int DebuggerLibrary::isDebuggerActive(void) {
return debuggerActive ? 1 : 0;
}

View File

@ -43,13 +43,13 @@ struct DebuggerLibraryInterceptor {
bool sourceCodeCalled = false;
bool optionCalled = false;
bool kernelDebugDataCalled = false;
bool targetCapsCalled = false;
bool initCalled = false;
int newDeviceRetVal = 0;
int sourceCodeRetVal = 0;
int optionRetVal = 0;
int kernelDebugDataRetVal = 0;
int targetCapsRetVal = 0;
int initRetVal = 0;
};
class DebuggerLibrary : public OCLRT::OsLibrary {
@ -64,11 +64,11 @@ class DebuggerLibrary : public OCLRT::OsLibrary {
}
static void setDebuggerActive(bool active) {
isDebuggerActive = active;
debuggerActive = active;
}
static bool getDebuggerActive() {
return isDebuggerActive;
return debuggerActive;
}
static void setLibraryAvailable(bool available) {
@ -95,7 +95,8 @@ class DebuggerLibrary : public OCLRT::OsLibrary {
static int getDebuggerOption(GfxDbgOption *);
static int notifyKernelDebugData(GfxDbgKernelDebugData *);
static int init(GfxDbgTargetCaps *);
static int isDebuggerActive(void);
static bool isLibraryAvailable;
static bool isDebuggerActive;
static bool debuggerActive;
};

View File

@ -21,7 +21,6 @@
*/
#pragma once
#include "runtime/memory_manager/os_agnostic_memory_manager.h"
#include "runtime/command_stream/command_stream_receiver_hw.h"
#include "runtime/memory_manager/os_agnostic_memory_manager.h"
#include <map>

View File

@ -36,7 +36,9 @@ class MockMemoryManager;
class MockDevice : public Device {
public:
using Device::commandStreamReceiver;
using Device::createDeviceImpl;
using Device::initializeCaps;
using Device::sourceLevelDebugger;
void setOSTime(OSTime *osTime);
void setDriverInfo(DriverInfo *driverInfo);

View File

@ -20,6 +20,7 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "runtime/source_level_debugger/source_level_debugger.h"
#include "unit_tests/fixtures/device_fixture.h"
#include "unit_tests/helpers/debug_manager_state_restore.h"
#include "unit_tests/mocks/mock_builtins.h"
@ -32,7 +33,18 @@ using namespace OCLRT;
class MockDeviceWithActiveDebugger : public MockDevice {
public:
MockDeviceWithActiveDebugger(const HardwareInfo &hwInfo, bool isRootDevice = true) : MockDevice(hwInfo, isRootDevice) {}
class MockOsLibrary : public OsLibrary {
public:
void *getProcAddress(const std::string &procName) override {
return nullptr;
}
bool isLoaded() override {
return false;
}
};
MockDeviceWithActiveDebugger(const HardwareInfo &hwInfo, bool isRootDevice = true) : MockDevice(hwInfo, isRootDevice) {
sourceLevelDebugger.reset(new SourceLevelDebugger(new MockOsLibrary));
}
void initializeCaps() override {
MockDevice::initializeCaps();

View File

@ -20,12 +20,19 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "runtime/device/device.h"
#include "runtime/os_interface/os_interface.h"
#include "runtime/program/kernel_info.h"
#include "runtime/source_level_debugger/source_level_debugger.h"
#include "unit_tests/fixtures/device_fixture.h"
#include "unit_tests/libult/source_level_debugger_library.h"
#include "unit_tests/libult/create_command_stream.h"
#include <gtest/gtest.h>
#include <memory>
using namespace OCLRT;
using std::unique_ptr;
class DebuggerLibraryRestorer {
public:
@ -45,7 +52,7 @@ class DebuggerLibraryRestorer {
class MockSourceLevelDebugger : public SourceLevelDebugger {
public:
using SourceLevelDebugger::debuggerLibrary;
MockSourceLevelDebugger() = default;
MockSourceLevelDebugger() : SourceLevelDebugger(SourceLevelDebugger::loadDebugger()) {}
void setActive(bool active) {
isActive = active;
}
@ -59,7 +66,7 @@ TEST(SourceLevelDebugger, givenNoKernelDebuggerLibraryWhenSourceLevelDebuggerIsC
EXPECT_EQ(nullptr, debugger.debuggerLibrary.get());
}
TEST(SourceLevelDebugger, givenKernelDebuggerLibraryAvailableWhenIsDebuggerActiveIsCalledThenLibraryIsLoadedAndFalseIsReturned) {
TEST(SourceLevelDebugger, givenKernelDebuggerLibraryAvailableWhenSourceLevelDebuggerIsConstructedThenLibraryIsLoaded) {
DebuggerLibraryRestorer restorer;
DebuggerLibrary::setLibraryAvailable(true);
@ -67,10 +74,20 @@ TEST(SourceLevelDebugger, givenKernelDebuggerLibraryAvailableWhenIsDebuggerActiv
EXPECT_NE(nullptr, debugger.debuggerLibrary.get());
}
TEST(SourceLevelDebugger, givenKernelDebuggerLibraryAvailableWhenIsDebuggerActiveIsCalledThenTrueIsReturned) {
TEST(SourceLevelDebugger, givenKernelDebuggerLibraryAvailableWhenIsDebuggerActiveIsCalledThenFalseIsReturned) {
DebuggerLibraryRestorer restorer;
DebuggerLibrary::setLibraryAvailable(true);
MockSourceLevelDebugger debugger;
bool active = debugger.isDebuggerActive();
EXPECT_FALSE(active);
}
TEST(SourceLevelDebugger, givenKernelDebuggerLibraryActiveWhenIsDebuggerActiveIsCalledThenTrueIsReturned) {
DebuggerLibraryRestorer restorer;
DebuggerLibrary::setLibraryAvailable(true);
DebuggerLibrary::setDebuggerActive(true);
MockSourceLevelDebugger debugger;
bool active = debugger.isDebuggerActive();
EXPECT_TRUE(active);
@ -90,6 +107,7 @@ TEST(SourceLevelDebugger, givenKernelDebuggerLibraryActiveWhenNotifySourceCodeIs
DebuggerLibraryInterceptor interceptor;
DebuggerLibrary::setLibraryAvailable(true);
DebuggerLibrary::setDebuggerActive(true);
DebuggerLibrary::injectDebuggerLibraryInterceptor(&interceptor);
MockSourceLevelDebugger debugger;
@ -110,6 +128,7 @@ TEST(SourceLevelDebugger, givenKernelDebuggerLibraryNotActiveWhenNotifySourceCod
DebuggerLibraryInterceptor interceptor;
DebuggerLibrary::setLibraryAvailable(true);
DebuggerLibrary::setDebuggerActive(false);
DebuggerLibrary::injectDebuggerLibraryInterceptor(&interceptor);
MockSourceLevelDebugger debugger;
@ -126,6 +145,7 @@ TEST(SourceLevelDebugger, givenKernelDebuggerLibraryActiveWhenNotifyNewDeviceIsC
DebuggerLibraryInterceptor interceptor;
DebuggerLibrary::setLibraryAvailable(true);
DebuggerLibrary::setDebuggerActive(true);
DebuggerLibrary::injectDebuggerLibraryInterceptor(&interceptor);
MockSourceLevelDebugger debugger;
@ -140,6 +160,7 @@ TEST(SourceLevelDebugger, givenKernelDebuggerLibraryNotActiveWhenNotifyNewDevice
DebuggerLibraryInterceptor interceptor;
DebuggerLibrary::setLibraryAvailable(true);
DebuggerLibrary::setDebuggerActive(false);
DebuggerLibrary::injectDebuggerLibraryInterceptor(&interceptor);
MockSourceLevelDebugger debugger;
@ -154,6 +175,7 @@ TEST(SourceLevelDebugger, givenKernelDebuggerLibraryActiveWhenIsOptimizationDisa
DebuggerLibraryInterceptor interceptor;
DebuggerLibrary::setLibraryAvailable(true);
DebuggerLibrary::setDebuggerActive(true);
DebuggerLibrary::injectDebuggerLibraryInterceptor(&interceptor);
MockSourceLevelDebugger debugger;
@ -186,6 +208,7 @@ TEST(SourceLevelDebugger, givenActiveDebuggerWhenGetDebuggerOptionReturnsZeroThe
DebuggerLibraryInterceptor interceptor;
DebuggerLibrary::setLibraryAvailable(true);
DebuggerLibrary::setDebuggerActive(true);
DebuggerLibrary::injectDebuggerLibraryInterceptor(&interceptor);
char value = '1';
@ -205,6 +228,7 @@ TEST(SourceLevelDebugger, givenActiveDebuggerAndOptDisabledWhenGetDebuggerOption
DebuggerLibraryInterceptor interceptor;
DebuggerLibrary::setLibraryAvailable(true);
DebuggerLibrary::setDebuggerActive(true);
DebuggerLibrary::injectDebuggerLibraryInterceptor(&interceptor);
char value = '1';
@ -224,6 +248,7 @@ TEST(SourceLevelDebugger, givenActiveDebuggerAndOptDisabledWhenGetDebuggerOption
DebuggerLibraryInterceptor interceptor;
DebuggerLibrary::setLibraryAvailable(true);
DebuggerLibrary::setDebuggerActive(true);
DebuggerLibrary::injectDebuggerLibraryInterceptor(&interceptor);
char value = '0';
@ -243,10 +268,178 @@ TEST(SourceLevelDebugger, givenKernelDebuggerLibraryActiveWhenNotifyKernelDebugD
DebuggerLibraryInterceptor interceptor;
DebuggerLibrary::setLibraryAvailable(true);
DebuggerLibrary::setDebuggerActive(true);
DebuggerLibrary::injectDebuggerLibraryInterceptor(&interceptor);
MockSourceLevelDebugger debugger;
debugger.notifyKernelDebugData();
char isa[8];
char dbgIsa[10];
char visa[12];
KernelInfo info;
info.debugData.genIsa = dbgIsa;
info.debugData.vIsa = visa;
info.debugData.genIsaSize = sizeof(dbgIsa);
info.debugData.vIsaSize = sizeof(visa);
info.name = "debugKernel";
SKernelBinaryHeaderCommon kernelHeader;
kernelHeader.KernelHeapSize = sizeof(isa);
info.heapInfo.pKernelHeader = &kernelHeader;
info.heapInfo.pKernelHeap = isa;
debugger.notifyKernelDebugData(6, &info);
EXPECT_TRUE(interceptor.kernelDebugDataCalled);
}
EXPECT_EQ(static_cast<uint32_t>(IGFXDBG_CURRENT_VERSION), interceptor.kernelDebugDataArgIn.version);
EXPECT_EQ(reinterpret_cast<GfxDeviceHandle>(6), interceptor.kernelDebugDataArgIn.hDevice);
EXPECT_EQ(reinterpret_cast<GenRtProgramHandle>(0), interceptor.kernelDebugDataArgIn.hProgram);
EXPECT_EQ(dbgIsa, interceptor.kernelDebugDataArgIn.dbgGenIsaBuffer);
EXPECT_EQ(sizeof(dbgIsa), interceptor.kernelDebugDataArgIn.dbgGenIsaSize);
EXPECT_EQ(visa, interceptor.kernelDebugDataArgIn.dbgVisaBuffer);
EXPECT_EQ(sizeof(visa), interceptor.kernelDebugDataArgIn.dbgVisaSize);
EXPECT_EQ(kernelHeader.KernelHeapSize, interceptor.kernelDebugDataArgIn.KernelBinSize);
EXPECT_EQ(isa, interceptor.kernelDebugDataArgIn.kernelBinBuffer);
EXPECT_STREQ(info.name.c_str(), interceptor.kernelDebugDataArgIn.kernelName);
}
TEST(SourceLevelDebugger, givenKernelDebuggerLibraryNotActiveWhenNotifyKernelDebugDataIsCalledThenDebuggerLibraryFunctionIsNotCalled) {
DebuggerLibraryRestorer restorer;
DebuggerLibraryInterceptor interceptor;
DebuggerLibrary::setLibraryAvailable(true);
DebuggerLibrary::setDebuggerActive(false);
DebuggerLibrary::injectDebuggerLibraryInterceptor(&interceptor);
MockSourceLevelDebugger debugger;
debugger.setActive(false);
KernelInfo info;
debugger.notifyKernelDebugData(6, &info);
EXPECT_FALSE(interceptor.kernelDebugDataCalled);
}
TEST(SourceLevelDebugger, givenKernelDebuggerLibraryActiveWhenInitializeIsCalledWithLocalMemoryUsageFalseThenDebuggerFunctionIsCalledWithCorrectArg) {
DebuggerLibraryRestorer restorer;
DebuggerLibraryInterceptor interceptor;
DebuggerLibrary::setLibraryAvailable(true);
DebuggerLibrary::setDebuggerActive(true);
DebuggerLibrary::injectDebuggerLibraryInterceptor(&interceptor);
MockSourceLevelDebugger debugger;
debugger.initialize(false);
EXPECT_TRUE(interceptor.initCalled);
EXPECT_FALSE(interceptor.targetCapsArgIn.supportsLocalMemory);
}
TEST(SourceLevelDebugger, givenKernelDebuggerLibraryActiveWhenInitializeReturnsErrorThenIsActiveIsSetToFalse) {
DebuggerLibraryRestorer restorer;
DebuggerLibraryInterceptor interceptor;
DebuggerLibrary::setLibraryAvailable(true);
DebuggerLibrary::setDebuggerActive(true);
DebuggerLibrary::injectDebuggerLibraryInterceptor(&interceptor);
MockSourceLevelDebugger debugger;
interceptor.initRetVal = IgfxdbgRetVal::IGFXDBG_FAILURE;
debugger.initialize(false);
EXPECT_TRUE(interceptor.initCalled);
EXPECT_FALSE(debugger.isDebuggerActive());
}
TEST(SourceLevelDebugger, givenKernelDebuggerLibraryActiveWhenInitializeIsCalledWithLocalMemoryUsageTrueThenDebuggerFunctionIsCalledWithCorrectArg) {
DebuggerLibraryRestorer restorer;
DebuggerLibraryInterceptor interceptor;
DebuggerLibrary::setLibraryAvailable(true);
DebuggerLibrary::setDebuggerActive(true);
DebuggerLibrary::injectDebuggerLibraryInterceptor(&interceptor);
MockSourceLevelDebugger debugger;
debugger.initialize(true);
EXPECT_TRUE(interceptor.initCalled);
EXPECT_TRUE(interceptor.targetCapsArgIn.supportsLocalMemory);
}
TEST(SourceLevelDebugger, givenKernelDebuggerLibraryNotActiveWhenInitializeIsCalledThenDebuggerFunctionIsNotCalled) {
DebuggerLibraryRestorer restorer;
DebuggerLibraryInterceptor interceptor;
DebuggerLibrary::setLibraryAvailable(true);
DebuggerLibrary::setDebuggerActive(false);
DebuggerLibrary::injectDebuggerLibraryInterceptor(&interceptor);
MockSourceLevelDebugger debugger;
debugger.initialize(false);
EXPECT_FALSE(interceptor.initCalled);
}
TEST(SourceLevelDebugger, givenKernelDebuggerLibraryActiveWhenDeviceIsConstructedThenDebuggerIsInitialized) {
DebuggerLibraryRestorer restorer;
DebuggerLibraryInterceptor interceptor;
DebuggerLibrary::setLibraryAvailable(true);
DebuggerLibrary::setDebuggerActive(true);
DebuggerLibrary::injectDebuggerLibraryInterceptor(&interceptor);
unique_ptr<MockDevice> device(new MockDevice(*platformDevices[0]));
EXPECT_TRUE(interceptor.initCalled);
}
TEST(SourceLevelDebugger, givenKernelDebuggerLibraryActiveWhenDeviceImplIsCreatedThenDebuggerIsNotified) {
DebuggerLibraryRestorer restorer;
DebuggerLibraryInterceptor interceptor;
DebuggerLibrary::setLibraryAvailable(true);
DebuggerLibrary::setDebuggerActive(true);
DebuggerLibrary::injectDebuggerLibraryInterceptor(&interceptor);
unique_ptr<MockDevice> device(new MockDevice(*platformDevices[0]));
MockDevice::createDeviceImpl(platformDevices[0], true, *device.get());
EXPECT_TRUE(interceptor.newDeviceCalled);
uint32_t deviceHandleExpected = device->getCommandStreamReceiver().getOSInterface() != nullptr ? device->getCommandStreamReceiver().getOSInterface()->getDeviceHandle() : 0;
EXPECT_EQ(reinterpret_cast<GfxDeviceHandle>(static_cast<uint64_t>(deviceHandleExpected)), interceptor.newDeviceArgIn.dh);
}
TEST(SourceLevelDebugger, givenKernelDebuggerLibraryActiveWhenDeviceImplIsCreatedWithOsCsrThenDebuggerIsNotifiedWithCorrectDeviceHandle) {
DebuggerLibraryRestorer restorer;
DebuggerLibraryInterceptor interceptor;
DebuggerLibrary::setLibraryAvailable(true);
DebuggerLibrary::setDebuggerActive(true);
DebuggerLibrary::injectDebuggerLibraryInterceptor(&interceptor);
overrideCommandStreamReceiverCreation = true;
// Device::create must be used to create correct OS memory manager
unique_ptr<Device> device(Device::create<Device>(platformDevices[0]));
ASSERT_NE(nullptr, device->getCommandStreamReceiver().getOSInterface());
EXPECT_TRUE(interceptor.newDeviceCalled);
uint32_t deviceHandleExpected = device->getCommandStreamReceiver().getOSInterface()->getDeviceHandle();
EXPECT_EQ(reinterpret_cast<GfxDeviceHandle>(static_cast<uint64_t>(deviceHandleExpected)), interceptor.newDeviceArgIn.dh);
}
TEST(SourceLevelDebugger, givenKernelDebuggerLibraryNotActiveWhenDeviceIsCreatedThenDebuggerIsNotCreatedInitializedAndNotNotified) {
DebuggerLibraryRestorer restorer;
DebuggerLibraryInterceptor interceptor;
DebuggerLibrary::setLibraryAvailable(true);
DebuggerLibrary::setDebuggerActive(false);
DebuggerLibrary::injectDebuggerLibraryInterceptor(&interceptor);
unique_ptr<MockDevice> device(DeviceHelper<>::create());
EXPECT_EQ(nullptr, device->sourceLevelDebugger.get());
EXPECT_FALSE(interceptor.initCalled);
EXPECT_FALSE(interceptor.newDeviceCalled);
}