From 13c1fe57d9ad076125848b2c45e3caf03c7ba24e Mon Sep 17 00:00:00 2001 From: Mateusz Hoppe Date: Tue, 17 Nov 2020 19:56:12 +0100 Subject: [PATCH] Enlarge output buffer size used by kernel printf data Related-To: NEO-5208 Signed-off-by: Mateusz Hoppe --- .../unit_test/program/printf_helper_tests.cpp | 186 +++++++++++------- shared/source/program/print_formatter.cpp | 18 +- shared/source/program/print_formatter.h | 5 +- 3 files changed, 134 insertions(+), 75 deletions(-) diff --git a/opencl/test/unit_test/program/printf_helper_tests.cpp b/opencl/test/unit_test/program/printf_helper_tests.cpp index 94f1c5a05b..d100de9459 100644 --- a/opencl/test/unit_test/program/printf_helper_tests.cpp +++ b/opencl/test/unit_test/program/printf_helper_tests.cpp @@ -26,6 +26,8 @@ using namespace iOpenCL; class PrintFormatterTest : public testing::Test { public: std::unique_ptr printFormatter; + static const size_t maxPrintfOutputLength = 4096; + static const size_t printfBufferSize = 1024; std::string format; uint8_t buffer; @@ -36,7 +38,7 @@ class PrintFormatterTest : public testing::Test { std::unique_ptr kernelInfo; ClDevice *device; - uint8_t underlyingBuffer[PrintFormatter::maxPrintfOutputLength]; + uint8_t underlyingBuffer[maxPrintfOutputLength]; uint32_t offset; int maxStringIndex; @@ -45,14 +47,14 @@ class PrintFormatterTest : public testing::Test { void SetUp() override { offset = 4; maxStringIndex = 0; - data = new MockGraphicsAllocation(underlyingBuffer, PrintFormatter::maxPrintfOutputLength); + data = new MockGraphicsAllocation(underlyingBuffer, maxPrintfOutputLength); kernelInfo = std::make_unique(); device = new MockClDevice{MockDevice::createWithNewExecutionEnvironment(nullptr)}; program = std::make_unique(toClDeviceVector(*device)); kernel = new MockKernel(program.get(), *kernelInfo); - printFormatter = std::unique_ptr(new PrintFormatter(static_cast(data->getUnderlyingBuffer()), PrintFormatter::maxPrintfOutputLength, is32bit, kernelInfo->patchInfo.stringDataMap)); + printFormatter = std::unique_ptr(new PrintFormatter(static_cast(data->getUnderlyingBuffer()), printfBufferSize, is32bit, kernelInfo->patchInfo.stringDataMap)); underlyingBuffer[0] = 0; underlyingBuffer[1] = 0; @@ -178,10 +180,10 @@ TEST_P(PrintfInt8Test, GivenFormatContainingIntWhenPrintingThenValueIsInserted) storeData(stringIndex); injectValue(input.value); - char referenceOutput[PrintFormatter::maxPrintfOutputLength]; - char actualOutput[PrintFormatter::maxPrintfOutputLength]; + char referenceOutput[maxPrintfOutputLength]; + char actualOutput[maxPrintfOutputLength]; - printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, PrintFormatter::maxPrintfOutputLength, str, PrintFormatter::maxPrintfOutputLength); }); + printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength); }); snprintf(referenceOutput, sizeof(referenceOutput), input.format.c_str(), input.value); @@ -218,10 +220,10 @@ TEST_P(PrintfInt32Test, GivenFormatContainingIntWhenPrintingThenValueIsInserted) storeData(stringIndex); injectValue(input.value); - char referenceOutput[PrintFormatter::maxPrintfOutputLength]; - char actualOutput[PrintFormatter::maxPrintfOutputLength]; + char referenceOutput[maxPrintfOutputLength]; + char actualOutput[maxPrintfOutputLength]; - printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, PrintFormatter::maxPrintfOutputLength, str, PrintFormatter::maxPrintfOutputLength); }); + printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength); }); snprintf(referenceOutput, sizeof(referenceOutput), input.format.c_str(), input.value); @@ -259,10 +261,10 @@ TEST_P(PrintfUint32Test, GivenFormatContainingUintWhenPrintingThenValueIsInserte storeData(stringIndex); injectValue(input.value); - char referenceOutput[PrintFormatter::maxPrintfOutputLength]; - char actualOutput[PrintFormatter::maxPrintfOutputLength]; + char referenceOutput[maxPrintfOutputLength]; + char actualOutput[maxPrintfOutputLength]; - printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, PrintFormatter::maxPrintfOutputLength, str, PrintFormatter::maxPrintfOutputLength); }); + printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength); }); snprintf(referenceOutput, sizeof(referenceOutput), input.format.c_str(), input.value); @@ -277,9 +279,9 @@ TEST_P(PrintfUint32Test, GivenBufferSizeGreaterThanPrintBufferWhenPrintingThenBu storeData(stringIndex); injectValue(input.value); - char referenceOutput[PrintFormatter::maxPrintfOutputLength] = ""; - char actualOutput[PrintFormatter::maxPrintfOutputLength] = ""; - printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, PrintFormatter::maxPrintfOutputLength, str, PrintFormatter::maxPrintfOutputLength); }); + char referenceOutput[maxPrintfOutputLength] = ""; + char actualOutput[maxPrintfOutputLength] = ""; + printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength); }); EXPECT_STREQ(referenceOutput, actualOutput); } @@ -311,10 +313,10 @@ TEST_P(PrintfFloatTest, GivenFormatContainingFloatWhenPrintingThenValueIsInserte storeData(stringIndex); injectValue(input.value); - char referenceOutput[PrintFormatter::maxPrintfOutputLength]; - char actualOutput[PrintFormatter::maxPrintfOutputLength]; + char referenceOutput[maxPrintfOutputLength]; + char actualOutput[maxPrintfOutputLength]; - printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, PrintFormatter::maxPrintfOutputLength, str, PrintFormatter::maxPrintfOutputLength); }); + printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength); }); snprintf(referenceOutput, sizeof(referenceOutput), input.format.c_str(), input.value); @@ -354,10 +356,10 @@ TEST_P(PrintfDoubleToFloatTest, GivenFormatContainingFloatAndDoubleWhenPrintingT storeData(stringIndex); injectValue(input.value); - char referenceOutput[PrintFormatter::maxPrintfOutputLength]; - char actualOutput[PrintFormatter::maxPrintfOutputLength]; + char referenceOutput[maxPrintfOutputLength]; + char actualOutput[maxPrintfOutputLength]; - printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, PrintFormatter::maxPrintfOutputLength, str, PrintFormatter::maxPrintfOutputLength); }); + printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength); }); snprintf(referenceOutput, sizeof(referenceOutput), input.format.c_str(), input.value); @@ -399,10 +401,10 @@ TEST_P(PrintfDoubleTest, GivenFormatContainingDoubleWhenPrintingThenValueIsInser storeData(stringIndex); injectValue(input.value); - char referenceOutput[PrintFormatter::maxPrintfOutputLength]; - char actualOutput[PrintFormatter::maxPrintfOutputLength]; + char referenceOutput[maxPrintfOutputLength]; + char actualOutput[maxPrintfOutputLength]; - printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, PrintFormatter::maxPrintfOutputLength, str, PrintFormatter::maxPrintfOutputLength); }); + printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength); }); if (input.format[input.format.length() - 1] == 'F') input.format[input.format.length() - 1] = 'f'; @@ -430,9 +432,9 @@ TEST_P(PrintfSpecialTest, GivenFormatContainingDoublePercentageWhenPrintingThenV auto stringIndex = injectFormatString(input.first); storeData(stringIndex); - char actualOutput[PrintFormatter::maxPrintfOutputLength]; + char actualOutput[maxPrintfOutputLength]; - printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, PrintFormatter::maxPrintfOutputLength, str, PrintFormatter::maxPrintfOutputLength); }); + printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength); }); EXPECT_STREQ(input.second.c_str(), actualOutput); } @@ -460,9 +462,9 @@ TEST_P(PrintfNoArgumentsTest, GivenNoArgumentsWhenPrintingThenCharsAreEscaped) { auto stringIndex = injectFormatString(input.first); storeData(stringIndex); - char actualOutput[PrintFormatter::maxPrintfOutputLength]; + char actualOutput[maxPrintfOutputLength]; - printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, PrintFormatter::maxPrintfOutputLength, str, PrintFormatter::maxPrintfOutputLength); }); + printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength); }); EXPECT_STREQ(input.second.c_str(), actualOutput); } @@ -487,10 +489,10 @@ TEST_P(PrintfStringTest, GivenFormatContainingStringWhenPrintingThenValueIsInser auto inputIndex = injectFormatString(input.value); injectStringValue(inputIndex); - char referenceOutput[PrintFormatter::maxPrintfOutputLength]; - char actualOutput[PrintFormatter::maxPrintfOutputLength]; + char referenceOutput[maxPrintfOutputLength]; + char actualOutput[maxPrintfOutputLength]; - printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, PrintFormatter::maxPrintfOutputLength, str, PrintFormatter::maxPrintfOutputLength); }); + printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength); }); snprintf(referenceOutput, sizeof(referenceOutput), input.format.c_str(), input.value.c_str()); @@ -501,6 +503,58 @@ INSTANTIATE_TEST_CASE_P(PrintfStringTest, PrintfStringTest, ::testing::ValuesIn(stringValues2)); +TEST_F(PrintFormatterTest, GivenLongStringValueWhenPrintedThenFullStringIsPrinted) { + char testedLongString[maxPrintfOutputLength]; + memset(testedLongString, 'a', maxPrintfOutputLength - 1); + testedLongString[maxPrintfOutputLength - 1] = '\0'; + + auto stringIndex = injectFormatString(testedLongString); + storeData(stringIndex); + + char actualOutput[maxPrintfOutputLength]; + + printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength); }); + + EXPECT_STREQ(testedLongString, actualOutput); +} + +TEST_F(PrintFormatterTest, GivenStringSpecifierWhenLongStringIsPassedAsValueThenFullStringIsPrinted) { + char testedLongString[maxPrintfOutputLength]; + memset(testedLongString, 'a', maxPrintfOutputLength - 5); + testedLongString[maxPrintfOutputLength - 5] = '\0'; + + auto stringIndex = injectFormatString("%s"); + storeData(stringIndex); + + auto inputIndex = injectFormatString(testedLongString); + injectStringValue(inputIndex); + + char actualOutput[maxPrintfOutputLength]; + + printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength); }); + + EXPECT_STREQ(testedLongString, actualOutput); +} + +TEST_F(PrintFormatterTest, GivenTooLongStringWhenPrintedThenOutputIsTruncated) { + std::unique_ptr testedLongString(new char[PrintFormatter::maxSinglePrintStringLength + 1024]); + memset(testedLongString.get(), 'a', PrintFormatter::maxSinglePrintStringLength + 1024 - 1); + testedLongString[PrintFormatter::maxSinglePrintStringLength + 1024 - 1] = '\0'; + + auto stringIndex = injectFormatString(testedLongString.get()); + storeData(stringIndex); + + std::unique_ptr actualOutput(new char[PrintFormatter::maxSinglePrintStringLength + 1024]); + + printFormatter->printKernelOutput([&actualOutput](char *str) { + size_t length = strnlen_s(str, PrintFormatter::maxSinglePrintStringLength + 1024); + strncpy_s(actualOutput.get(), PrintFormatter::maxSinglePrintStringLength + 1024, str, length); }); + + auto testedLength = strnlen_s(testedLongString.get(), PrintFormatter::maxSinglePrintStringLength + 1024); + auto actualLength = strnlen_s(actualOutput.get(), PrintFormatter::maxSinglePrintStringLength + 1024); + EXPECT_GT(testedLength, actualLength); +} + TEST_F(PrintFormatterTest, GivenNullTokenWhenPrintingThenNullIsInserted) { auto stringIndex = injectFormatString("%s"); storeData(stringIndex); @@ -508,9 +562,9 @@ TEST_F(PrintFormatterTest, GivenNullTokenWhenPrintingThenNullIsInserted) { storeData(PRINTF_DATA_TYPE::VECTOR_INT); storeData(0); - char actualOutput[PrintFormatter::maxPrintfOutputLength]; + char actualOutput[maxPrintfOutputLength]; - printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, PrintFormatter::maxPrintfOutputLength, str, PrintFormatter::maxPrintfOutputLength); }); + printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength); }); EXPECT_STREQ("(null)", actualOutput); } @@ -530,9 +584,9 @@ TEST_F(PrintFormatterTest, GivenVector2WhenPrintingThenAllValuesAreInserted) { for (int i = 0; i < channelCount; i++) storeData(i + 1); - char actualOutput[PrintFormatter::maxPrintfOutputLength]; + char actualOutput[maxPrintfOutputLength]; - printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, PrintFormatter::maxPrintfOutputLength, str, PrintFormatter::maxPrintfOutputLength); }); + printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength); }); EXPECT_STREQ("1,2", actualOutput); } @@ -551,9 +605,9 @@ TEST_F(PrintFormatterTest, GivenVector4WhenPrintingThenAllValuesAreInserted) { for (int i = 0; i < channelCount; i++) storeData(i + 1); - char actualOutput[PrintFormatter::maxPrintfOutputLength]; + char actualOutput[maxPrintfOutputLength]; - printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, PrintFormatter::maxPrintfOutputLength, str, PrintFormatter::maxPrintfOutputLength); }); + printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength); }); EXPECT_STREQ("1,2,3,4", actualOutput); } @@ -572,9 +626,9 @@ TEST_F(PrintFormatterTest, GivenVector8WhenPrintingThenAllValuesAreInserted) { for (int i = 0; i < channelCount; i++) storeData(i + 1); - char actualOutput[PrintFormatter::maxPrintfOutputLength]; + char actualOutput[maxPrintfOutputLength]; - printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, PrintFormatter::maxPrintfOutputLength, str, PrintFormatter::maxPrintfOutputLength); }); + printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength); }); EXPECT_STREQ("1,2,3,4,5,6,7,8", actualOutput); } @@ -593,9 +647,9 @@ TEST_F(PrintFormatterTest, GivenVector16WhenPrintingThenAllValuesAreInserted) { for (int i = 0; i < channelCount; i++) storeData(i + 1); - char actualOutput[PrintFormatter::maxPrintfOutputLength]; + char actualOutput[maxPrintfOutputLength]; - printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, PrintFormatter::maxPrintfOutputLength, str, PrintFormatter::maxPrintfOutputLength); }); + printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength); }); EXPECT_STREQ("1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16", actualOutput); } @@ -614,9 +668,9 @@ TEST_F(PrintFormatterTest, GivenVectorOfBytesWhenPrintingThenAllValuesAreInserte storeData(1); storeData(2); - char actualOutput[PrintFormatter::maxPrintfOutputLength]; + char actualOutput[maxPrintfOutputLength]; - printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, PrintFormatter::maxPrintfOutputLength, str, PrintFormatter::maxPrintfOutputLength); }); + printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength); }); EXPECT_STREQ("1,2", actualOutput); } @@ -634,9 +688,9 @@ TEST_F(PrintFormatterTest, GivenVectorOfShortsWhenPrintingThenAllValuesAreInsert storeData(1); storeData(2); - char actualOutput[PrintFormatter::maxPrintfOutputLength]; + char actualOutput[maxPrintfOutputLength]; - printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, PrintFormatter::maxPrintfOutputLength, str, PrintFormatter::maxPrintfOutputLength); }); + printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength); }); EXPECT_STREQ("1,2", actualOutput); } @@ -654,9 +708,9 @@ TEST_F(PrintFormatterTest, GivenVectorOfIntsWhenPrintingThenAllValuesAreInserted storeData(1); storeData(2); - char actualOutput[PrintFormatter::maxPrintfOutputLength]; + char actualOutput[maxPrintfOutputLength]; - printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, PrintFormatter::maxPrintfOutputLength, str, PrintFormatter::maxPrintfOutputLength); }); + printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength); }); EXPECT_STREQ("1,2", actualOutput); } @@ -674,9 +728,9 @@ TEST_F(PrintFormatterTest, GivenSpecialVectorWhenPrintingThenAllValuesAreInserte storeData(1); storeData(2); - char actualOutput[PrintFormatter::maxPrintfOutputLength]; + char actualOutput[maxPrintfOutputLength]; - printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, PrintFormatter::maxPrintfOutputLength, str, PrintFormatter::maxPrintfOutputLength); }); + printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength); }); EXPECT_STREQ("1,2", actualOutput); } @@ -693,9 +747,9 @@ TEST_F(PrintFormatterTest, GivenVectorOfLongsWhenPrintingThenAllValuesAreInserte storeData(1); storeData(2); - char actualOutput[PrintFormatter::maxPrintfOutputLength]; + char actualOutput[maxPrintfOutputLength]; - printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, PrintFormatter::maxPrintfOutputLength, str, PrintFormatter::maxPrintfOutputLength); }); + printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength); }); EXPECT_STREQ("1,2", actualOutput); } @@ -713,9 +767,9 @@ TEST_F(PrintFormatterTest, GivenVectorOfFloatsWhenPrintingThenAllValuesAreInsert storeData(1.0); storeData(2.0); - char actualOutput[PrintFormatter::maxPrintfOutputLength]; + char actualOutput[maxPrintfOutputLength]; - printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, PrintFormatter::maxPrintfOutputLength, str, PrintFormatter::maxPrintfOutputLength); }); + printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength); }); EXPECT_STREQ("1.000000,2.000000", actualOutput); } @@ -733,9 +787,9 @@ TEST_F(PrintFormatterTest, GivenVectorOfDoublesWhenPrintingThenAllValuesAreInser storeData(1.0); storeData(2.0); - char actualOutput[PrintFormatter::maxPrintfOutputLength]; + char actualOutput[maxPrintfOutputLength]; - printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, PrintFormatter::maxPrintfOutputLength, str, PrintFormatter::maxPrintfOutputLength); }); + printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength); }); EXPECT_STREQ("1.000000,2.000000", actualOutput); } @@ -756,18 +810,18 @@ TEST_F(PrintFormatterTest, GivenPointerWhenPrintingThenValueIsInserted) { storeData(padding); } - char actualOutput[PrintFormatter::maxPrintfOutputLength]; - char referenceOutput[PrintFormatter::maxPrintfOutputLength]; + char actualOutput[maxPrintfOutputLength]; + char referenceOutput[maxPrintfOutputLength]; snprintf(referenceOutput, sizeof(referenceOutput), "%p", reinterpret_cast(&temp)); - printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, PrintFormatter::maxPrintfOutputLength, str, PrintFormatter::maxPrintfOutputLength); }); + printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength); }); EXPECT_STREQ(referenceOutput, actualOutput); } TEST_F(PrintFormatterTest, GivenPointerWith32BitKernelWhenPrintingThen32BitPointerIsPrinted) { - printFormatter.reset(new PrintFormatter(static_cast(data->getUnderlyingBuffer()), PrintFormatter::maxPrintfOutputLength, true, kernelInfo->patchInfo.stringDataMap)); + printFormatter.reset(new PrintFormatter(static_cast(data->getUnderlyingBuffer()), printfBufferSize, true, kernelInfo->patchInfo.stringDataMap)); auto stringIndex = injectFormatString("%p"); storeData(stringIndex); kernelInfo->gpuPointerSize = 4; @@ -784,12 +838,12 @@ TEST_F(PrintFormatterTest, GivenPointerWith32BitKernelWhenPrintingThen32BitPoint uint32_t padding = 0xdeadbeef; storeData(padding); - char actualOutput[PrintFormatter::maxPrintfOutputLength]; - char referenceOutput[PrintFormatter::maxPrintfOutputLength]; + char actualOutput[maxPrintfOutputLength]; + char referenceOutput[maxPrintfOutputLength]; snprintf(referenceOutput, sizeof(referenceOutput), "%p", pointer); - printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, PrintFormatter::maxPrintfOutputLength, str, PrintFormatter::maxPrintfOutputLength); }); + printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength); }); EXPECT_STREQ(referenceOutput, actualOutput); } @@ -824,17 +878,17 @@ TEST_F(PrintFormatterTest, Given2ByteVectorsWhenPrintingThenDataBufferParsedProp for (int i = 0; i < 12; i++) storeData(static_cast(0)); - char actualOutput[PrintFormatter::maxPrintfOutputLength]; + char actualOutput[maxPrintfOutputLength]; - printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, PrintFormatter::maxPrintfOutputLength, str, PrintFormatter::maxPrintfOutputLength); }); + printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength); }); EXPECT_STREQ("1,2,3,4 1,2,3,4", actualOutput); } TEST_F(PrintFormatterTest, GivenEmptyBufferWhenPrintingThenFailSafely) { - char actualOutput[PrintFormatter::maxPrintfOutputLength]; + char actualOutput[maxPrintfOutputLength]; actualOutput[0] = 0; - printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, PrintFormatter::maxPrintfOutputLength, str, PrintFormatter::maxPrintfOutputLength); }); + printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength); }); EXPECT_STREQ("", actualOutput); } diff --git a/shared/source/program/print_formatter.cpp b/shared/source/program/print_formatter.cpp index 68ad50ce12..1be9c0d199 100644 --- a/shared/source/program/print_formatter.cpp +++ b/shared/source/program/print_formatter.cpp @@ -19,6 +19,8 @@ PrintFormatter::PrintFormatter(const uint8_t *printfOutputBuffer, uint32_t print printfOutputBufferSize(printfOutputBufferMaxSize), stringLiteralMap(stringLiteralMap), using32BitPointers(using32BitPointers) { + + output.reset(new char[maxSinglePrintStringLength]); } void PrintFormatter::printKernelOutput(const std::function &print) { @@ -40,10 +42,11 @@ void PrintFormatter::printKernelOutput(const std::function &print) } void PrintFormatter::printString(const char *formatString, const std::function &print) { - size_t length = strnlen_s(formatString, maxPrintfOutputLength); - char output[maxPrintfOutputLength]; + size_t length = strnlen_s(formatString, maxSinglePrintStringLength - 1); size_t cursor = 0; + std::unique_ptr dataFormat(new char[length + 1]); + for (size_t i = 0; i <= length; i++) { if (formatString[i] == '\\') output[cursor++] = escapeChar(formatString[++i]); @@ -56,23 +59,22 @@ void PrintFormatter::printString(const char *formatString, const std::function @@ -47,7 +48,7 @@ class PrintFormatter { bool using32BitPointers, const StringMap &stringLiteralMap); void printKernelOutput(const std::function &print = [](char *str) { printToSTDOUT(str); }); - static const size_t maxPrintfOutputLength = 1024; + constexpr static size_t maxSinglePrintStringLength = 16 * MemoryConstants::kiloByte; protected: const char *queryPrintfString(uint32_t index) const; @@ -112,6 +113,8 @@ class PrintFormatter { return charactersPrinted; } + std::unique_ptr output; + const uint8_t *printfOutputBuffer = nullptr; // buffer extracted from the kernel, contains values to be printed uint32_t printfOutputBufferSize = 0; // size of the data contained in the buffer