Source Level Debugger - adding notifications

- notifySourceCode, notifyKernelDebugData, notifyDeviceDestruction
- added processDebugData method in Program
- change options when SLD is active
- add space at the beginning of extension list options

Change-Id: Iac1e52f849544dbfda62407e112cde83fa94e3ad
This commit is contained in:
Hoppe, Mateusz
2018-05-02 14:27:55 +02:00
committed by sys_ocldev
parent cec056f3c4
commit b59a5f1910
23 changed files with 547 additions and 43 deletions

View File

@ -108,6 +108,10 @@ Device::~Device() {
commandStreamReceiver = nullptr;
}
if (deviceInfo.sourceLevelDebuggerActive && sourceLevelDebugger) {
sourceLevelDebugger->notifyDeviceDestruction();
}
if (memoryManager) {
if (preemptionAllocation) {
memoryManager->freeGraphicsMemory(preemptionAllocation);

View File

@ -136,6 +136,7 @@ class Device : public BaseObject<_cl_device_id> {
std::string deviceExtensions;
bool getEnabled64kbPages();
bool isSourceLevelDebuggerActive() const;
SourceLevelDebugger *getSourceLevelDebugger() { return sourceLevelDebugger.get(); }
protected:
Device() = delete;

View File

@ -83,7 +83,7 @@ std::string convertEnabledExtensionsToCompilerInternalOptions(const char *enable
while ((pos = extensionsList.find(" ", pos)) != std::string::npos) {
extensionsList.replace(pos, 1, ",+");
}
extensionsList = "-cl-ext=-all,+" + extensionsList;
extensionsList = " -cl-ext=-all,+" + extensionsList;
return extensionsList;
}

View File

@ -24,6 +24,7 @@
#include "runtime/compiler_interface/compiler_options.h"
#include "runtime/os_interface/debug_settings_manager.h"
#include "runtime/platform/platform.h"
#include "runtime/source_level_debugger/source_level_debugger.h"
#include "runtime/helpers/validators.h"
#include "program.h"
#include <cstring>
@ -91,13 +92,24 @@ cl_int Program::build(
break;
}
internalOptions.append(platform()->peekCompilerExtensions());
if (isKernelDebugEnabled()) {
internalOptions.append(CompilerOptions::debugKernelEnable);
options.append(" -g ");
if (pDevice->getSourceLevelDebugger()) {
if (pDevice->getSourceLevelDebugger()->isOptimizationDisabled()) {
options.append("-cl-opt-disable ");
}
std::string filename;
pDevice->getSourceLevelDebugger()->notifySourceCode(sourceCode.c_str(), sourceCode.size(), filename);
if (!filename.empty()) {
// Add "-s" flag first so it will be ignored by clang in case the options already have this flag set.
options = std::string("-s ") + filename + " " + options;
}
}
}
internalOptions.append(platform()->peekCompilerExtensions());
inputArgs.pInput = (char *)(sourceCode.c_str());
inputArgs.InputSize = (uint32_t)sourceCode.size();
inputArgs.pOptions = options.c_str();
@ -122,6 +134,15 @@ cl_int Program::build(
break;
}
if (isKernelDebugEnabled()) {
processDebugData();
if (pDevice->getSourceLevelDebugger()) {
for (size_t i = 0; i < kernelInfoArray.size(); i++) {
pDevice->getSourceLevelDebugger()->notifyKernelDebugData(kernelInfoArray[i]);
}
}
}
separateBlockKernels();
} while (false);

View File

@ -24,6 +24,7 @@
#include "runtime/compiler_interface/compiler_interface.h"
#include "runtime/compiler_interface/compiler_options.h"
#include "runtime/platform/platform.h"
#include "runtime/source_level_debugger/source_level_debugger.h"
#include "runtime/helpers/validators.h"
#include "program.h"
#include <cstring>
@ -155,6 +156,16 @@ cl_int Program::compile(
if (isKernelDebugEnabled()) {
internalOptions.append(CompilerOptions::debugKernelEnable);
options.append(" -g ");
if (pDevice->getSourceLevelDebugger()) {
if (pDevice->getSourceLevelDebugger()->isOptimizationDisabled()) {
options.append("-cl-opt-disable ");
}
std::string filename;
pDevice->getSourceLevelDebugger()->notifySourceCode(sourceCode.c_str(), sourceCode.size(), filename);
if (!filename.empty()) {
options = std::string("-s ") + filename + " " + options;
}
}
}
inputArgs.pInput = pCompileData;

View File

@ -23,6 +23,7 @@
#include "runtime/compiler_interface/compiler_interface.h"
#include "runtime/platform/platform.h"
#include "runtime/helpers/validators.h"
#include "runtime/source_level_debugger/source_level_debugger.h"
#include "program.h"
#include "elf/writer.h"
#include <cstring>
@ -147,6 +148,13 @@ cl_int Program::link(
break;
}
programBinaryType = CL_PROGRAM_BINARY_TYPE_EXECUTABLE;
if (isKernelDebugEnabled()) {
processDebugData();
for (size_t i = 0; i < kernelInfoArray.size(); i++) {
pDevice->getSourceLevelDebugger()->notifyKernelDebugData(kernelInfoArray[i]);
}
}
} else {
retVal = pCompilerInterface->createLibrary(*this, inputArgs);
if (retVal != CL_SUCCESS) {

View File

@ -28,6 +28,7 @@
#include "runtime/memory_manager/memory_manager.h"
#include "patch_list.h"
#include "patch_shared.h"
#include "program_debug_data.h"
#include "program.h"
#include "runtime/kernel/kernel.h"
@ -992,4 +993,34 @@ bool Program::validateGenBinaryHeader(const iOpenCL::SProgramBinaryHeader *pGenB
pGenBinaryHeader->Version == CURRENT_ICBE_VERSION &&
validateGenBinaryDevice(static_cast<GFXCORE_FAMILY>(pGenBinaryHeader->Device));
}
void Program::processDebugData() {
if (debugData != nullptr) {
SProgramDebugDataHeaderIGC *programDebugHeader = reinterpret_cast<SProgramDebugDataHeaderIGC *>(debugData);
DEBUG_BREAK_IF(programDebugHeader->NumberOfKernels != kernelInfoArray.size());
const SKernelDebugDataHeaderIGC *kernelDebugHeader = reinterpret_cast<SKernelDebugDataHeaderIGC *>(ptrOffset(programDebugHeader, sizeof(SProgramDebugDataHeaderIGC)));
const char *kernelName = nullptr;
const char *kernelDebugData = nullptr;
for (uint32_t i = 0; i < programDebugHeader->NumberOfKernels; i++) {
kernelName = reinterpret_cast<const char *>(ptrOffset(kernelDebugHeader, sizeof(SKernelDebugDataHeaderIGC)));
auto kernelInfo = kernelInfoArray[i];
UNRECOVERABLE_IF(kernelInfo->name.compare(0, kernelInfo->name.size(), kernelName) != 0);
kernelDebugData = ptrOffset(kernelName, kernelDebugHeader->KernelNameSize);
kernelInfo->debugData.vIsa = kernelDebugData;
kernelInfo->debugData.genIsa = ptrOffset(kernelDebugData, kernelDebugHeader->SizeVisaDbgInBytes);
kernelInfo->debugData.vIsaSize = kernelDebugHeader->SizeVisaDbgInBytes;
kernelInfo->debugData.genIsaSize = kernelDebugHeader->SizeGenIsaDbgInBytes;
kernelDebugData = ptrOffset(kernelDebugData, kernelDebugHeader->SizeVisaDbgInBytes + kernelDebugHeader->SizeGenIsaDbgInBytes);
kernelDebugHeader = reinterpret_cast<const SKernelDebugDataHeaderIGC *>(kernelDebugData);
}
}
}
} // namespace OCLRT

View File

@ -87,6 +87,7 @@ Program::Program(Context *context, bool isBuiltIn) : context(context), isBuiltIn
if (DebugManager.flags.DisableStatelessToStatefulOptimization.get()) {
internalOptions += "-cl-intel-greater-than-4GB-buffer-required ";
}
kernelDebugEnabled = pDevice->isSourceLevelDebuggerActive();
}
if (DebugManager.flags.EnableStatelessToStatefulBufferOffsetOpt.get()) {

View File

@ -188,6 +188,7 @@ class Program : public BaseObject<_cl_program> {
void storeLlvmBinary(const void *pSrc, const size_t srcSize);
void storeDebugData(const void *pSrc, const size_t srcSize);
void processDebugData();
void updateBuildLog(const Device *pDevice, const char *pErrorString, const size_t errorStringSize);

View File

@ -34,6 +34,7 @@ const char *SourceLevelDebugger::getDebuggerOptionSymbol = "getDebuggerOption";
const char *SourceLevelDebugger::notifyKernelDebugDataSymbol = "notifyKernelDebugData";
const char *SourceLevelDebugger::initSymbol = "init";
const char *SourceLevelDebugger::isDebuggerActiveSymbol = "isDebuggerActive";
const char *SourceLevelDebugger::notifyDeviceDestructionSymbol = "notifyDeviceDestruction";
class SourceLevelDebugger::SourceLevelDebuggerInterface {
public:
@ -46,6 +47,7 @@ class SourceLevelDebugger::SourceLevelDebuggerInterface {
typedef int (*NotifyKernelDebugDataFunction)(GfxDbgKernelDebugData *data);
typedef int (*InitFunction)(GfxDbgTargetCaps *data);
typedef int (*IsDebuggerActiveFunction)(void);
typedef int (*NotifyDeviceDestructionFunction)(GfxDbgDeviceDestructionData *data);
NotifyNewDeviceFunction notifyNewDeviceFunc = nullptr;
NotifySourceCodeFunction notifySourceCodeFunc = nullptr;
@ -53,6 +55,7 @@ class SourceLevelDebugger::SourceLevelDebuggerInterface {
NotifyKernelDebugDataFunction notifyKernelDebugDataFunc = nullptr;
InitFunction initFunc = nullptr;
IsDebuggerActiveFunction isDebuggerActive = nullptr;
NotifyDeviceDestructionFunction notifyDeviceDestructionFunc = nullptr;
};
SourceLevelDebugger *SourceLevelDebugger::create() {
@ -88,6 +91,7 @@ SourceLevelDebugger::SourceLevelDebugger(OsLibrary *library) {
UNRECOVERABLE_IF(sourceLevelDebuggerInterface->notifyKernelDebugDataFunc == nullptr);
UNRECOVERABLE_IF(sourceLevelDebuggerInterface->notifyNewDeviceFunc == nullptr);
UNRECOVERABLE_IF(sourceLevelDebuggerInterface->notifySourceCodeFunc == nullptr);
UNRECOVERABLE_IF(sourceLevelDebuggerInterface->notifyDeviceDestructionFunc == nullptr);
isActive = true;
}
}
@ -111,31 +115,55 @@ void SourceLevelDebugger::getFunctions() {
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));
sourceLevelDebuggerInterface->notifyDeviceDestructionFunc = reinterpret_cast<SourceLevelDebuggerInterface::NotifyDeviceDestructionFunction>(debuggerLibrary->getProcAddress(notifyDeviceDestructionSymbol));
}
void SourceLevelDebugger::notifyNewDevice(uint32_t deviceHandle) const {
bool SourceLevelDebugger::notifyNewDevice(uint32_t deviceHandle) {
if (isActive) {
GfxDbgNewDeviceData newDevice;
newDevice.version = IGFXDBG_CURRENT_VERSION;
newDevice.dh = reinterpret_cast<GfxDeviceHandle>(static_cast<uint64_t>(deviceHandle));
newDevice.udh = GfxDeviceHandle(0);
sourceLevelDebuggerInterface->notifyNewDeviceFunc(&newDevice);
int result = sourceLevelDebuggerInterface->notifyNewDeviceFunc(&newDevice);
DEBUG_BREAK_IF(static_cast<IgfxdbgRetVal>(result) != IgfxdbgRetVal::IGFXDBG_SUCCESS);
static_cast<void>(result);
this->deviceHandle = deviceHandle;
}
return false;
}
void SourceLevelDebugger::notifySourceCode(uint32_t deviceHandle, const char *source, size_t sourceSize) const {
bool SourceLevelDebugger::notifyDeviceDestruction() {
if (isActive) {
GfxDbgDeviceDestructionData deviceDestruction;
deviceDestruction.version = IGFXDBG_CURRENT_VERSION;
deviceDestruction.dh = reinterpret_cast<GfxDeviceHandle>(static_cast<uint64_t>(this->deviceHandle));
int result = sourceLevelDebuggerInterface->notifyDeviceDestructionFunc(&deviceDestruction);
DEBUG_BREAK_IF(static_cast<IgfxdbgRetVal>(result) != IgfxdbgRetVal::IGFXDBG_SUCCESS);
static_cast<void>(result);
this->deviceHandle = 0;
return true;
}
return false;
}
bool SourceLevelDebugger::notifySourceCode(const char *source, size_t sourceSize, std::string &file) const {
if (isActive) {
GfxDbgSourceCode sourceCode;
char fileName[FILENAME_MAX] = "";
sourceCode.version = IGFXDBG_CURRENT_VERSION;
sourceCode.hDevice = reinterpret_cast<GfxDeviceHandle>(static_cast<uint64_t>(deviceHandle));
sourceCode.hDevice = reinterpret_cast<GfxDeviceHandle>(static_cast<uint64_t>(this->deviceHandle));
sourceCode.sourceCode = source;
sourceCode.sourceCodeSize = static_cast<unsigned int>(sourceSize);
sourceCode.sourceName = &fileName[0];
sourceCode.sourceNameMaxLen = sizeof(fileName);
sourceLevelDebuggerInterface->notifySourceCodeFunc(&sourceCode);
int result = sourceLevelDebuggerInterface->notifySourceCodeFunc(&sourceCode);
DEBUG_BREAK_IF(static_cast<IgfxdbgRetVal>(result) != IgfxdbgRetVal::IGFXDBG_SUCCESS);
static_cast<void>(result);
file = fileName;
}
return false;
}
bool SourceLevelDebugger::isOptimizationDisabled() const {
@ -157,10 +185,10 @@ bool SourceLevelDebugger::isOptimizationDisabled() const {
return false;
}
void SourceLevelDebugger::notifyKernelDebugData(uint32_t deviceHandle, const KernelInfo *kernelInfo) const {
bool SourceLevelDebugger::notifyKernelDebugData(const KernelInfo *kernelInfo) const {
if (isActive) {
GfxDbgKernelDebugData kernelDebugData;
kernelDebugData.hDevice = reinterpret_cast<GfxDeviceHandle>(static_cast<uint64_t>(deviceHandle));
kernelDebugData.hDevice = reinterpret_cast<GfxDeviceHandle>(static_cast<uint64_t>(this->deviceHandle));
kernelDebugData.version = IGFXDBG_CURRENT_VERSION;
kernelDebugData.hProgram = reinterpret_cast<GenRtProgramHandle>(0);
@ -173,11 +201,14 @@ void SourceLevelDebugger::notifyKernelDebugData(uint32_t deviceHandle, const Ker
kernelDebugData.dbgGenIsaBuffer = kernelInfo->debugData.genIsa;
kernelDebugData.dbgGenIsaSize = kernelInfo->debugData.genIsaSize;
sourceLevelDebuggerInterface->notifyKernelDebugDataFunc(&kernelDebugData);
int result = sourceLevelDebuggerInterface->notifyKernelDebugDataFunc(&kernelDebugData);
DEBUG_BREAK_IF(static_cast<IgfxdbgRetVal>(result) != IgfxdbgRetVal::IGFXDBG_SUCCESS);
static_cast<void>(result);
}
return false;
}
void SourceLevelDebugger::initialize(bool useLocalMemory) {
bool SourceLevelDebugger::initialize(bool useLocalMemory) {
if (isActive) {
GfxDbgTargetCaps caps = {IGFXDBG_CURRENT_VERSION, useLocalMemory};
int result = sourceLevelDebuggerInterface->initFunc(&caps);
@ -185,5 +216,6 @@ void SourceLevelDebugger::initialize(bool useLocalMemory) {
isActive = false;
}
}
return false;
}
} // namespace OCLRT

View File

@ -23,6 +23,7 @@
#pragma once
#include "runtime/os_interface/os_library.h"
#include <memory>
#include <string>
namespace OCLRT {
struct KernelInfo;
@ -30,17 +31,18 @@ struct KernelInfo;
class SourceLevelDebugger {
public:
SourceLevelDebugger(OsLibrary *library);
~SourceLevelDebugger();
virtual ~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(uint32_t deviceHandle, const KernelInfo *kernelInfo) const;
void initialize(bool useLocalMemory);
MOCKABLE_VIRTUAL bool isDebuggerActive();
MOCKABLE_VIRTUAL bool notifyNewDevice(uint32_t deviceHandle);
MOCKABLE_VIRTUAL bool notifyDeviceDestruction();
MOCKABLE_VIRTUAL bool notifySourceCode(const char *sourceCode, size_t size, std::string &filename) const;
MOCKABLE_VIRTUAL bool isOptimizationDisabled() const;
MOCKABLE_VIRTUAL bool notifyKernelDebugData(const KernelInfo *kernelInfo) const;
MOCKABLE_VIRTUAL bool initialize(bool useLocalMemory);
protected:
class SourceLevelDebuggerInterface;
@ -51,6 +53,7 @@ class SourceLevelDebugger {
std::unique_ptr<OsLibrary> debuggerLibrary;
bool isActive = false;
uint32_t deviceHandle = 0;
static const char *notifyNewDeviceSymbol;
static const char *notifySourceCodeSymbol;
@ -58,6 +61,7 @@ class SourceLevelDebugger {
static const char *notifyKernelDebugDataSymbol;
static const char *initSymbol;
static const char *isDebuggerActiveSymbol;
static const char *notifyDeviceDestructionSymbol;
// OS specific library name
static const char *dllName;
};

View File

@ -39,16 +39,28 @@ bool SourceLevelDebugger::isDebuggerActive() {
return false;
}
void SourceLevelDebugger::notifyNewDevice(uint32_t deviceHandle) const {
bool SourceLevelDebugger::notifyNewDevice(uint32_t deviceHandle) {
return false;
}
void SourceLevelDebugger::notifySourceCode(uint32_t deviceHandle, const char *sourceCode, size_t size) const {
bool SourceLevelDebugger::notifyDeviceDestruction() {
return false;
}
bool SourceLevelDebugger::notifySourceCode(const char *sourceCode, size_t size, std::string &filename) const {
return false;
}
bool SourceLevelDebugger::isOptimizationDisabled() const {
return false;
}
void SourceLevelDebugger::notifyKernelDebugData(uint32_t deviceHandle, const KernelInfo *kernelInfo) const {
bool SourceLevelDebugger::notifyKernelDebugData(const KernelInfo *kernelInfo) const {
return false;
}
void SourceLevelDebugger::initialize(bool useLocalMemory) {
bool SourceLevelDebugger::initialize(bool useLocalMemory) {
return false;
}
} // namespace OCLRT

View File

@ -23,6 +23,7 @@
#include "runtime/compiler_interface/compiler_options.h"
#include "runtime/command_queue/command_queue.h"
#include "runtime/program/program.h"
#include "runtime/source_level_debugger/source_level_debugger.h"
#include "unit_tests/fixtures/enqueue_handler_fixture.h"
#include "unit_tests/helpers/kernel_binary_helper.h"
#include "unit_tests/helpers/kernel_filename_helper.h"
@ -44,6 +45,8 @@ class EnqueueDebugKernelTest : public ProgramSimpleFixture,
void SetUp() override {
ProgramSimpleFixture::SetUp();
device = pDevice;
pDevice->sourceLevelDebugger.reset(new SourceLevelDebugger(nullptr));
if (pDevice->getHardwareInfo().pPlatform->eRenderCoreFamily >= IGFX_GEN9_CORE) {
std::string filename;
std::string kernelOption(CompilerOptions::debugKernelEnable);

View File

@ -42,6 +42,8 @@ void *DebuggerLibrary::getProcAddress(const std::string &procName) {
return reinterpret_cast<void *>(init);
} else if (procName == "isDebuggerActive") {
return reinterpret_cast<void *>(isDebuggerActive);
} else if (procName == "notifyDeviceDestruction") {
return reinterpret_cast<void *>(notifyDeviceDestruction);
}
return nullptr;
}
@ -66,6 +68,9 @@ int DebuggerLibrary::notifySourceCode(GfxDbgSourceCode *sourceCode) {
if (interceptor) {
interceptor->sourceCodeArgIn = *sourceCode;
interceptor->sourceCodeCalled = true;
if (interceptor->sourceCodeArgOut && sourceCode->sourceNameMaxLen > 0) {
memcpy_s(sourceCode->sourceName, sourceCode->sourceNameMaxLen, interceptor->sourceCodeArgOut->sourceName, interceptor->sourceCodeArgOut->sourceNameMaxLen);
}
return interceptor->sourceCodeRetVal;
}
return IgfxdbgRetVal::IGFXDBG_SUCCESS;
@ -105,3 +110,12 @@ int DebuggerLibrary::init(GfxDbgTargetCaps *targetCaps) {
int DebuggerLibrary::isDebuggerActive(void) {
return debuggerActive ? 1 : 0;
}
int DebuggerLibrary::notifyDeviceDestruction(GfxDbgDeviceDestructionData *deviceDestruction) {
if (interceptor) {
interceptor->deviceDestructionArgIn = *deviceDestruction;
interceptor->deviceDestructionCalled = true;
return interceptor->deviceDestructionRetVal;
}
return IgfxdbgRetVal::IGFXDBG_SUCCESS;
}

View File

@ -32,24 +32,28 @@ struct DebuggerLibraryInterceptor {
GfxDbgOption optionArgIn;
GfxDbgKernelDebugData kernelDebugDataArgIn;
GfxDbgTargetCaps targetCapsArgIn;
GfxDbgDeviceDestructionData deviceDestructionArgIn;
GfxDbgNewDeviceData *newDeviceArgOut = nullptr;
GfxDbgSourceCode *sourceCodeArgOut = nullptr;
GfxDbgOption *optionArgOut = nullptr;
GfxDbgKernelDebugData *kernelDebugDataArgOut = nullptr;
GfxDbgTargetCaps *targetCapsArgOut = nullptr;
GfxDbgDeviceDestructionData *deviceDestructionArgOut = nullptr;
bool newDeviceCalled = false;
bool sourceCodeCalled = false;
bool optionCalled = false;
bool kernelDebugDataCalled = false;
bool initCalled = false;
bool deviceDestructionCalled = false;
int newDeviceRetVal = 0;
int sourceCodeRetVal = 0;
int optionRetVal = 0;
int kernelDebugDataRetVal = 0;
int initRetVal = 0;
int deviceDestructionRetVal = 0;
};
class DebuggerLibrary : public OCLRT::OsLibrary {
@ -96,6 +100,7 @@ class DebuggerLibrary : public OCLRT::OsLibrary {
static int notifyKernelDebugData(GfxDbgKernelDebugData *);
static int init(GfxDbgTargetCaps *);
static int isDebuggerActive(void);
static int notifyDeviceDestruction(GfxDbgDeviceDestructionData *);
static bool isLibraryAvailable;
static bool debuggerActive;

View File

@ -58,6 +58,7 @@ set(IGDRCL_SRCS_tests_mocks
${CMAKE_CURRENT_SOURCE_DIR}/mock_sampler.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_sip.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mock_sip.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_source_level_debugger.h
${CMAKE_CURRENT_SOURCE_DIR}/mock_submissions_aggregator.h
)

View File

@ -0,0 +1,120 @@
/*
* 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.
*/
#pragma once
#include "runtime/source_level_debugger/source_level_debugger.h"
#include "gmock/gmock.h"
#include <string>
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Winconsistent-missing-override"
#endif
using namespace OCLRT;
class MockSourceLevelDebugger : public SourceLevelDebugger {
public:
using SourceLevelDebugger::debuggerLibrary;
using SourceLevelDebugger::deviceHandle;
MockSourceLevelDebugger() : SourceLevelDebugger(SourceLevelDebugger::loadDebugger()) {
this->deviceHandle = mockDeviceHandle;
}
MockSourceLevelDebugger(OsLibrary *library) : SourceLevelDebugger(library) {
this->deviceHandle = mockDeviceHandle;
}
void setActive(bool active) {
isActive = active;
}
static const uint32_t mockDeviceHandle = 23;
};
class MockActiveSourceLevelDebugger : public SourceLevelDebugger {
public:
using SourceLevelDebugger::debuggerLibrary;
using SourceLevelDebugger::deviceHandle;
MockActiveSourceLevelDebugger() : SourceLevelDebugger(nullptr) {
this->deviceHandle = mockDeviceHandle;
isActive = true;
}
MockActiveSourceLevelDebugger(OsLibrary *library) : SourceLevelDebugger(nullptr) {
this->deviceHandle = mockDeviceHandle;
isActive = true;
}
void setActive(bool active) {
isActive = active;
}
bool isOptimizationDisabled() const override {
return isOptDisabled;
}
bool isDebuggerActive() override {
return isActive;
}
bool notifyNewDevice(uint32_t deviceHandle) override {
return false;
}
bool notifyDeviceDestruction() override {
return true;
}
bool notifySourceCode(const char *sourceCode, size_t size, std::string &filename) const override {
filename = sourceCodeFilename;
return true;
}
bool notifyKernelDebugData(const KernelInfo *kernelInfo) const override {
return false;
}
bool initialize(bool useLocalMemory) override {
return false;
}
static const uint32_t mockDeviceHandle = 23;
bool isOptDisabled = false;
std::string sourceCodeFilename;
};
class GMockSourceLevelDebugger : public SourceLevelDebugger {
public:
GMockSourceLevelDebugger(OsLibrary *library) : SourceLevelDebugger(library) {
}
void setActive(bool active) {
isActive = active;
}
bool isDebuggerActive() override {
return isActive;
}
MOCK_METHOD0(notifyDeviceDestruction, bool(void));
MOCK_CONST_METHOD1(notifyKernelDebugData, bool(const KernelInfo *));
MOCK_CONST_METHOD0(isOptimizationDisabled, bool());
MOCK_METHOD1(notifyNewDevice, bool(uint32_t));
MOCK_CONST_METHOD3(notifySourceCode, bool(const char *, size_t, std::string &));
MOCK_METHOD1(initialize, bool(bool));
};

View File

@ -83,7 +83,7 @@ TEST_F(PlatformTest, PlatformgetAsCompilerEnabledExtensionsString) {
pPlatform->initialize(numPlatformDevices, platformDevices);
compilerExtensions = pPlatform->peekCompilerExtensions();
EXPECT_THAT(compilerExtensions, ::testing::HasSubstr(std::string("-cl-ext=-all,+cl")));
EXPECT_THAT(compilerExtensions, ::testing::HasSubstr(std::string(" -cl-ext=-all,+cl")));
if (std::string(pPlatform->getDevice(0)->getDeviceInfo().clVersion).find("OpenCL 2.1") != std::string::npos) {
EXPECT_THAT(compilerExtensions, ::testing::HasSubstr(std::string("cl_khr_subgroups")));
}
@ -160,7 +160,7 @@ TEST_F(PlatformTest, getAsCompilerEnabledExtensionsString) {
EXPECT_THAT(extensionsList, ::testing::HasSubstr(std::string("cl_khr_3d_image_writes")));
std::string compilerExtensions = convertEnabledExtensionsToCompilerInternalOptions(extensionsList.c_str());
EXPECT_THAT(compilerExtensions, ::testing::HasSubstr(std::string("-cl-ext=-all,+cl")));
EXPECT_THAT(compilerExtensions, ::testing::HasSubstr(std::string(" -cl-ext=-all,+cl")));
if (hwInfo->capabilityTable.clVersionSupport > 20) {
EXPECT_THAT(compilerExtensions, ::testing::HasSubstr(std::string("cl_khr_subgroups")));

View File

@ -27,6 +27,7 @@ set(IGDRCL_SRCS_tests_program
${CMAKE_CURRENT_SOURCE_DIR}/kernel_info_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/printf_handler_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/printf_helper_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/process_debug_data_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/process_elf_binary_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/process_spir_binary_tests.cpp
${CMAKE_CURRENT_SOURCE_DIR}/program_data_tests.cpp

View File

@ -0,0 +1,95 @@
/*
* 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 "unit_tests/program/program_tests.h"
#include "unit_tests/mocks/mock_program.h"
#include "program_debug_data.h"
#include "test.h"
#include <memory>
using namespace iOpenCL;
using namespace OCLRT;
TEST_F(ProgramTests, GivenProgramWithDebugDataForTwoKernelsWhenPorcessedThenDebugDataIsSetInKernelInfos) {
const char kernelName1[] = "kernel1";
const char kernelName2[] = "kernel2";
uint32_t kernelNameSize = static_cast<uint32_t>(sizeof(kernelName1));
uint32_t genIsaSize = 8;
uint32_t visaSize = 8;
size_t debugDataSize = sizeof(SProgramDebugDataHeaderIGC) + 2 * (sizeof(SKernelDebugDataHeaderIGC) + kernelNameSize + genIsaSize + visaSize);
std::unique_ptr<char[]> debugData(new char[debugDataSize]);
KernelInfo *kernelInfo1 = new KernelInfo();
kernelInfo1->name = kernelName1;
KernelInfo *kernelInfo2 = new KernelInfo();
kernelInfo2->name = kernelName2;
std::unique_ptr<MockProgram> program(new MockProgram());
SProgramDebugDataHeaderIGC *programDebugHeader = reinterpret_cast<SProgramDebugDataHeaderIGC *>(debugData.get());
programDebugHeader->NumberOfKernels = 2;
SKernelDebugDataHeaderIGC *kernelDebugHeader = reinterpret_cast<SKernelDebugDataHeaderIGC *>(ptrOffset(programDebugHeader, sizeof(SProgramDebugDataHeaderIGC)));
kernelDebugHeader->KernelNameSize = kernelNameSize;
kernelDebugHeader->SizeGenIsaDbgInBytes = genIsaSize;
kernelDebugHeader->SizeVisaDbgInBytes = visaSize;
char *kernelName = reinterpret_cast<char *>(ptrOffset(kernelDebugHeader, sizeof(SKernelDebugDataHeaderIGC)));
memcpy_s(kernelName, kernelNameSize, kernelName1, kernelNameSize);
char *vIsa1 = (ptrOffset(kernelName, kernelNameSize));
memset(vIsa1, 10, visaSize);
char *genIsa1 = (ptrOffset(vIsa1, visaSize));
memset(genIsa1, 20, genIsaSize);
kernelDebugHeader = reinterpret_cast<SKernelDebugDataHeaderIGC *>(ptrOffset(vIsa1, genIsaSize + visaSize));
kernelDebugHeader->KernelNameSize = kernelNameSize;
kernelDebugHeader->SizeGenIsaDbgInBytes = genIsaSize;
kernelDebugHeader->SizeVisaDbgInBytes = visaSize;
kernelName = reinterpret_cast<char *>(ptrOffset(kernelDebugHeader, sizeof(SKernelDebugDataHeaderIGC)));
memcpy_s(kernelName, kernelNameSize, kernelName2, kernelNameSize);
char *vIsa2 = (ptrOffset(kernelName, kernelNameSize));
memset(vIsa2, 10, visaSize);
char *genIsa2 = (ptrOffset(vIsa2, visaSize));
memset(genIsa2, 20, genIsaSize);
program->storeDebugData(debugData.get(), debugDataSize);
program->addKernelInfo(kernelInfo1);
program->addKernelInfo(kernelInfo2);
program->processDebugData();
size_t programDebugDataSize = 0;
EXPECT_EQ(genIsaSize, kernelInfo1->debugData.genIsaSize);
EXPECT_EQ(visaSize, kernelInfo1->debugData.vIsaSize);
EXPECT_EQ(ptrDiff(vIsa1, debugData.get()), ptrDiff(kernelInfo1->debugData.vIsa, program->getDebugDataBinary(programDebugDataSize)));
EXPECT_EQ(ptrDiff(genIsa1, debugData.get()), ptrDiff(kernelInfo1->debugData.genIsa, program->getDebugDataBinary(programDebugDataSize)));
EXPECT_EQ(genIsaSize, kernelInfo2->debugData.genIsaSize);
EXPECT_EQ(visaSize, kernelInfo2->debugData.vIsaSize);
EXPECT_EQ(ptrDiff(vIsa2, debugData.get()), ptrDiff(kernelInfo2->debugData.vIsa, program->getDebugDataBinary(programDebugDataSize)));
EXPECT_EQ(ptrDiff(genIsa2, debugData.get()), ptrDiff(kernelInfo2->debugData.genIsa, program->getDebugDataBinary(programDebugDataSize)));
}

View File

@ -26,6 +26,7 @@
#include "unit_tests/helpers/kernel_binary_helper.h"
#include "unit_tests/helpers/kernel_filename_helper.h"
#include "unit_tests/mocks/mock_program.h"
#include "unit_tests/mocks/mock_source_level_debugger.h"
#include "unit_tests/program/program_tests.h"
#include "unit_tests/program/program_from_binary.h"
#include "test.h"
@ -107,6 +108,37 @@ TEST_F(ProgramWithKernelDebuggingTest, givenEnabledKernelDebugWhenProgramIsCompi
}
}
TEST_F(ProgramWithKernelDebuggingTest, givenEnabledKernelDebugAndOptDisabledWhenProgramIsCompiledThenOptionsIncludeClOptDisableFlag) {
if (pDevice->getHardwareInfo().pPlatform->eRenderCoreFamily >= IGFX_GEN9_CORE) {
MockActiveSourceLevelDebugger *sourceLevelDebugger = new MockActiveSourceLevelDebugger;
sourceLevelDebugger->isOptDisabled = true;
pDevice->sourceLevelDebugger.reset(sourceLevelDebugger);
cl_int retVal = pProgram->compile(1, &device, nullptr,
0, nullptr, nullptr,
nullptr,
nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_THAT(pProgram->getOptions(), ::testing::HasSubstr("-cl-opt-disable"));
}
}
TEST_F(ProgramWithKernelDebuggingTest, givenEnabledKernelDebugWhenProgramIsCompiledThenOptionsStartsWithDashSFilename) {
if (pDevice->getHardwareInfo().pPlatform->eRenderCoreFamily >= IGFX_GEN9_CORE) {
MockActiveSourceLevelDebugger *sourceLevelDebugger = new MockActiveSourceLevelDebugger;
sourceLevelDebugger->sourceCodeFilename = "debugFileName";
pDevice->sourceLevelDebugger.reset(sourceLevelDebugger);
cl_int retVal = pProgram->compile(1, &device, nullptr,
0, nullptr, nullptr,
nullptr,
nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_THAT(pProgram->getOptions(), ::testing::StartsWith("-s debugFileName"));
}
}
TEST_F(ProgramWithKernelDebuggingTest, givenEnabledKernelDebugWhenProgramIsBuiltThenInternalOptionsIncludeDebugFlag) {
if (pDevice->getHardwareInfo().pPlatform->eRenderCoreFamily >= IGFX_GEN9_CORE) {
std::string receivedInternalOptions;
@ -131,6 +163,78 @@ TEST_F(ProgramWithKernelDebuggingTest, givenEnabledKernelDebugWhenProgramIsBuilt
}
}
TEST_F(ProgramWithKernelDebuggingTest, givenEnabledKernelDebugAndOptDisabledWhenProgramIsBuiltThenOptionsIncludeClOptDisableFlag) {
if (pDevice->getHardwareInfo().pPlatform->eRenderCoreFamily >= IGFX_GEN9_CORE) {
MockActiveSourceLevelDebugger *sourceLevelDebugger = new MockActiveSourceLevelDebugger;
sourceLevelDebugger->isOptDisabled = true;
pDevice->sourceLevelDebugger.reset(sourceLevelDebugger);
cl_int retVal = pProgram->build(1, &device, nullptr, nullptr, nullptr, false);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_THAT(pProgram->getOptions(), ::testing::HasSubstr("-cl-opt-disable"));
}
}
TEST_F(ProgramWithKernelDebuggingTest, givenEnabledKernelDebugWhenProgramIsBuiltThenOptionsStartsWithDashSFilename) {
if (pDevice->getHardwareInfo().pPlatform->eRenderCoreFamily >= IGFX_GEN9_CORE) {
MockActiveSourceLevelDebugger *sourceLevelDebugger = new MockActiveSourceLevelDebugger;
sourceLevelDebugger->sourceCodeFilename = "debugFileName";
pDevice->sourceLevelDebugger.reset(sourceLevelDebugger);
cl_int retVal = pProgram->build(1, &device, nullptr, nullptr, nullptr, false);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_THAT(pProgram->getOptions(), ::testing::StartsWith("-s debugFileName"));
}
}
TEST_F(ProgramWithKernelDebuggingTest, givenEnabledKernelDebugWhenProgramIsBuiltThenDebuggerIsNotifiedWithKernelDebugData) {
if (pDevice->getHardwareInfo().pPlatform->eRenderCoreFamily >= IGFX_GEN9_CORE) {
GMockSourceLevelDebugger *sourceLevelDebugger = new GMockSourceLevelDebugger(nullptr);
ON_CALL(*sourceLevelDebugger, notifySourceCode(::testing::_, ::testing::_, ::testing::_)).WillByDefault(::testing::Return(false));
ON_CALL(*sourceLevelDebugger, isOptimizationDisabled()).WillByDefault(::testing::Return(false));
EXPECT_CALL(*sourceLevelDebugger, isOptimizationDisabled()).Times(1);
EXPECT_CALL(*sourceLevelDebugger, notifySourceCode(::testing::_, ::testing::_, ::testing::_)).Times(1);
EXPECT_CALL(*sourceLevelDebugger, notifyKernelDebugData(::testing::_)).Times(1);
sourceLevelDebugger->setActive(true);
pDevice->sourceLevelDebugger.reset(sourceLevelDebugger);
cl_int retVal = pProgram->build(1, &device, nullptr, nullptr, nullptr, false);
EXPECT_EQ(CL_SUCCESS, retVal);
}
}
TEST_F(ProgramWithKernelDebuggingTest, givenEnabledKernelDebugWhenProgramIsLinkedThenDebuggerIsNotifiedWithKernelDebugData) {
if (pDevice->getHardwareInfo().pPlatform->eRenderCoreFamily >= IGFX_GEN9_CORE) {
GMockSourceLevelDebugger *sourceLevelDebugger = new GMockSourceLevelDebugger(nullptr);
ON_CALL(*sourceLevelDebugger, notifySourceCode(::testing::_, ::testing::_, ::testing::_)).WillByDefault(::testing::Return(false));
ON_CALL(*sourceLevelDebugger, isOptimizationDisabled()).WillByDefault(::testing::Return(false));
EXPECT_CALL(*sourceLevelDebugger, isOptimizationDisabled()).Times(1);
EXPECT_CALL(*sourceLevelDebugger, notifySourceCode(::testing::_, ::testing::_, ::testing::_)).Times(1);
EXPECT_CALL(*sourceLevelDebugger, notifyKernelDebugData(::testing::_)).Times(1);
sourceLevelDebugger->setActive(true);
pDevice->sourceLevelDebugger.reset(sourceLevelDebugger);
cl_int retVal = pProgram->compile(1, &device, nullptr,
0, nullptr, nullptr,
nullptr,
nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
cl_program program = pProgram;
retVal = pProgram->link(1, &device, nullptr,
1, &program, nullptr, nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
}
}
TEST_F(ProgramWithKernelDebuggingTest, givenProgramWithKernelDebugEnabledWhenBuiltThenPatchTokenAllocateSipSurfaceHasSizeGreaterThanZero) {
if (pDevice->getHardwareInfo().pPlatform->eRenderCoreFamily >= IGFX_GEN9_CORE) {
retVal = pProgram->build(1, &device, CompilerOptions::debugKernelEnable, nullptr, nullptr, false);
@ -151,3 +255,20 @@ TEST_F(ProgramWithKernelDebuggingTest, givenKernelDebugEnabledWhenProgramIsBuilt
EXPECT_NE(0u, debugDataSize);
}
}
TEST_F(ProgramWithKernelDebuggingTest, givenProgramWithKernelDebugEnabledWhenProcessDebugDataIsCalledThenKernelInfosAreFilledWithDebugData) {
if (pDevice->getHardwareInfo().pPlatform->eRenderCoreFamily >= IGFX_GEN9_CORE) {
retVal = pProgram->build(1, &device, nullptr, nullptr, nullptr, false);
EXPECT_EQ(CL_SUCCESS, retVal);
pProgram->processDebugData();
auto kernelInfo = pProgram->getKernelInfo("CopyBuffer");
EXPECT_NE(0u, kernelInfo->debugData.genIsaSize);
EXPECT_NE(0u, kernelInfo->debugData.vIsaSize);
EXPECT_NE(nullptr, kernelInfo->debugData.genIsa);
EXPECT_NE(nullptr, kernelInfo->debugData.vIsa);
}
}

View File

@ -25,12 +25,14 @@
#include "unit_tests/helpers/debug_manager_state_restore.h"
#include "unit_tests/mocks/mock_builtins.h"
#include "unit_tests/mocks/mock_device.h"
#include "unit_tests/mocks/mock_source_level_debugger.h"
#include "test.h"
using PreambleTest = ::testing::Test;
using namespace OCLRT;
template <typename T = SourceLevelDebugger>
class MockDeviceWithActiveDebugger : public MockDevice {
public:
class MockOsLibrary : public OsLibrary {
@ -43,13 +45,18 @@ class MockDeviceWithActiveDebugger : public MockDevice {
}
};
MockDeviceWithActiveDebugger(const HardwareInfo &hwInfo, bool isRootDevice = true) : MockDevice(hwInfo, isRootDevice) {
sourceLevelDebugger.reset(new SourceLevelDebugger(new MockOsLibrary));
sourceLevelDebuggerCreated = new T(new MockOsLibrary);
sourceLevelDebugger.reset(sourceLevelDebuggerCreated);
}
void initializeCaps() override {
MockDevice::initializeCaps();
this->setSourceLevelDebuggerActive(true);
}
T *getSourceLevelDebugger() {
return sourceLevelDebuggerCreated;
}
T *sourceLevelDebuggerCreated = nullptr;
};
TEST(DeviceCreation, givenDeviceWithMidThreadPreemptionAndDebuggingActiveWhenDeviceIsCreatedThenCorrectSipKernelIsCreated) {
@ -65,7 +72,7 @@ TEST(DeviceCreation, givenDeviceWithMidThreadPreemptionAndDebuggingActiveWhenDev
EXPECT_FALSE(mockBuiltins->getSipKernelCalled);
DebugManager.flags.ForcePreemptionMode.set((int32_t)PreemptionMode::MidThread);
auto device = std::unique_ptr<MockDeviceWithActiveDebugger>(Device::create<MockDeviceWithActiveDebugger>(nullptr));
auto device = std::unique_ptr<MockDeviceWithActiveDebugger<>>(Device::create<MockDeviceWithActiveDebugger<>>(nullptr));
EXPECT_TRUE(mockBuiltins->getSipKernelCalled);
EXPECT_LE(SipKernelType::DbgCsr, mockBuiltins->getSipKernelType);
@ -88,7 +95,7 @@ TEST(DeviceCreation, givenDeviceWithDisabledPreemptionAndDebuggingActiveWhenDevi
EXPECT_FALSE(mockBuiltins->getSipKernelCalled);
DebugManager.flags.ForcePreemptionMode.set((int32_t)PreemptionMode::Disabled);
auto device = std::unique_ptr<MockDeviceWithActiveDebugger>(Device::create<MockDeviceWithActiveDebugger>(nullptr));
auto device = std::unique_ptr<MockDeviceWithActiveDebugger<>>(Device::create<MockDeviceWithActiveDebugger<>>(nullptr));
EXPECT_TRUE(mockBuiltins->getSipKernelCalled);
EXPECT_LE(SipKernelType::DbgCsr, mockBuiltins->getSipKernelType);
@ -97,3 +104,9 @@ TEST(DeviceCreation, givenDeviceWithDisabledPreemptionAndDebuggingActiveWhenDevi
mockBuiltins.reset();
}
}
TEST(DeviceWithSourceLevelDebugger, givenDeviceWithSourceLevelDebuggerActiveWhenDeviceIsDestructedThenSourceLevelDebuggerIsNotified) {
auto device = std::unique_ptr<MockDeviceWithActiveDebugger<GMockSourceLevelDebugger>>(Device::create<MockDeviceWithActiveDebugger<GMockSourceLevelDebugger>>(nullptr));
GMockSourceLevelDebugger *gmock = device->getSourceLevelDebugger();
EXPECT_CALL(*gmock, notifyDeviceDestruction()).Times(1);
}

View File

@ -27,11 +27,14 @@
#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 "unit_tests/mocks/mock_source_level_debugger.h"
#include <gtest/gtest.h>
#include <memory>
#include <string>
using namespace OCLRT;
using std::string;
using std::unique_ptr;
class DebuggerLibraryRestorer {
@ -49,15 +52,6 @@ class DebuggerLibraryRestorer {
bool restoreAvailableState = false;
};
class MockSourceLevelDebugger : public SourceLevelDebugger {
public:
using SourceLevelDebugger::debuggerLibrary;
MockSourceLevelDebugger() : SourceLevelDebugger(SourceLevelDebugger::loadDebugger()) {}
void setActive(bool active) {
isActive = active;
}
};
TEST(SourceLevelDebugger, givenNoKernelDebuggerLibraryWhenSourceLevelDebuggerIsCreatedThenLibraryIsNotLoaded) {
DebuggerLibraryRestorer restorer;
DebuggerLibrary::setLibraryAvailable(false);
@ -112,15 +106,24 @@ TEST(SourceLevelDebugger, givenKernelDebuggerLibraryActiveWhenNotifySourceCodeIs
MockSourceLevelDebugger debugger;
GfxDbgSourceCode argOut;
char fileName[] = "filename";
argOut.sourceName = fileName;
argOut.sourceNameMaxLen = sizeof(fileName);
interceptor.sourceCodeArgOut = &argOut;
const char source[] = "sourceCode";
debugger.notifySourceCode(4, source, sizeof(source));
string file;
debugger.notifySourceCode(source, sizeof(source), file);
EXPECT_TRUE(interceptor.sourceCodeCalled);
EXPECT_EQ(reinterpret_cast<GfxDeviceHandle>(static_cast<uint64_t>(4u)), interceptor.sourceCodeArgIn.hDevice);
EXPECT_EQ(reinterpret_cast<GfxDeviceHandle>(static_cast<uint64_t>(MockSourceLevelDebugger::mockDeviceHandle)), interceptor.sourceCodeArgIn.hDevice);
EXPECT_EQ(source, interceptor.sourceCodeArgIn.sourceCode);
EXPECT_EQ(sizeof(source), interceptor.sourceCodeArgIn.sourceCodeSize);
EXPECT_NE(nullptr, interceptor.sourceCodeArgIn.sourceName);
EXPECT_NE(0u, interceptor.sourceCodeArgIn.sourceNameMaxLen);
EXPECT_STREQ(fileName, file.c_str());
}
TEST(SourceLevelDebugger, givenKernelDebuggerLibraryNotActiveWhenNotifySourceCodeIsCalledThenDebuggerLibraryFunctionIsNotCalled) {
@ -136,7 +139,8 @@ TEST(SourceLevelDebugger, givenKernelDebuggerLibraryNotActiveWhenNotifySourceCod
debugger.setActive(false);
const char source[] = "sourceCode";
debugger.notifySourceCode(4, source, sizeof(source));
string file;
debugger.notifySourceCode(source, sizeof(source), file);
EXPECT_FALSE(interceptor.sourceCodeCalled);
}
@ -153,6 +157,7 @@ TEST(SourceLevelDebugger, givenKernelDebuggerLibraryActiveWhenNotifyNewDeviceIsC
EXPECT_TRUE(interceptor.newDeviceCalled);
EXPECT_EQ(reinterpret_cast<GfxDeviceHandle>(static_cast<uint64_t>(4u)), interceptor.newDeviceArgIn.dh);
EXPECT_EQ(4u, debugger.deviceHandle);
}
TEST(SourceLevelDebugger, givenKernelDebuggerLibraryNotActiveWhenNotifyNewDeviceIsCalledThenDebuggerLibraryFunctionIsNotCalled) {
@ -289,12 +294,12 @@ TEST(SourceLevelDebugger, givenKernelDebuggerLibraryActiveWhenNotifyKernelDebugD
info.heapInfo.pKernelHeader = &kernelHeader;
info.heapInfo.pKernelHeap = isa;
debugger.notifyKernelDebugData(6, &info);
debugger.notifyKernelDebugData(&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<GfxDeviceHandle>(static_cast<uint64_t>(MockSourceLevelDebugger::mockDeviceHandle)), interceptor.kernelDebugDataArgIn.hDevice);
EXPECT_EQ(reinterpret_cast<GenRtProgramHandle>(0), interceptor.kernelDebugDataArgIn.hProgram);
EXPECT_EQ(dbgIsa, interceptor.kernelDebugDataArgIn.dbgGenIsaBuffer);
@ -319,7 +324,7 @@ TEST(SourceLevelDebugger, givenKernelDebuggerLibraryNotActiveWhenNotifyKernelDeb
debugger.setActive(false);
KernelInfo info;
debugger.notifyKernelDebugData(6, &info);
debugger.notifyKernelDebugData(&info);
EXPECT_FALSE(interceptor.kernelDebugDataCalled);
}