25
#include "precompiled.hpp"
26
#include "cds/classListWriter.hpp"
27
#include "compiler/compileLog.hpp"
29
#include "memory/allocation.inline.hpp"
30
#include "oops/oop.inline.hpp"
31
#include "runtime/arguments.hpp"
32
#include "runtime/mutexLocker.hpp"
33
#include "runtime/orderAccess.hpp"
34
#include "runtime/os.inline.hpp"
35
#include "runtime/safepoint.hpp"
36
#include "runtime/vm_version.hpp"
37
#include "utilities/defaultStream.hpp"
38
#include "utilities/macros.hpp"
39
#include "utilities/ostream.hpp"
40
#include "utilities/vmError.hpp"
41
#include "utilities/xmlstream.hpp"
44
extern "C" void jio_print(const char* s, size_t len);
45
extern "C" int jio_printf(const char *fmt, ...);
47
outputStream::outputStream(bool has_time_stamps) {
54
if (has_time_stamps) _stamp.update();
57
bool outputStream::update_position(const char* s, size_t len) {
58
bool saw_newline = false;
59
for (size_t i = 0; i < len; i++) {
63
_precount += _position + 1;
65
} else if (ch == '\t') {
66
int tw = 8 - (_position & 7);
80
const char* outputStream::do_vsnprintf(char* buffer, size_t buflen,
81
const char* format, va_list ap,
84
assert(buflen >= 2, "buffer too small");
87
size_t required_len = 0;
94
if (!strchr(format, '%')) {
97
result_len = strlen(result);
98
if (add_cr && result_len >= buflen) {
99
required_len = result_len + 1;
100
result_len = buflen - 1;
102
} else if (strncmp(format, "%s", 3) == 0) {
104
result = va_arg(ap, const char*);
105
result_len = strlen(result);
106
if (add_cr && result_len >= buflen) {
107
required_len = result_len + 1;
108
result_len = buflen - 1;
111
int required_buffer_len = os::vsnprintf(buffer, buflen, format, ap);
112
assert(required_buffer_len >= 0, "vsnprintf encoding error");
114
required_len = required_buffer_len;
115
if (required_len < buflen) {
116
result_len = required_len;
118
result_len = buflen - 1;
122
if (result != buffer) {
123
memcpy(buffer, result, result_len);
128
buffer[result_len++] = '\n';
129
buffer[result_len] = 0;
132
if (required_len > result_len) {
133
warning("outputStream::do_vsnprintf output truncated -- buffer length is " SIZE_FORMAT
134
" bytes but " SIZE_FORMAT " bytes are needed.",
135
add_cr ? buflen + 1 : buflen, required_len + 1);
141
void outputStream::do_vsnprintf_and_write_with_automatic_buffer(const char* format, va_list ap, bool add_cr) {
142
char buffer[O_BUFLEN];
144
const char* str = do_vsnprintf(buffer, sizeof(buffer), format, ap, add_cr, len);
148
void outputStream::do_vsnprintf_and_write_with_scratch_buffer(const char* format, va_list ap, bool add_cr) {
150
const char* str = do_vsnprintf(_scratch, _scratch_len, format, ap, add_cr, len);
154
void outputStream::do_vsnprintf_and_write(const char* format, va_list ap, bool add_cr) {
155
if (_autoindent && _position == 0) {
159
do_vsnprintf_and_write_with_scratch_buffer(format, ap, add_cr);
161
do_vsnprintf_and_write_with_automatic_buffer(format, ap, add_cr);
165
void outputStream::print(const char* format, ...) {
167
va_start(ap, format);
168
do_vsnprintf_and_write(format, ap, false);
172
void outputStream::print_cr(const char* format, ...) {
174
va_start(ap, format);
175
do_vsnprintf_and_write(format, ap, true);
179
void outputStream::vprint(const char *format, va_list argptr) {
180
do_vsnprintf_and_write(format, argptr, false);
183
void outputStream::vprint_cr(const char* format, va_list argptr) {
184
do_vsnprintf_and_write(format, argptr, true);
187
void outputStream::print_raw(const char* str, size_t len) {
188
if (_autoindent && _position == 0) {
194
int outputStream::fill_to(int col) {
195
const int need_fill = MAX2(col - position(), 0);
200
void outputStream::move_to(int col, int slop, int min_space) {
201
if (position() >= col + slop)
203
int need_fill = col - position();
204
if (need_fill < min_space)
205
need_fill = min_space;
209
void outputStream::put(char ch) {
210
assert(ch != 0, "please fix call site");
211
char buf[] = { ch, '\0' };
215
void outputStream::sp(int count) {
216
if (count < 0) return;
219
int nw = (count > 8) ? 8 : count;
220
this->write(" ", nw);
225
void outputStream::cr() {
226
this->write("\n", 1);
229
void outputStream::cr_indent() {
233
void outputStream::stamp() {
234
if (! _stamp.is_updated()) {
241
jio_snprintf(buf, sizeof(buf), "%.3f", _stamp.seconds());
245
void outputStream::stamp(bool guard,
247
const char* suffix) {
256
void outputStream::date_stamp(bool guard,
258
const char* suffix) {
263
static const char error_time[] = "yyyy-mm-ddThh:mm:ss.mmm+zzzz";
264
static const int buffer_length = 32;
265
char buffer[buffer_length];
266
const char* iso8601_result = os::iso8601_time(buffer, buffer_length);
267
if (iso8601_result != nullptr) {
270
print_raw(error_time);
276
outputStream& outputStream::indent() {
277
sp(_indentation - _position);
281
bool outputStream::set_autoindent(bool value) {
282
const bool old = _autoindent;
287
void outputStream::print_jlong(jlong value) {
288
print(JLONG_FORMAT, value);
291
void outputStream::print_julong(julong value) {
292
print(JULONG_FORMAT, value);
306
void outputStream::print_data(void* data, size_t len, bool with_ascii, bool rel_addr) {
307
size_t limit = (len + 16) / 16 * 16;
308
for (size_t i = 0; i < limit; ++i) {
311
indent().print("%07" PRIxPTR ":", i);
313
indent().print(PTR_FORMAT ":", p2i((unsigned char*)data + i));
320
print("%02x", ((unsigned char*)data)[i]);
324
if ((i + 1) % 16 == 0) {
327
for (size_t j = 0; j < 16; ++j) {
328
size_t idx = i + j - 15;
330
char c = ((char*)data)[idx];
331
print("%c", c >= 32 && c <= 126 ? c : '.');
340
stringStream::stringStream(size_t initial_capacity) :
342
_buffer(_small_buffer),
344
_capacity(sizeof(_small_buffer)),
347
if (initial_capacity > _capacity) {
348
grow(initial_capacity);
354
stringStream::stringStream(char* fixed_buffer, size_t fixed_buffer_size) :
356
_buffer(fixed_buffer),
358
_capacity(fixed_buffer_size),
365
void stringStream::grow(size_t new_capacity) {
366
assert(!_is_fixed, "Don't call for caller provided buffers");
367
assert(new_capacity > _capacity, "Sanity");
368
assert(new_capacity > sizeof(_small_buffer), "Sanity");
369
if (_buffer == _small_buffer) {
370
_buffer = NEW_C_HEAP_ARRAY(char, new_capacity, mtInternal);
371
_capacity = new_capacity;
373
::memcpy(_buffer, _small_buffer, _written);
377
_buffer = REALLOC_C_HEAP_ARRAY(char, _buffer, new_capacity, mtInternal);
378
_capacity = new_capacity;
382
void stringStream::write(const char* s, size_t len) {
383
assert(_is_frozen == false, "Modification forbidden");
384
assert(_capacity >= _written + 1, "Sanity");
388
const size_t reasonable_max_len = 1 * G;
389
if (len >= reasonable_max_len) {
390
assert(false, "bad length? (" SIZE_FORMAT ")", len);
393
size_t write_len = 0;
395
write_len = MIN2(len, _capacity - _written - 1);
398
size_t needed = _written + len + 1;
399
if (needed > _capacity) {
400
grow(MAX2(needed, _capacity * 2));
403
assert(_written + write_len + 1 <= _capacity, "stringStream oob");
405
::memcpy(_buffer + _written, s, write_len);
406
_written += write_len;
413
update_position(s, len);
416
void stringStream::zero_terminate() {
417
assert(_buffer != nullptr &&
418
_written < _capacity, "sanity");
419
_buffer[_written] = '\0';
422
void stringStream::reset() {
423
assert(_is_frozen == false, "Modification forbidden");
424
_written = 0; _precount = 0; _position = 0;
428
char* stringStream::as_string(bool c_heap) const {
429
char* copy = c_heap ?
430
NEW_C_HEAP_ARRAY(char, _written + 1, mtInternal) : NEW_RESOURCE_ARRAY(char, _written + 1);
431
::memcpy(copy, _buffer, _written);
432
copy[_written] = '\0';
436
OrderAccess::storestore();
441
stringStream::~stringStream() {
442
if (!_is_fixed && _buffer != _small_buffer) {
443
FREE_C_HEAP_ARRAY(char, _buffer);
456
static nullStream tty_preinit_stream;
457
outputStream* tty = &tty_preinit_stream;
461
#define EXTRACHARLEN 32
462
#define CURRENTAPPX ".current"
464
static char* get_datetime_string(char *buf, size_t len) {
465
os::local_time_string(buf, len);
466
int i = (int)strlen(buf);
468
if (buf[i] == ' ') buf[i] = '_';
469
else if (buf[i] == ':') buf[i] = '-';
474
static const char* make_log_name_internal(const char* log_name, const char* force_directory,
475
int pid, const char* tms) {
476
const char* basename = log_name;
477
char file_sep = os::file_separator()[0];
481
for (cp = log_name; *cp != '\0'; cp++) {
482
if (*cp == '/' || *cp == file_sep) {
486
const char* nametail = log_name;
488
size_t buffer_length;
489
if (force_directory != nullptr) {
490
buffer_length = strlen(force_directory) + strlen(os::file_separator()) +
491
strlen(basename) + 1;
493
buffer_length = strlen(log_name) + 1;
496
const char* pts = strstr(basename, "%p");
497
int pid_pos = (pts == nullptr) ? -1 : (pts - nametail);
500
jio_snprintf(pid_text, sizeof(pid_text), "pid%u", pid);
501
buffer_length += strlen(pid_text);
504
pts = strstr(basename, "%t");
505
int tms_pos = (pts == nullptr) ? -1 : (pts - nametail);
507
buffer_length += strlen(tms);
511
if (buffer_length > JVM_MAXPATHLEN) {
516
char *buf = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal);
519
if (force_directory != nullptr) {
520
strcat(buf, force_directory);
521
strcat(buf, os::file_separator());
526
int first = -1, second = -1;
527
const char *p1st = nullptr;
528
const char *p2nd = nullptr;
530
if (pid_pos >= 0 && tms_pos >= 0) {
532
if (pid_pos < tms_pos) {
545
} else if (pid_pos >= 0) {
549
} else if (tms_pos >= 0) {
555
int buf_pos = (int)strlen(buf);
556
const char* tail = nametail;
559
tail = nametail + first + 2;
560
strncpy(&buf[buf_pos], nametail, first);
561
strcpy(&buf[buf_pos + first], p1st);
562
buf_pos = (int)strlen(buf);
564
strncpy(&buf[buf_pos], tail, second - first - 2);
565
strcpy(&buf[buf_pos + second - first - 2], p2nd);
566
tail = nametail + second + 2;
577
const char* make_log_name(const char* log_name, const char* force_directory) {
579
get_datetime_string(timestr, sizeof(timestr));
580
return make_log_name_internal(log_name, force_directory, os::current_process_id(),
584
fileStream::fileStream(const char* file_name) {
585
_file = os::fopen(file_name, "w");
586
if (_file != nullptr) {
589
warning("Cannot open file %s due to %s\n", file_name, os::strerror(errno));
594
fileStream::fileStream(const char* file_name, const char* opentype) {
595
_file = os::fopen(file_name, opentype);
596
if (_file != nullptr) {
599
warning("Cannot open file %s due to %s\n", file_name, os::strerror(errno));
604
void fileStream::write(const char* s, size_t len) {
605
if (_file != nullptr) {
607
size_t count = fwrite(s, 1, len, _file);
608
update_position(s, len);
612
long fileStream::fileSize() {
614
if (_file != nullptr) {
615
long pos = ::ftell(_file);
616
if (pos < 0) return pos;
617
if (::fseek(_file, 0, SEEK_END) == 0) {
618
size = ::ftell(_file);
620
::fseek(_file, pos, SEEK_SET);
625
fileStream::~fileStream() {
626
if (_file != nullptr) {
632
void fileStream::flush() {
633
if (_file != nullptr) {
638
fdStream fdStream::_stdout_stream(1);
639
fdStream fdStream::_stderr_stream(2);
641
void fdStream::write(const char* s, size_t len) {
644
ssize_t count = ::write(_fd, s, (int)len);
645
update_position(s, len);
649
defaultStream* defaultStream::instance = nullptr;
650
int defaultStream::_output_fd = 1;
651
int defaultStream::_error_fd = 2;
652
FILE* defaultStream::_output_stream = stdout;
653
FILE* defaultStream::_error_stream = stderr;
655
#define LOG_MAJOR_VERSION 160
656
#define LOG_MINOR_VERSION 1
658
void defaultStream::init() {
660
if (LogVMOutput || LogCompilation) {
665
bool defaultStream::has_log_file() {
670
if (!_inited && !VMError::is_error_reported()) init();
671
return _log_file != nullptr;
674
fileStream* defaultStream::open_file(const char* log_name) {
675
const char* try_name = make_log_name(log_name, nullptr);
676
if (try_name == nullptr) {
677
warning("Cannot open file %s: file name is too long.\n", log_name);
681
fileStream* file = new (mtInternal) fileStream(try_name);
682
FREE_C_HEAP_ARRAY(char, try_name);
683
if (file->is_open()) {
690
jio_printf("Warning: Cannot open log file: %s\n", log_name);
691
try_name = make_log_name(log_name, os::get_temp_directory());
692
if (try_name == nullptr) {
693
warning("Cannot open file %s: file name is too long for directory %s.\n", log_name, os::get_temp_directory());
697
jio_printf("Warning: Forcing option -XX:LogFile=%s\n", try_name);
699
file = new (mtInternal) fileStream(try_name);
700
FREE_C_HEAP_ARRAY(char, try_name);
701
if (file->is_open()) {
709
void defaultStream::init_log() {
711
const char* log_name = LogFile != nullptr ? LogFile : "hotspot_%p.log";
712
fileStream* file = open_file(log_name);
714
if (file != nullptr) {
716
_outer_xmlStream = new(mtInternal) xmlStream(file);
721
DisplayVMOutput = true;
722
LogCompilation = false;
726
void defaultStream::start_log() {
727
xmlStream*xs = _outer_xmlStream;
728
if (this == tty) xtty = xs;
730
xs->print_cr("<?xml version='1.0' encoding='UTF-8'?>");
735
jlong time_ms = os::javaTimeMillis() - tty->time_stamp().milliseconds();
736
xs->head("hotspot_log version='%d %d'"
737
" process='%d' time_ms='" INT64_FORMAT "'",
738
LOG_MAJOR_VERSION, LOG_MINOR_VERSION,
739
os::current_process_id(), (int64_t)time_ms);
741
xs->head("vm_version");
742
xs->head("name"); xs->text("%s", VM_Version::vm_name()); xs->cr();
744
xs->head("release"); xs->text("%s", VM_Version::vm_release()); xs->cr();
746
xs->head("info"); xs->text("%s", VM_Version::internal_vm_info_string()); xs->cr();
748
xs->tail("vm_version");
750
xs->head("vm_arguments");
751
if (Arguments::num_jvm_flags() > 0) {
753
Arguments::print_jvm_flags_on(xs->text());
756
if (Arguments::num_jvm_args() > 0) {
758
Arguments::print_jvm_args_on(xs->text());
761
if (Arguments::java_command() != nullptr) {
762
xs->head("command"); xs->text()->print_cr("%s", Arguments::java_command());
765
if (Arguments::sun_java_launcher() != nullptr) {
766
xs->head("launcher"); xs->text()->print_cr("%s", Arguments::sun_java_launcher());
767
xs->tail("launcher");
769
if (Arguments::system_properties() != nullptr) {
770
xs->head("properties");
773
outputStream *text = xs->text();
774
for (SystemProperty* p = Arguments::system_properties(); p != nullptr; p = p->next()) {
775
assert(p->key() != nullptr, "p->key() is null");
779
text->print_raw(p->key());
781
assert(p->value() != nullptr, "p->value() is null");
782
text->print_raw_cr(p->value());
785
xs->tail("properties");
787
xs->tail("vm_arguments");
797
void defaultStream::finish_log() {
798
xmlStream* xs = _outer_xmlStream;
802
CompileLog::finish_log(xs->out());
804
xs->done("hotspot_log");
807
fileStream* file = _log_file;
810
delete _outer_xmlStream;
811
_outer_xmlStream = nullptr;
817
void defaultStream::finish_log_on_error(char *buf, int buflen) {
818
xmlStream* xs = _outer_xmlStream;
820
if (xs && xs->out()) {
825
CompileLog::finish_log_on_error(xs->out(), buf, buflen);
827
xs->done_raw("hotspot_log");
830
fileStream* file = _log_file;
832
_outer_xmlStream = nullptr;
844
intx defaultStream::hold(intx writer_id) {
845
bool has_log = has_log_file();
847
writer_id == NO_WRITER ||
850
tty_lock == nullptr ||
853
Thread::current_or_null() == nullptr ||
856
!SerializeVMOutput ||
859
VMError::is_error_reported() ||
862
(SafepointSynchronize::is_synchronizing() &&
863
Thread::current()->is_VM_thread())
868
if (_writer == writer_id) {
872
tty_lock->lock_without_safepoint_check();
874
if (writer_id != _last_writer) {
878
_log_file->print_cr("<writer thread='" UINTX_FORMAT "'/>", writer_id);
880
_last_writer = writer_id;
886
void defaultStream::release(intx holder) {
887
if (holder == NO_WRITER) {
891
if (_writer != holder) {
898
void defaultStream::write(const char* s, size_t len) {
899
intx thread_id = os::current_thread_id();
900
intx holder = hold(thread_id);
902
if (DisplayVMOutput &&
903
(_outer_xmlStream == nullptr || !_outer_xmlStream->inside_attrs())) {
909
if (has_log_file() && _outer_xmlStream != nullptr) {
910
_outer_xmlStream->write_text(s, len);
911
bool nl = update_position(s, len);
917
update_position(s, len);
923
intx ttyLocker::hold_tty() {
924
if (defaultStream::instance == nullptr) return defaultStream::NO_WRITER;
925
intx thread_id = os::current_thread_id();
926
return defaultStream::instance->hold(thread_id);
929
void ttyLocker::release_tty(intx holder) {
930
if (holder == defaultStream::NO_WRITER) return;
931
defaultStream::instance->release(holder);
934
bool ttyLocker::release_tty_if_locked() {
935
intx thread_id = os::current_thread_id();
936
if (defaultStream::instance->writer() == thread_id) {
939
release_tty(thread_id);
945
void ttyLocker::break_tty_lock_for_safepoint(intx holder) {
946
if (defaultStream::instance != nullptr &&
947
defaultStream::instance->writer() == holder) {
948
if (xtty != nullptr) {
949
xtty->print_cr("<!-- safepoint while printing -->");
951
defaultStream::instance->release(holder);
957
if (defaultStream::instance == nullptr) {
958
defaultStream::instance = new(mtInternal) defaultStream();
959
tty = defaultStream::instance;
965
tty->time_stamp().update_to(1);
969
void ostream_init_log() {
972
ClassListWriter::init();
977
defaultStream::instance->has_log_file();
983
static bool ostream_exit_called = false;
984
if (ostream_exit_called) return;
985
ostream_exit_called = true;
986
ClassListWriter::delete_classlist();
988
outputStream* tmp = tty;
989
tty = DisplayVMOutputToStderr ? fdStream::stderr_stream() : fdStream::stdout_stream();
990
if (tmp != &tty_preinit_stream && tmp != defaultStream::instance) {
993
delete defaultStream::instance;
995
defaultStream::instance = nullptr;
999
void ostream_abort() {
1001
if (tty) tty->flush();
1003
if (defaultStream::instance != nullptr) {
1004
static char buf[4096];
1005
defaultStream::instance->finish_log_on_error(buf, sizeof(buf));
1009
bufferedStream::bufferedStream(size_t initial_size, size_t bufmax) : outputStream() {
1010
buffer_length = initial_size;
1011
buffer = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal);
1013
buffer_max = bufmax;
1017
void bufferedStream::write(const char* s, size_t len) {
1023
if(buffer_pos + len > buffer_max) {
1027
size_t end = buffer_pos + len;
1028
if (end >= buffer_length) {
1031
if (end < buffer_length * 2) {
1032
end = buffer_length * 2;
1038
const size_t reasonable_cap = MAX2(100 * M, buffer_max * 2);
1039
if (end > reasonable_cap) {
1041
assert(false, "Exceeded max buffer size for this string (\"%.200s...\").", buffer);
1045
end = reasonable_cap;
1046
size_t remaining = end - buffer_pos;
1047
if (len >= remaining) {
1048
len = remaining - 1;
1052
if (buffer_length < end) {
1053
buffer = REALLOC_C_HEAP_ARRAY(char, buffer, end, mtInternal);
1054
buffer_length = end;
1058
memcpy(buffer + buffer_pos, s, len);
1060
update_position(s, len);
1064
char* bufferedStream::as_string() {
1065
char* copy = NEW_RESOURCE_ARRAY(char, buffer_pos+1);
1066
strncpy(copy, buffer, buffer_pos);
1067
copy[buffer_pos] = 0;
1071
bufferedStream::~bufferedStream() {
1072
FREE_C_HEAP_ARRAY(char, buffer);
1077
#if defined(LINUX) || defined(AIX) || defined(_ALLBSD_SOURCE)
1078
#include <sys/types.h>
1079
#include <sys/socket.h>
1080
#include <netinet/in.h>
1082
#include <arpa/inet.h>
1083
#elif defined(_WINDOWS)
1084
#include <Ws2tcpip.h>
1088
networkStream::networkStream() : bufferedStream(1024*10, 1024*10) {
1092
int result = ::socket(AF_INET, SOCK_STREAM, 0);
1094
assert(false, "Socket could not be created!");
1100
ssize_t networkStream::read(char *buf, size_t len) {
1101
return os::recv(_socket, buf, len, 0);
1104
void networkStream::flush() {
1106
ssize_t result = os::raw_send(_socket, (char *)base(), size(), 0);
1107
assert(result != -1, "connection error");
1108
assert(result >= 0 && (size_t)result == size(), "didn't send enough data");
1113
networkStream::~networkStream() {
1117
void networkStream::close() {
1118
if (_socket != -1) {
1120
os::socket_close(_socket);
1126
bool networkStream::connect(const char *host, short port) {
1129
int ret = os::snprintf(s_port, sizeof(s_port), "%hu", (unsigned short) port);
1130
assert(ret > 0, "snprintf failed: %d", ret);
1132
struct addrinfo* addr_info = nullptr;
1133
struct addrinfo hints;
1135
memset(&hints, 0, sizeof(hints));
1136
hints.ai_family = AF_INET;
1137
hints.ai_socktype = SOCK_STREAM;
1140
ret = getaddrinfo(host, s_port, &hints, &addr_info);
1142
warning("networkStream::connect getaddrinfo for host %s and port %s failed: %s",
1143
host, s_port, gai_strerror(ret));
1147
ssize_t conn = os::connect(_socket, addr_info->ai_addr, (socklen_t)addr_info->ai_addrlen);
1148
freeaddrinfo(addr_info);