Add debug key for dumping ELF to file

Add "DumpZEBin" debug flag. When this flag is enabled, Zebin will be
dumped to a .elf file (with appropiate suffix, in case such file has
been dumped before).
Signed-off-by: Kacper Nowak <kacper.nowak@intel.com>
Related-To: NEO-7895
This commit is contained in:
Kacper Nowak
2023-04-17 11:44:37 +00:00
committed by Compute-Runtime-Automation
parent 411ed1c643
commit c7adbc2140
8 changed files with 54 additions and 15 deletions

View File

@@ -47,7 +47,6 @@
#include "program_debug_data.h"
#include <fstream>
#include <list>
#include <memory>
#include <unordered_map>
@@ -1317,16 +1316,7 @@ void ModuleImp::registerElfInDebuggerL0() {
this->debugElfHandle = debuggerL0->registerElf(&debugData);
if (NEO::DebugManager.flags.DebuggerLogBitmask.get() & NEO::DebugVariables::DEBUGGER_LOG_BITMASK::DUMP_ELF) {
std::ofstream elfFile;
std::string name = "dumped_module";
std::string fileName = name + ".elf";
int suffix = 0;
while (fileExists(fileName)) {
fileName = name + "_" + std::to_string(suffix) + ".elf";
suffix++;
}
writeDataToFile(fileName.c_str(), debugData.vIsa, debugData.vIsaSize);
dumpFileIncrement(debugData.vIsa, debugData.vIsaSize, "dumped_debug_module", ".elf");
}
StackVec<NEO::GraphicsAllocation *, 32> segmentAllocs;

View File

@@ -748,7 +748,7 @@ HWTEST_F(ModuleWithZebinAndL0DebuggerTest, GivenDumpElfFlagAndZebinWhenInitializ
memcpy_s(moduleMock->translationUnit->unpackedDeviceBinary.get(), moduleMock->translationUnit->unpackedDeviceBinarySize,
zebin.storage.data(), zebin.storage.size());
std::string fileName = "dumped_module.elf";
std::string fileName = "dumped_debug_module.elf";
EXPECT_FALSE(fileExists(fileName));
EXPECT_EQ(moduleMock->initialize(&moduleDesc, neoDevice), ZE_RESULT_SUCCESS);

View File

@@ -242,6 +242,7 @@ DECLARE_DEBUG_VARIABLE(bool, PrintExecutionBuffer, false, "print execution buffe
DECLARE_DEBUG_VARIABLE(bool, PrintBOsForSubmit, false, "print all BOs passed to submission")
DECLARE_DEBUG_VARIABLE(bool, PrintDebugSettings, false, "Dump all debug variables settings to text file. Print to stdout if value is different than default.")
DECLARE_DEBUG_VARIABLE(bool, PrintDebugMessages, false, "when enabled, some debug messages will be propagated to console")
DECLARE_DEBUG_VARIABLE(bool, DumpZEBin, false, "Enables dumping zebin (elf) to a binary file (.elf extension)")
DECLARE_DEBUG_VARIABLE(bool, DumpKernels, false, "Enables dumping kernels' program source code to text files and program from binary to bin file")
DECLARE_DEBUG_VARIABLE(bool, DumpKernelArgs, false, "Enables dumping kernels args to binary files")
DECLARE_DEBUG_VARIABLE(bool, LogApiCalls, false, "Enables logging api function calls, inputs and outputs to file")

View File

@@ -7,11 +7,13 @@
#include "shared/source/compiler_interface/intermediate_representations.h"
#include "shared/source/compiler_interface/linker.h"
#include "shared/source/debug_settings/debug_settings_manager.h"
#include "shared/source/device_binary_format/device_binary_formats.h"
#include "shared/source/device_binary_format/elf/elf_decoder.h"
#include "shared/source/device_binary_format/elf/elf_encoder.h"
#include "shared/source/device_binary_format/zebin/zebin_decoder.h"
#include "shared/source/device_binary_format/zebin/zebin_elf.h"
#include "shared/source/helpers/file_io.h"
#include "shared/source/program/kernel_info.h"
#include "shared/source/program/program_info.h"
@@ -22,7 +24,9 @@ namespace NEO {
template <Elf::ELF_IDENTIFIER_CLASS numBits>
SingleDeviceBinary unpackSingleZebin(const ArrayRef<const uint8_t> archive, const ConstStringRef requestedProductAbbreviation, const TargetDevice &requestedTargetDevice,
std::string &outErrReason, std::string &outWarning) {
if (1 == NEO::DebugManager.flags.DumpZEBin.get()) {
dumpFileIncrement(reinterpret_cast<const char *>(archive.begin()), archive.size(), "dumped_zebin_module", ".elf");
}
auto elf = Elf::decodeElf<numBits>(archive, outErrReason, outWarning);
if (nullptr == elf.elfFileHeader) {
return {};

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2022 Intel Corporation
* Copyright (C) 2018-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -11,6 +11,7 @@
#include "shared/source/helpers/stdio.h"
#include <cstring>
#include <fstream>
#include <new>
size_t writeDataToFile(
@@ -60,3 +61,14 @@ bool fileExistsHasSize(const std::string &fileName) {
}
return pFile != nullptr && nsize > 0;
}
void dumpFileIncrement(const char *data, size_t dataSize, const std::string &filename, const std::string &extension) {
std::ofstream fstream;
auto filenameWithExt = filename + extension;
int suffix = 0;
while (fileExists(filenameWithExt)) {
filenameWithExt = filename + "_" + std::to_string(suffix) + extension;
suffix++;
}
writeDataToFile(filenameWithExt.c_str(), data, dataSize);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2021 Intel Corporation
* Copyright (C) 2018-2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -22,3 +22,4 @@ size_t writeDataToFile(
bool fileExists(const std::string &fileName);
bool fileExistsHasSize(const std::string &fileName);
void dumpFileIncrement(const char *data, size_t dataSize, const std::string &filename, const std::string &extension);

View File

@@ -73,6 +73,7 @@ DisableCachingForStatefulBufferAccess = 0
PrintDebugSettings = 0
UsePipeControlMultiKernelEventSync = -1
PrintDebugMessages = 0
DumpZEBin = 0
DumpKernels = 0
DumpKernelArgs = 0
LogApiCalls = 0

View File

@@ -8,10 +8,12 @@
#include "shared/source/device_binary_format/device_binary_formats.h"
#include "shared/source/device_binary_format/elf/elf.h"
#include "shared/source/device_binary_format/zebin/zebin_elf.h"
#include "shared/source/helpers/file_io.h"
#include "shared/source/helpers/hw_info.h"
#include "shared/source/helpers/ptr_math.h"
#include "shared/source/helpers/string.h"
#include "shared/source/program/program_info.h"
#include "shared/test/common/helpers/debug_manager_state_restore.h"
#include "shared/test/common/mocks/mock_modules_zebin.h"
#include "shared/test/common/test_macros/test.h"
@@ -116,6 +118,34 @@ TEST(UnpackSingleDeviceBinaryZebin, WhenValidBinaryAndMatchedWithRequestedTarget
EXPECT_TRUE(unpackErrors.empty());
}
TEST(UnpackSingleDeviceBinaryZebin, givenDumpZEBinFlagSetWhenUnpackingZebinBinaryThenEachTimeZebinIsDumpedToFile) {
DebugManagerStateRestore dbgRestorer;
DebugManager.flags.DumpZEBin.set(true);
NEO::Elf::ElfFileHeader<NEO::Elf::EI_CLASS_64> zebin;
zebin.type = NEO::Zebin::Elf::ET_ZEBIN_EXE;
zebin.machine = static_cast<decltype(zebin.machine)>(IGFX_SKYLAKE);
NEO::TargetDevice targetDevice;
targetDevice.productFamily = static_cast<PRODUCT_FAMILY>(zebin.machine);
targetDevice.stepping = 0U;
targetDevice.maxPointerSizeInBytes = 8;
std::string unpackErrors;
std::string unpackWarnings;
std::string fileName = "dumped_zebin_module.elf";
std::string fileNameInc = "dumped_zebin_module_0.elf";
EXPECT_FALSE(fileExists(fileName));
EXPECT_FALSE(fileExists(fileNameInc));
NEO::unpackSingleDeviceBinary<NEO::DeviceBinaryFormat::Zebin>(ArrayRef<const uint8_t>::fromAny(&zebin, 1U), "", targetDevice, unpackErrors, unpackWarnings);
EXPECT_TRUE(fileExistsHasSize(fileName));
NEO::unpackSingleDeviceBinary<NEO::DeviceBinaryFormat::Zebin>(ArrayRef<const uint8_t>::fromAny(&zebin, 1U), "", targetDevice, unpackErrors, unpackWarnings);
EXPECT_TRUE(fileExistsHasSize(fileNameInc));
std::remove(fileName.c_str());
std::remove(fileNameInc.c_str());
}
TEST(UnpackSingleDeviceBinaryZebin, WhenValidBinaryForDifferentDeviceThenUnpackingFails) {
NEO::Elf::ElfFileHeader<NEO::Elf::EI_CLASS_64> zebin;
zebin.type = NEO::Zebin::Elf::ET_ZEBIN_EXE;