Bug Summary

File:jdk/test/hotspot/gtest/logging/logTestUtils.inline.hpp
Warning:line 154, column 24
The left operand of '==' is a garbage value due to array index out of bounds

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name test_logFileOutput.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mthread-model posix -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/libjvm/gtest/objs/precompiled -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS -D _GNU_SOURCE -D _REENTRANT -D LIBC=gnu -D LINUX -D VM_LITTLE_ENDIAN -D _LP64=1 -D ASSERT -D CHECK_UNHANDLED_OOPS -D TARGET_ARCH_x86 -D INCLUDE_SUFFIX_OS=_linux -D INCLUDE_SUFFIX_CPU=_x86 -D INCLUDE_SUFFIX_COMPILER=_gcc -D TARGET_COMPILER_gcc -D AMD64 -D HOTSPOT_LIB_ARCH="amd64" -D COMPILER1 -D COMPILER2 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc/adfiles -I /home/daniel/Projects/java/jdk/src/hotspot/share -I /home/daniel/Projects/java/jdk/src/hotspot/os/linux -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix -I /home/daniel/Projects/java/jdk/src/hotspot/cpu/x86 -I /home/daniel/Projects/java/jdk/src/hotspot/os_cpu/linux_x86 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc -I /home/daniel/Projects/java/jdk/src/hotspot/share/precompiled -I /home/daniel/Projects/java/jdk/src/hotspot/share/include -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix/include -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base/linux -I /home/daniel/Projects/java/jdk/src/java.base/share/native/libjimage -I /home/daniel/Projects/java/googletest/googletest/include -I /home/daniel/Projects/java/googletest/googlemock/include -I /home/daniel/Projects/java/jdk/test/hotspot/gtest -I /home/daniel/Projects/java/jdk/test/hotspot/gtest -D _FORTIFY_SOURCE=2 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/x86_64-linux-gnu/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/x86_64-linux-gnu/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-format-zero-length -Wno-unused-parameter -Wno-unused -Wno-parentheses -Wno-comment -Wno-unknown-pragmas -Wno-address -Wno-delete-non-virtual-dtor -Wno-char-subscripts -Wno-array-bounds -Wno-int-in-bool-context -Wno-ignored-qualifiers -Wno-missing-field-initializers -Wno-implicit-fallthrough -Wno-empty-body -Wno-strict-overflow -Wno-sequence-point -Wno-maybe-uninitialized -Wno-misleading-indentation -Wno-cast-function-type -Wno-shift-negative-value -Wno-undef -Wno-stringop-overflow -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /home/daniel/Projects/java/jdk/make/hotspot -ferror-limit 19 -fmessage-length 0 -fvisibility hidden -stack-protector 1 -fno-rtti -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /home/daniel/Projects/java/scan/2021-12-21-193737-8510-1 -x c++ /home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/test_logFileOutput.cpp

/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/test_logFileOutput.cpp

1/*
2 * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24#include "precompiled.hpp"
25#include "jvm.h"
26#include "logTestUtils.inline.hpp"
27#include "logging/logFileOutput.hpp"
28#include "memory/resourceArea.hpp"
29#include "runtime/os.hpp"
30#include "unittest.hpp"
31#include "utilities/globalDefinitions.hpp"
32#include "utilities/ostream.hpp"
33
34static const char* name = prepend_prefix_temp_dir("file=", "testlog.pid%p.%t.log");
35
36// Test parsing a bunch of valid file output options
37TEST_VM(LogFileOutput, parse_valid)class LogFileOutput_parse_valid_vm_Test : public ::testing::Test
{ public: LogFileOutput_parse_valid_vm_Test() {} private: virtual
void TestBody(); static ::testing::TestInfo* const test_info_
__attribute__ ((unused)); LogFileOutput_parse_valid_vm_Test(
LogFileOutput_parse_valid_vm_Test const &) = delete; void
operator=(LogFileOutput_parse_valid_vm_Test const &) = delete
;};::testing::TestInfo* const LogFileOutput_parse_valid_vm_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo(
"LogFileOutput", "parse_valid_vm", __null, __null, ::testing
::internal::CodeLocation("/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/test_logFileOutput.cpp"
, 37), (::testing::internal::GetTestTypeId()), ::testing::Test
::SetUpTestCase, ::testing::Test::TearDownTestCase, new ::testing
::internal::TestFactoryImpl< LogFileOutput_parse_valid_vm_Test
>);void LogFileOutput_parse_valid_vm_Test::TestBody()
{
38 const char* valid_options[] = {
39 "", "filecount=10", "filesize=512",
40 "filecount=11,filesize=256",
41 "filesize=256,filecount=11",
42 "filesize=0", "filecount=1",
43 "filesize=1m", "filesize=1M",
44 "filesize=1k", "filesize=1G"
45 };
46
47 // Override LogOutput's vm_start time to get predictable file name
48 LogFileOutput::set_file_name_parameters(0);
49
50 for (size_t i = 0; i < ARRAY_SIZE(valid_options)sizeof(array_size_impl(valid_options)); i++) {
51 ResourceMark rm;
52 stringStream ss;
53 {
54 LogFileOutput fo(name);
55 EXPECT_STREQ(name, fo.name())switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::CmpHelperSTREQ("name", "fo.name()"
, name, fo.name()))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/test_logFileOutput.cpp"
, 55, gtest_ar.failure_message()) = ::testing::Message()
;
56 EXPECT_TRUE(fo.initialize(valid_options[i], &ss))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(fo.initialize(valid_options
[i], &ss))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/test_logFileOutput.cpp"
, 56, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "fo.initialize(valid_options[i], &ss)", "false", "true"
).c_str()) = ::testing::Message()
57 << "Did not accept valid option(s) '" << valid_options[i] << "': " << ss.as_string();
58 remove(fo.cur_log_file_name());
59 }
60 }
61}
62
63// Test parsing a bunch of invalid file output options
64TEST_VM(LogFileOutput, parse_invalid)class LogFileOutput_parse_invalid_vm_Test : public ::testing::
Test { public: LogFileOutput_parse_invalid_vm_Test() {} private
: virtual void TestBody(); static ::testing::TestInfo* const test_info_
__attribute__ ((unused)); LogFileOutput_parse_invalid_vm_Test
(LogFileOutput_parse_invalid_vm_Test const &) = delete; void
operator=(LogFileOutput_parse_invalid_vm_Test const &) =
delete;};::testing::TestInfo* const LogFileOutput_parse_invalid_vm_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo(
"LogFileOutput", "parse_invalid_vm", __null, __null, ::testing
::internal::CodeLocation("/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/test_logFileOutput.cpp"
, 64), (::testing::internal::GetTestTypeId()), ::testing::Test
::SetUpTestCase, ::testing::Test::TearDownTestCase, new ::testing
::internal::TestFactoryImpl< LogFileOutput_parse_invalid_vm_Test
>);void LogFileOutput_parse_invalid_vm_Test::TestBody()
{
65 const char* invalid_options[] = {
66 "invalidopt", "filecount=",
67 "filesize=,filecount=10",
68 "fileco=10", "ilesize=512",
69 "filecount=11,,filesize=256",
70 ",filesize=256,filecount=11",
71 "filesize=256,filecount=11,",
72 "filesize=-1", "filecount=0.1",
73 "filecount=-2", "filecount=2.0",
74 "filecount= 2", "filesize=2 ",
75 "filecount=ab", "filesize=0xz",
76 "filecount=1MB", "filesize=99bytes",
77 "filesize=9999999999999999999999999",
78 "filecount=9999999999999999999999999"
79 };
80
81 for (size_t i = 0; i < ARRAY_SIZE(invalid_options)sizeof(array_size_impl(invalid_options)); i++) {
82 ResourceMark rm;
83 stringStream ss;
84 LogFileOutput fo(name);
85 EXPECT_FALSE(fo.initialize(invalid_options[i], &ss))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(fo.initialize(invalid_options
[i], &ss)))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/test_logFileOutput.cpp"
, 85, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "fo.initialize(invalid_options[i], &ss)", "true", "false"
).c_str()) = ::testing::Message()
86 << "Accepted invalid option(s) '" << invalid_options[i] << "': " << ss.as_string();
87 }
88}
89
90// Test for overflows with filesize
91TEST_VM(LogFileOutput, filesize_overflow)class LogFileOutput_filesize_overflow_vm_Test : public ::testing
::Test { public: LogFileOutput_filesize_overflow_vm_Test() {}
private: virtual void TestBody(); static ::testing::TestInfo
* const test_info_ __attribute__ ((unused)); LogFileOutput_filesize_overflow_vm_Test
(LogFileOutput_filesize_overflow_vm_Test const &) = delete
; void operator=(LogFileOutput_filesize_overflow_vm_Test const
&) = delete;};::testing::TestInfo* const LogFileOutput_filesize_overflow_vm_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo(
"LogFileOutput", "filesize_overflow_vm", __null, __null, ::testing
::internal::CodeLocation("/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/test_logFileOutput.cpp"
, 91), (::testing::internal::GetTestTypeId()), ::testing::Test
::SetUpTestCase, ::testing::Test::TearDownTestCase, new ::testing
::internal::TestFactoryImpl< LogFileOutput_filesize_overflow_vm_Test
>);void LogFileOutput_filesize_overflow_vm_Test::TestBody(
)
{
92 char buf[256];
93 int ret = jio_snprintf(buf, sizeof(buf), "filesize=" SIZE_FORMAT"%" "l" "u" "K", SIZE_MAX(18446744073709551615UL));
94 ASSERT_GT(ret, 0)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::CmpHelperGT("ret", "0", ret
, 0))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/test_logFileOutput.cpp"
, 94, gtest_ar.failure_message()) = ::testing::Message()
<< "Buffer too small";
95
96 ResourceMark rm;
97 stringStream ss;
98 LogFileOutput fo(name);
99 EXPECT_FALSE(fo.initialize(buf, &ss))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(fo.initialize(buf, &
ss)))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/test_logFileOutput.cpp"
, 99, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "fo.initialize(buf, &ss)", "true", "false").c_str()) = ::
testing::Message()
<< "Accepted filesize that overflows";
100}
101
102TEST_VM(LogFileOutput, startup_rotation)class LogFileOutput_startup_rotation_vm_Test : public ::testing
::Test { public: LogFileOutput_startup_rotation_vm_Test() {} private
: virtual void TestBody(); static ::testing::TestInfo* const test_info_
__attribute__ ((unused)); LogFileOutput_startup_rotation_vm_Test
(LogFileOutput_startup_rotation_vm_Test const &) = delete
; void operator=(LogFileOutput_startup_rotation_vm_Test const
&) = delete;};::testing::TestInfo* const LogFileOutput_startup_rotation_vm_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo(
"LogFileOutput", "startup_rotation_vm", __null, __null, ::testing
::internal::CodeLocation("/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/test_logFileOutput.cpp"
, 102), (::testing::internal::GetTestTypeId()), ::testing::Test
::SetUpTestCase, ::testing::Test::TearDownTestCase, new ::testing
::internal::TestFactoryImpl< LogFileOutput_startup_rotation_vm_Test
>);void LogFileOutput_startup_rotation_vm_Test::TestBody()
{
103 ResourceMark rm;
104 const size_t rotations = 5;
105 const char* filename = prepend_temp_dir("start-rotate-test");
106 char* rotated_file[rotations];
107
108 for (size_t i = 0; i < rotations; i++) {
109 size_t len = strlen(filename) + 3;
110 rotated_file[i] = NEW_RESOURCE_ARRAY(char, len)(char*) resource_allocate_bytes((len) * sizeof(char));
111 int ret = jio_snprintf(rotated_file[i], len, "%s." SIZE_FORMAT"%" "l" "u", filename, i);
112 ASSERT_NE(-1, ret)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar = (::testing::internal::CmpHelperNE("-1", "ret", -1
, ret))) ; else return ::testing::internal::AssertHelper(::testing
::TestPartResult::kFatalFailure, "/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/test_logFileOutput.cpp"
, 112, gtest_ar.failure_message()) = ::testing::Message()
;
113 delete_file(rotated_file[i]);
114 }
115
116 delete_file(filename);
117 init_log_file(filename);
118 ASSERT_TRUE(file_exists(filename))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(file_exists(filename)
)) ; else return ::testing::internal::AssertHelper(::testing::
TestPartResult::kFatalFailure, "/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/test_logFileOutput.cpp"
, 118, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "file_exists(filename)", "false", "true").c_str()) = ::testing
::Message()
119 << "configured logging to file '" << filename << "' but file was not found";
120
121 // Initialize the same file a bunch more times to trigger rotations
122 for (size_t i = 0; i < rotations; i++) {
123 init_log_file(filename);
124 EXPECT_TRUE(file_exists(rotated_file[i]))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(file_exists(rotated_file
[i]))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/test_logFileOutput.cpp"
, 124, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "file_exists(rotated_file[i])", "false", "true").c_str()) =
::testing::Message()
;
125 }
126
127 // Remove a file and expect its slot to be re-used
128 delete_file(rotated_file[1]);
129 init_log_file(filename);
130 EXPECT_TRUE(file_exists(rotated_file[1]))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(file_exists(rotated_file
[1]))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/test_logFileOutput.cpp"
, 130, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "file_exists(rotated_file[1])", "false", "true").c_str()) =
::testing::Message()
;
131
132 // Clean up after test
133 delete_file(filename);
134 for (size_t i = 0; i < rotations; i++) {
135 delete_file(rotated_file[i]);
136 }
137}
138
139TEST_VM(LogFileOutput, startup_truncation)class LogFileOutput_startup_truncation_vm_Test : public ::testing
::Test { public: LogFileOutput_startup_truncation_vm_Test() {
} private: virtual void TestBody(); static ::testing::TestInfo
* const test_info_ __attribute__ ((unused)); LogFileOutput_startup_truncation_vm_Test
(LogFileOutput_startup_truncation_vm_Test const &) = delete
; void operator=(LogFileOutput_startup_truncation_vm_Test const
&) = delete;};::testing::TestInfo* const LogFileOutput_startup_truncation_vm_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo(
"LogFileOutput", "startup_truncation_vm", __null, __null, ::
testing::internal::CodeLocation("/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/test_logFileOutput.cpp"
, 139), (::testing::internal::GetTestTypeId()), ::testing::Test
::SetUpTestCase, ::testing::Test::TearDownTestCase, new ::testing
::internal::TestFactoryImpl< LogFileOutput_startup_truncation_vm_Test
>);void LogFileOutput_startup_truncation_vm_Test::TestBody
()
{
140 ResourceMark rm;
141 const char* filename = prepend_temp_dir("start-truncate-test");
142 const char* archived_filename = prepend_temp_dir("start-truncate-test.0");
143
144 delete_file(filename);
145 delete_file(archived_filename);
146
147 // Use the same log file twice and expect it to be overwritten/truncated
148 init_log_file(filename, "filecount=0");
149 ASSERT_TRUE(file_exists(filename))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(file_exists(filename)
)) ; else return ::testing::internal::AssertHelper(::testing::
TestPartResult::kFatalFailure, "/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/test_logFileOutput.cpp"
, 149, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "file_exists(filename)", "false", "true").c_str()) = ::testing
::Message()
1
Control jumps to 'case 0:' at line 149
2
Taking true branch
150 << "configured logging to file '" << filename << "' but file was not found";
151
152 init_log_file(filename, "filecount=0");
153 ASSERT_TRUE(file_exists(filename))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(file_exists(filename)
)) ; else return ::testing::internal::AssertHelper(::testing::
TestPartResult::kFatalFailure, "/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/test_logFileOutput.cpp"
, 153, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "file_exists(filename)", "false", "true").c_str()) = ::testing
::Message()
3
Control jumps to 'case 0:' at line 153
4
Taking true branch
154 << "configured logging to file '" << filename << "' but file was not found";
155 EXPECT_FALSE(file_exists(archived_filename))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(file_exists(archived_filename
)))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/test_logFileOutput.cpp"
, 155, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "file_exists(archived_filename)", "true", "false").c_str())
= ::testing::Message()
5
Control jumps to 'case 0:' at line 155
6
Taking true branch
156 << "existing log file was not properly truncated when filecount was 0";
157
158 // Verify that the file was really truncated and not just appended
159 EXPECT_TRUE(file_contains_substring(filename, LOG_TEST_STRING_LITERAL))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(file_contains_substring
(filename, "a (hopefully) unique log message for testing"))) ;
else ::testing::internal::AssertHelper(::testing::TestPartResult
::kNonFatalFailure, "/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/test_logFileOutput.cpp"
, 159, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "file_contains_substring(filename, LOG_TEST_STRING_LITERAL)"
, "false", "true").c_str()) = ::testing::Message()
;
7
Control jumps to 'case 0:' at line 159
8
Taking false branch
160 const char* repeated[] = { LOG_TEST_STRING_LITERAL"a (hopefully) unique log message for testing", LOG_TEST_STRING_LITERAL"a (hopefully) unique log message for testing" };
161 EXPECT_FALSE(file_contains_substrings_in_order(filename, repeated))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(file_contains_substrings_in_order
(filename, repeated)))) ; else ::testing::internal::AssertHelper
(::testing::TestPartResult::kNonFatalFailure, "/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/test_logFileOutput.cpp"
, 161, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "file_contains_substrings_in_order(filename, repeated)", "true"
, "false").c_str()) = ::testing::Message()
9
Control jumps to 'case 0:' at line 161
10
Calling 'file_contains_substrings_in_order'
162 << "log file " << filename << " appended rather than truncated";
163
164 delete_file(filename);
165 delete_file(archived_filename);
166}
167
168TEST_VM(LogFileOutput, invalid_file)class LogFileOutput_invalid_file_vm_Test : public ::testing::
Test { public: LogFileOutput_invalid_file_vm_Test() {} private
: virtual void TestBody(); static ::testing::TestInfo* const test_info_
__attribute__ ((unused)); LogFileOutput_invalid_file_vm_Test
(LogFileOutput_invalid_file_vm_Test const &) = delete; void
operator=(LogFileOutput_invalid_file_vm_Test const &) = delete
;};::testing::TestInfo* const LogFileOutput_invalid_file_vm_Test
::test_info_ = ::testing::internal::MakeAndRegisterTestInfo(
"LogFileOutput", "invalid_file_vm", __null, __null, ::testing
::internal::CodeLocation("/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/test_logFileOutput.cpp"
, 168), (::testing::internal::GetTestTypeId()), ::testing::Test
::SetUpTestCase, ::testing::Test::TearDownTestCase, new ::testing
::internal::TestFactoryImpl< LogFileOutput_invalid_file_vm_Test
>);void LogFileOutput_invalid_file_vm_Test::TestBody()
{
169 ResourceMark rm;
170 stringStream ss;
171
172 // Attempt to log to a directory (existing log not a regular file)
173 create_directory("tmplogdir");
174 LogFileOutput bad_file("file=tmplogdir");
175 EXPECT_FALSE(bad_file.initialize("", &ss))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(bad_file.initialize
("", &ss)))) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/test_logFileOutput.cpp"
, 175, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "bad_file.initialize(\"\", &ss)", "true", "false").c_str
()) = ::testing::Message()
176 << "file was initialized when there was an existing directory with the same name";
177 EXPECT_TRUE(string_contains_substring(ss.as_string(), "tmplogdir is not a regular file"))switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(string_contains_substring
(ss.as_string(), "tmplogdir is not a regular file"))) ; else ::
testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/test_logFileOutput.cpp"
, 177, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "string_contains_substring(ss.as_string(), \"tmplogdir is not a regular file\")"
, "false", "true").c_str()) = ::testing::Message()
178 << "missing expected error message, received msg: %s" << ss.as_string();
179 delete_empty_directory("tmplogdir");
180}

/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/logTestUtils.inline.hpp

1/*
2 * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24#include "logging/log.hpp"
25#include "logging/logAsyncWriter.hpp"
26#include "logging/logConfiguration.hpp"
27#include "logging/logStream.hpp"
28#include "memory/resourceArea.hpp"
29#include "runtime/os.hpp"
30#include "unittest.hpp"
31
32#define LOG_TEST_STRING_LITERAL"a (hopefully) unique log message for testing" "a (hopefully) unique log message for testing"
33
34static const char* invalid_selection_substr[] = {
35 "=", "+", " ", "+=", "+=*", "*+", " +", "**", "++", ".", ",", ",,", ",+",
36 " *", "all+", "all*", "+all", "+all=Warning", "==Info", "=InfoWarning",
37 "BadTag+", "logging++", "logging*+", ",=", "gc+gc+"
38};
39
40static inline bool string_contains_substring(const char* haystack, const char* needle) {
41 return strstr(haystack, needle) != NULL__null;
42}
43
44static inline bool file_exists(const char* filename) {
45 struct stat st;
46 return os::stat(filename, &st) == 0;
47}
48
49static inline void delete_file(const char* filename) {
50 AsyncLogWriter::flush();
51 if (!file_exists(filename)) {
52 return;
53 }
54 int ret = remove(filename);
55 EXPECT_TRUE(ret == 0 || errno == ENOENT)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(ret == 0 || (*__errno_location
()) == 2)) ; else ::testing::internal::AssertHelper(::testing
::TestPartResult::kNonFatalFailure, "/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/logTestUtils.inline.hpp"
, 55, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "ret == 0 || errno == ENOENT", "false", "true").c_str()) = ::
testing::Message()
<< "failed to remove file '" << filename << "': "
56 << os::strerror(errno(*__errno_location ())) << " (" << errno(*__errno_location ()) << ")";
57}
58
59static inline void create_directory(const char* name) {
60 assert(!file_exists(name), "can't create directory: %s already exists", name)do { if (!(!file_exists(name))) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/logTestUtils.inline.hpp"
, 60, "assert(" "!file_exists(name)" ") failed", "can't create directory: %s already exists"
, name); ::breakpoint(); } } while (0)
;
61 bool failed;
62#ifdef _WINDOWS
63 failed = !CreateDirectory(name, NULL__null);
64#else
65 failed = mkdir(name, 0777);
66#endif
67 assert(!failed, "failed to create directory %s", name)do { if (!(!failed)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/logTestUtils.inline.hpp"
, 67, "assert(" "!failed" ") failed", "failed to create directory %s"
, name); ::breakpoint(); } } while (0)
;
68}
69
70static inline void delete_empty_directory(const char* name) {
71#ifdef _WINDOWS
72 if (!file_exists(name)) {
73 return;
74 }
75 bool failed;
76 failed = !RemoveDirectory(name);
77 EXPECT_FALSE(failed)switch (0) case 0: default: if (const ::testing::AssertionResult
gtest_ar_ = ::testing::AssertionResult(!(failed))) ; else ::
testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure
, "/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/logTestUtils.inline.hpp"
, 77, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_
, "failed", "true", "false").c_str()) = ::testing::Message()
<< "failed to remove directory '" << name
78 << "': LastError = " << GetLastError();
79#else
80 delete_file(name);
81#endif
82}
83
84static inline void init_log_file(const char* filename, const char* options = "") {
85 LogStreamHandle(Error, logging)LogStreamTemplate<LogLevel::Error, (LogTag::_logging), (LogTag
::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::
__NO_TAG), (LogTag::__NO_TAG)>
stream;
86 bool success = LogConfiguration::parse_log_arguments(filename, "logging=trace", "", options, &stream);
87 guarantee(success, "Failed to initialize log file '%s' with options '%s'", filename, options)do { if (!(success)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/logTestUtils.inline.hpp"
, 87, "guarantee(" "success" ") failed", "Failed to initialize log file '%s' with options '%s'"
, filename, options); ::breakpoint(); } } while (0)
;
88 log_debug(logging)(!(LogImpl<(LogTag::_logging), (LogTag::__NO_TAG), (LogTag
::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::
__NO_TAG)>::is_level(LogLevel::Debug))) ? (void)0 : LogImpl
<(LogTag::_logging), (LogTag::__NO_TAG), (LogTag::__NO_TAG
), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG)
>::write<LogLevel::Debug>
("%s", LOG_TEST_STRING_LITERAL"a (hopefully) unique log message for testing");
89 success = LogConfiguration::parse_log_arguments(filename, "all=off", "", "", &stream);
90 guarantee(success, "Failed to disable logging to file '%s'", filename)do { if (!(success)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/logTestUtils.inline.hpp"
, 90, "guarantee(" "success" ") failed", "Failed to disable logging to file '%s'"
, filename); ::breakpoint(); } } while (0)
;
91}
92
93static const char* tmp_dir = os::get_temp_directory();
94static const char* file_sep = os::file_separator();
95
96// Prepend filename with the temp directory and pid and return the result as a
97// resource allocated string.
98static inline char* prepend_temp_dir(const char* filename) {
99 size_t temp_file_len = strlen(tmp_dir) + strlen(file_sep) + strlen(filename) + 28;
100 char* temp_file = NEW_RESOURCE_ARRAY(char, temp_file_len)(char*) resource_allocate_bytes((temp_file_len) * sizeof(char
))
;
101 int ret = jio_snprintf(temp_file, temp_file_len, "%s%spid%d.%s",
102 tmp_dir, file_sep,
103 os::current_process_id(), filename);
104 return temp_file;
105}
106
107// Prepend filename with specified prefix and the temp directory and return the
108// result as a malloc allocated string. This is used by test_logFileOutput.cpp.
109static inline char* prepend_prefix_temp_dir(const char* prefix, const char* filename) {
110 size_t temp_file_len = strlen(prefix) + strlen(tmp_dir) + strlen(file_sep) + strlen(filename) + 1;
111 char* temp_file = (char*)os::malloc(temp_file_len, mtLogging);
112 int ret = jio_snprintf(temp_file, temp_file_len, "%s%s%s%s",
113 prefix, tmp_dir, file_sep, filename);
114 return temp_file;
115}
116
117// Read a complete line from fp and return it as a resource allocated string.
118// Returns NULL on EOF.
119static inline char* read_line(FILE* fp) {
120 assert(fp != NULL, "invalid fp")do { if (!(fp != __null)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/logTestUtils.inline.hpp"
, 120, "assert(" "fp != __null" ") failed", "invalid fp"); ::
breakpoint(); } } while (0)
;
121 int buflen = 512;
122 char* buf = NEW_RESOURCE_ARRAY(char, buflen)(char*) resource_allocate_bytes((buflen) * sizeof(char));
123 long pos = ftell(fp);
124 if (pos < 0) return NULL__null;
125
126 char* ret = fgets(buf, buflen, fp);
127 while (ret != NULL__null && buf[strlen(buf) - 1] != '\n' && !feof(fp)) {
128 // retry with a larger buffer
129 buf = REALLOC_RESOURCE_ARRAY(char, buf, buflen, buflen * 2)(char*) resource_reallocate_bytes((char*)(buf), (buflen) * sizeof
(char), (buflen * 2) * sizeof(char))
;
130 buflen *= 2;
131 // rewind to beginning of line
132 fseek(fp, pos, SEEK_SET0);
133 // retry read with new buffer
134 ret = fgets(buf, buflen, fp);
135 }
136 return ret;
137}
138
139static bool file_contains_substrings_in_order(const char* filename, const char* substrs[]) {
140 AsyncLogWriter::flush();
141 FILE* fp = fopen(filename, "r");
142 assert(fp != NULL, "error opening file %s: %s", filename, strerror(errno))do { if (!(fp != __null)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/test/hotspot/gtest/logging/logTestUtils.inline.hpp"
, 142, "assert(" "fp != __null" ") failed", "error opening file %s: %s"
, filename, strerror((*__errno_location ()))); ::breakpoint()
; } } while (0)
;
11
Assuming the condition is true
12
Taking false branch
13
Loop condition is false. Exiting loop
143
144 size_t idx = 0;
145 while (substrs[idx] != NULL__null) {
14
Loop condition is true. Entering loop body
146 ResourceMark rm;
147 char* line = read_line(fp);
148 if (line
14.1
'line' is not equal to NULL
14.1
'line' is not equal to NULL
== NULL__null) {
15
Taking false branch
149 break;
150 }
151 for (char* match = strstr(line, substrs[idx]); match != NULL__null;) {
16
Assuming 'match' is not equal to NULL
17
Loop condition is true. Entering loop body
19
Assuming 'match' is not equal to NULL
20
Loop condition is true. Entering loop body
152 size_t match_len = strlen(substrs[idx]);
153 idx++;
21
The value 2 is assigned to 'idx'
154 if (substrs[idx] == NULL__null) {
18
Taking false branch
22
The left operand of '==' is a garbage value due to array index out of bounds
155 break;
156 }
157 match = strstr(match + match_len, substrs[idx]);
158 }
159 }
160
161 fclose(fp);
162 return substrs[idx] == NULL__null;
163}
164
165static inline bool file_contains_substring(const char* filename, const char* substr) {
166 const char* strs[] = {substr, NULL__null};
167 return file_contains_substrings_in_order(filename, strs);
168}