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