ostream.cpp revision 4030:203f64878aab
12061Sjkh/* 23029Srgrimes * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 32061Sjkh * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 42061Sjkh * 52061Sjkh * This code is free software; you can redistribute it and/or modify it 62061Sjkh * under the terms of the GNU General Public License version 2 only, as 72061Sjkh * published by the Free Software Foundation. 82061Sjkh * 92160Scsgr * This code is distributed in the hope that it will be useful, but WITHOUT 102160Scsgr * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 112834Swollman * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 122061Sjkh * version 2 for more details (a copy is included in the LICENSE file that 132061Sjkh * accompanied this code). 142160Scsgr * 152626Scsgr * You should have received a copy of the GNU General Public License version 162061Sjkh * 2 along with this work; if not, write to the Free Software Foundation, 172160Scsgr * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 181594Srgrimes * 192061Sjkh * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 202160Scsgr * or visit www.oracle.com if you need additional information or have any 212061Sjkh * questions. 221594Srgrimes * 232061Sjkh */ 242061Sjkh 252061Sjkh#include "precompiled.hpp" 262061Sjkh#include "compiler/compileLog.hpp" 272061Sjkh#include "oops/oop.inline.hpp" 282061Sjkh#include "runtime/arguments.hpp" 292061Sjkh#include "utilities/defaultStream.hpp" 303029Srgrimes#include "utilities/ostream.hpp" 313029Srgrimes#include "utilities/top.hpp" 322061Sjkh#include "utilities/xmlstream.hpp" 332061Sjkh#ifdef TARGET_OS_FAMILY_linux 342061Sjkh# include "os_linux.inline.hpp" 352061Sjkh#endif 362061Sjkh#ifdef TARGET_OS_FAMILY_solaris 372061Sjkh# include "os_solaris.inline.hpp" 382061Sjkh#endif 392061Sjkh#ifdef TARGET_OS_FAMILY_windows 402061Sjkh# include "os_windows.inline.hpp" 412061Sjkh#endif 422061Sjkh#ifdef TARGET_OS_FAMILY_bsd 432061Sjkh# include "os_bsd.inline.hpp" 442061Sjkh#endif 452160Scsgr 462061Sjkhextern "C" void jio_print(const char* s); // Declarationtion of jvm method 472061Sjkh 482626ScsgroutputStream::outputStream(int width) { 492626Scsgr _width = width; 502626Scsgr _position = 0; 512626Scsgr _newlines = 0; 522061Sjkh _precount = 0; 532061Sjkh _indentation = 0; 542061Sjkh} 552061Sjkh 562061SjkhoutputStream::outputStream(int width, bool has_time_stamps) { 572061Sjkh _width = width; 582061Sjkh _position = 0; 592061Sjkh _newlines = 0; 602061Sjkh _precount = 0; 612061Sjkh _indentation = 0; 622061Sjkh if (has_time_stamps) _stamp.update(); 632061Sjkh} 642061Sjkh 652061Sjkhvoid outputStream::update_position(const char* s, size_t len) { 662061Sjkh for (size_t i = 0; i < len; i++) { 672061Sjkh char ch = s[i]; 682061Sjkh if (ch == '\n') { 692061Sjkh _newlines += 1; 702834Swollman _precount += _position + 1; 712834Swollman _position = 0; 722834Swollman } else if (ch == '\t') { 732834Swollman int tw = 8 - (_position & 7); 742834Swollman _position += tw; 752834Swollman _precount -= tw-1; // invariant: _precount + _position == total count 761594Srgrimes } else { 772061Sjkh _position += 1; 782061Sjkh } 792061Sjkh } 802061Sjkh} 812061Sjkh 822061Sjkh// Execute a vsprintf, using the given buffer if necessary. 832061Sjkh// Return a pointer to the formatted string. 842061Sjkhconst char* outputStream::do_vsnprintf(char* buffer, size_t buflen, 852061Sjkh const char* format, va_list ap, 862061Sjkh bool add_cr, 872061Sjkh size_t& result_len) { 882061Sjkh const char* result; 892061Sjkh if (add_cr) buflen--; 902061Sjkh if (!strchr(format, '%')) { 912061Sjkh // constant format string 922061Sjkh result = format; 932061Sjkh result_len = strlen(result); 942061Sjkh if (add_cr && result_len >= buflen) result_len = buflen-1; // truncate 952061Sjkh } else if (format[0] == '%' && format[1] == 's' && format[2] == '\0') { 962061Sjkh // trivial copy-through format string 972061Sjkh result = va_arg(ap, const char*); 983029Srgrimes result_len = strlen(result); 992061Sjkh if (add_cr && result_len >= buflen) result_len = buflen-1; // truncate 1002061Sjkh } else if (vsnprintf(buffer, buflen, format, ap) >= 0) { 1012061Sjkh result = buffer; 1022061Sjkh result_len = strlen(result); 1032061Sjkh } else { 1042061Sjkh DEBUG_ONLY(warning("increase O_BUFLEN in ostream.hpp -- output truncated");) 1052061Sjkh result = buffer; 1062302Spaul result_len = buflen - 1; 1073029Srgrimes buffer[result_len] = 0; 1082061Sjkh } 1093029Srgrimes if (add_cr) { 1102061Sjkh if (result != buffer) { 1113029Srgrimes strncpy(buffer, result, buflen); 1122061Sjkh result = buffer; 1132302Spaul } 1142302Spaul buffer[result_len++] = '\n'; 1152302Spaul buffer[result_len] = 0; 1162302Spaul } 1172302Spaul return result; 1182302Spaul} 1192302Spaul 1202302Spaulvoid outputStream::print(const char* format, ...) { 1212302Spaul char buffer[O_BUFLEN]; 1222302Spaul va_list ap; 1232302Spaul va_start(ap, format); 1242302Spaul size_t len; 1252302Spaul const char* str = do_vsnprintf(buffer, O_BUFLEN, format, ap, false, len); 1262302Spaul write(str, len); 1272061Sjkh va_end(ap); 1282061Sjkh} 1292061Sjkh 1302061Sjkhvoid outputStream::print_cr(const char* format, ...) { 1312061Sjkh char buffer[O_BUFLEN]; 1322061Sjkh va_list ap; 1332061Sjkh va_start(ap, format); 1342061Sjkh size_t len; 1352061Sjkh const char* str = do_vsnprintf(buffer, O_BUFLEN, format, ap, true, len); 1362061Sjkh write(str, len); 1372061Sjkh va_end(ap); 1382061Sjkh} 1392061Sjkh 1402061Sjkhvoid outputStream::vprint(const char *format, va_list argptr) { 1412061Sjkh char buffer[O_BUFLEN]; 1422061Sjkh size_t len; 1432061Sjkh const char* str = do_vsnprintf(buffer, O_BUFLEN, format, argptr, false, len); 1442061Sjkh write(str, len); 1452061Sjkh} 1462061Sjkh 1472061Sjkhvoid outputStream::vprint_cr(const char* format, va_list argptr) { 1482061Sjkh char buffer[O_BUFLEN]; 1492061Sjkh size_t len; 1502061Sjkh const char* str = do_vsnprintf(buffer, O_BUFLEN, format, argptr, true, len); 1512061Sjkh write(str, len); 1522061Sjkh} 1532061Sjkh 1542061Sjkhvoid outputStream::fill_to(int col) { 1552061Sjkh int need_fill = col - position(); 1562061Sjkh sp(need_fill); 1572061Sjkh} 1582061Sjkh 1592061Sjkhvoid outputStream::move_to(int col, int slop, int min_space) { 1602061Sjkh if (position() >= col + slop) 1612061Sjkh cr(); 1622061Sjkh int need_fill = col - position(); 1632061Sjkh if (need_fill < min_space) 1642061Sjkh need_fill = min_space; 1652061Sjkh sp(need_fill); 1662061Sjkh} 1672061Sjkh 1682061Sjkhvoid outputStream::put(char ch) { 1692061Sjkh assert(ch != 0, "please fix call site"); 1702061Sjkh char buf[] = { ch, '\0' }; 1712685Srgrimes write(buf, 1); 1722685Srgrimes} 1732626Scsgr 1742061Sjkh#define SP_USE_TABS false 1752061Sjkh 1762061Sjkhvoid outputStream::sp(int count) { 1772061Sjkh if (count < 0) return; 1782061Sjkh if (SP_USE_TABS && count >= 8) { 1792883Sphk int target = position() + count; 1802061Sjkh while (count >= 8) { 1812626Scsgr this->write("\t", 1); 1822626Scsgr count -= 8; 1832626Scsgr } 1842626Scsgr count = target - position(); 1852061Sjkh } 1862061Sjkh while (count > 0) { 1872061Sjkh int nw = (count > 8) ? 8 : count; 1882061Sjkh this->write(" ", nw); 1892061Sjkh count -= nw; 1902061Sjkh } 1912061Sjkh} 1922061Sjkh 1932061Sjkhvoid outputStream::cr() { 1942061Sjkh this->write("\n", 1); 1952468Spaul} 1962061Sjkh 1972273Spaulvoid outputStream::stamp() { 1982061Sjkh if (! _stamp.is_updated()) { 1992160Scsgr _stamp.update(); // start at 0 on first call to stamp() 2002160Scsgr } 2012160Scsgr 2022160Scsgr // outputStream::stamp() may get called by ostream_abort(), use snprintf 2032279Spaul // to avoid allocating large stack buffer in print(). 2042061Sjkh char buf[40]; 2052061Sjkh jio_snprintf(buf, sizeof(buf), "%.3f", _stamp.seconds()); 2062279Spaul print_raw(buf); 2072468Spaul} 2082468Spaul 2092626Scsgrvoid outputStream::stamp(bool guard, 2102061Sjkh const char* prefix, 2112061Sjkh const char* suffix) { 2122061Sjkh if (!guard) { 2132061Sjkh return; 2142061Sjkh } 2152061Sjkh print_raw(prefix); 2162061Sjkh stamp(); 2172061Sjkh print_raw(suffix); 2182061Sjkh} 2192626Scsgr 2202626Scsgrvoid outputStream::date_stamp(bool guard, 2212626Scsgr const char* prefix, 2222626Scsgr const char* suffix) { 2232626Scsgr if (!guard) { 2242626Scsgr return; 2252626Scsgr } 2262626Scsgr print_raw(prefix); 2272626Scsgr static const char error_time[] = "yyyy-mm-ddThh:mm:ss.mmm+zzzz"; 2282626Scsgr static const int buffer_length = 32; 2292626Scsgr char buffer[buffer_length]; 2302061Sjkh const char* iso8601_result = os::iso8601_time(buffer, buffer_length); 2312061Sjkh if (iso8601_result != NULL) { 2322061Sjkh print_raw(buffer); 2332061Sjkh } else { 2342061Sjkh print_raw(error_time); 2352061Sjkh } 2362273Spaul print_raw(suffix); 2372061Sjkh return; 2382061Sjkh} 2392061Sjkh 2402061SjkhoutputStream& outputStream::indent() { 2411594Srgrimes while (_position < _indentation) sp(); 242 return *this; 243} 244 245void outputStream::print_jlong(jlong value) { 246 print(JLONG_FORMAT, value); 247} 248 249void outputStream::print_julong(julong value) { 250 print(JULONG_FORMAT, value); 251} 252 253/** 254 * This prints out hex data in a 'windbg' or 'xxd' form, where each line is: 255 * <hex-address>: 8 * <hex-halfword> <ascii translation (optional)> 256 * example: 257 * 0000000: 7f44 4f46 0102 0102 0000 0000 0000 0000 .DOF............ 258 * 0000010: 0000 0000 0000 0040 0000 0020 0000 0005 .......@... .... 259 * 0000020: 0000 0000 0000 0040 0000 0000 0000 015d .......@.......] 260 * ... 261 * 262 * indent is applied to each line. Ends with a CR. 263 */ 264void outputStream::print_data(void* data, size_t len, bool with_ascii) { 265 size_t limit = (len + 16) / 16 * 16; 266 for (size_t i = 0; i < limit; ++i) { 267 if (i % 16 == 0) { 268 indent().print("%07x:", i); 269 } 270 if (i % 2 == 0) { 271 print(" "); 272 } 273 if (i < len) { 274 print("%02x", ((unsigned char*)data)[i]); 275 } else { 276 print(" "); 277 } 278 if ((i + 1) % 16 == 0) { 279 if (with_ascii) { 280 print(" "); 281 for (size_t j = 0; j < 16; ++j) { 282 size_t idx = i + j - 15; 283 if (idx < len) { 284 char c = ((char*)data)[idx]; 285 print("%c", c >= 32 && c <= 126 ? c : '.'); 286 } 287 } 288 } 289 print_cr(""); 290 } 291 } 292} 293 294stringStream::stringStream(size_t initial_size) : outputStream() { 295 buffer_length = initial_size; 296 buffer = NEW_RESOURCE_ARRAY(char, buffer_length); 297 buffer_pos = 0; 298 buffer_fixed = false; 299} 300 301// useful for output to fixed chunks of memory, such as performance counters 302stringStream::stringStream(char* fixed_buffer, size_t fixed_buffer_size) : outputStream() { 303 buffer_length = fixed_buffer_size; 304 buffer = fixed_buffer; 305 buffer_pos = 0; 306 buffer_fixed = true; 307} 308 309void stringStream::write(const char* s, size_t len) { 310 size_t write_len = len; // number of non-null bytes to write 311 size_t end = buffer_pos + len + 1; // position after write and final '\0' 312 if (end > buffer_length) { 313 if (buffer_fixed) { 314 // if buffer cannot resize, silently truncate 315 end = buffer_length; 316 write_len = end - buffer_pos - 1; // leave room for the final '\0' 317 } else { 318 // For small overruns, double the buffer. For larger ones, 319 // increase to the requested size. 320 if (end < buffer_length * 2) { 321 end = buffer_length * 2; 322 } 323 char* oldbuf = buffer; 324 buffer = NEW_RESOURCE_ARRAY(char, end); 325 strncpy(buffer, oldbuf, buffer_pos); 326 buffer_length = end; 327 } 328 } 329 // invariant: buffer is always null-terminated 330 guarantee(buffer_pos + write_len + 1 <= buffer_length, "stringStream oob"); 331 buffer[buffer_pos + write_len] = 0; 332 strncpy(buffer + buffer_pos, s, write_len); 333 buffer_pos += write_len; 334 335 // Note that the following does not depend on write_len. 336 // This means that position and count get updated 337 // even when overflow occurs. 338 update_position(s, len); 339} 340 341char* stringStream::as_string() { 342 char* copy = NEW_RESOURCE_ARRAY(char, buffer_pos+1); 343 strncpy(copy, buffer, buffer_pos); 344 copy[buffer_pos] = 0; // terminating null 345 return copy; 346} 347 348stringStream::~stringStream() {} 349 350xmlStream* xtty; 351outputStream* tty; 352outputStream* gclog_or_tty; 353extern Mutex* tty_lock; 354 355fileStream::fileStream(const char* file_name) { 356 _file = fopen(file_name, "w"); 357 _need_close = true; 358} 359 360fileStream::fileStream(const char* file_name, const char* opentype) { 361 _file = fopen(file_name, opentype); 362 _need_close = true; 363} 364 365void fileStream::write(const char* s, size_t len) { 366 if (_file != NULL) { 367 // Make an unused local variable to avoid warning from gcc 4.x compiler. 368 size_t count = fwrite(s, 1, len, _file); 369 } 370 update_position(s, len); 371} 372 373long fileStream::fileSize() { 374 long size = -1; 375 if (_file != NULL) { 376 long pos = ::ftell(_file); 377 if (::fseek(_file, 0, SEEK_END) == 0) { 378 size = ::ftell(_file); 379 } 380 ::fseek(_file, pos, SEEK_SET); 381 } 382 return size; 383} 384 385char* fileStream::readln(char *data, int count ) { 386 char * ret = ::fgets(data, count, _file); 387 //Get rid of annoying \n char 388 data[::strlen(data)-1] = '\0'; 389 return ret; 390} 391 392fileStream::~fileStream() { 393 if (_file != NULL) { 394 if (_need_close) fclose(_file); 395 _file = NULL; 396 } 397} 398 399void fileStream::flush() { 400 fflush(_file); 401} 402 403fdStream::fdStream(const char* file_name) { 404 _fd = open(file_name, O_WRONLY | O_CREAT | O_TRUNC, 0666); 405 _need_close = true; 406} 407 408fdStream::~fdStream() { 409 if (_fd != -1) { 410 if (_need_close) close(_fd); 411 _fd = -1; 412 } 413} 414 415void fdStream::write(const char* s, size_t len) { 416 if (_fd != -1) { 417 // Make an unused local variable to avoid warning from gcc 4.x compiler. 418 size_t count = ::write(_fd, s, (int)len); 419 } 420 update_position(s, len); 421} 422 423rotatingFileStream::~rotatingFileStream() { 424 if (_file != NULL) { 425 if (_need_close) fclose(_file); 426 _file = NULL; 427 FREE_C_HEAP_ARRAY(char, _file_name, mtInternal); 428 _file_name = NULL; 429 } 430} 431 432rotatingFileStream::rotatingFileStream(const char* file_name) { 433 _cur_file_num = 0; 434 _bytes_writen = 0L; 435 _file_name = NEW_C_HEAP_ARRAY(char, strlen(file_name)+10, mtInternal); 436 jio_snprintf(_file_name, strlen(file_name)+10, "%s.%d", file_name, _cur_file_num); 437 _file = fopen(_file_name, "w"); 438 _need_close = true; 439} 440 441rotatingFileStream::rotatingFileStream(const char* file_name, const char* opentype) { 442 _cur_file_num = 0; 443 _bytes_writen = 0L; 444 _file_name = NEW_C_HEAP_ARRAY(char, strlen(file_name)+10, mtInternal); 445 jio_snprintf(_file_name, strlen(file_name)+10, "%s.%d", file_name, _cur_file_num); 446 _file = fopen(_file_name, opentype); 447 _need_close = true; 448} 449 450void rotatingFileStream::write(const char* s, size_t len) { 451 if (_file != NULL) { 452 // Make an unused local variable to avoid warning from gcc 4.x compiler. 453 size_t count = fwrite(s, 1, len, _file); 454 Atomic::add((jlong)count, &_bytes_writen); 455 } 456 update_position(s, len); 457} 458 459// rotate_log must be called from VMThread at safepoint. In case need change parameters 460// for gc log rotation from thread other than VMThread, a sub type of VM_Operation 461// should be created and be submitted to VMThread's operation queue. DO NOT call this 462// function directly. Currently, it is safe to rotate log at safepoint through VMThread. 463// That is, no mutator threads and concurrent GC threads run parallel with VMThread to 464// write to gc log file at safepoint. If in future, changes made for mutator threads or 465// concurrent GC threads to run parallel with VMThread at safepoint, write and rotate_log 466// must be synchronized. 467void rotatingFileStream::rotate_log() { 468 if (_bytes_writen < (jlong)GCLogFileSize) return; 469#ifdef ASSERT 470 Thread *thread = Thread::current(); 471 assert(thread == NULL || 472 (thread->is_VM_thread() && SafepointSynchronize::is_at_safepoint()), 473 "Must be VMThread at safepoint"); 474#endif 475 if (NumberOfGCLogFiles == 1) { 476 // rotate in same file 477 rewind(); 478 _bytes_writen = 0L; 479 return; 480 } 481 482 // rotate file in names file.0, file.1, file.2, ..., file.<MaxGCLogFileNumbers-1> 483 // close current file, rotate to next file 484 if (_file != NULL) { 485 _cur_file_num ++; 486 if (_cur_file_num >= NumberOfGCLogFiles) _cur_file_num = 0; 487 jio_snprintf(_file_name, strlen(Arguments::gc_log_filename()) + 10, "%s.%d", 488 Arguments::gc_log_filename(), _cur_file_num); 489 fclose(_file); 490 _file = NULL; 491 } 492 _file = fopen(_file_name, "w"); 493 if (_file != NULL) { 494 _bytes_writen = 0L; 495 _need_close = true; 496 } else { 497 tty->print_cr("failed to open rotation log file %s due to %s\n", 498 _file_name, strerror(errno)); 499 _need_close = false; 500 } 501} 502 503defaultStream* defaultStream::instance = NULL; 504int defaultStream::_output_fd = 1; 505int defaultStream::_error_fd = 2; 506FILE* defaultStream::_output_stream = stdout; 507FILE* defaultStream::_error_stream = stderr; 508 509#define LOG_MAJOR_VERSION 160 510#define LOG_MINOR_VERSION 1 511 512void defaultStream::init() { 513 _inited = true; 514 if (LogVMOutput || LogCompilation) { 515 init_log(); 516 } 517} 518 519bool defaultStream::has_log_file() { 520 // lazily create log file (at startup, LogVMOutput is false even 521 // if +LogVMOutput is used, because the flags haven't been parsed yet) 522 // For safer printing during fatal error handling, do not init logfile 523 // if a VM error has been reported. 524 if (!_inited && !is_error_reported()) init(); 525 return _log_file != NULL; 526} 527 528static const char* make_log_name(const char* log_name, const char* force_directory) { 529 const char* basename = log_name; 530 char file_sep = os::file_separator()[0]; 531 const char* cp; 532 for (cp = log_name; *cp != '\0'; cp++) { 533 if (*cp == '/' || *cp == file_sep) { 534 basename = cp+1; 535 } 536 } 537 const char* nametail = log_name; 538 539 // Compute buffer length 540 size_t buffer_length; 541 if (force_directory != NULL) { 542 buffer_length = strlen(force_directory) + strlen(os::file_separator()) + 543 strlen(basename) + 1; 544 } else { 545 buffer_length = strlen(log_name) + 1; 546 } 547 548 const char* star = strchr(basename, '*'); 549 int star_pos = (star == NULL) ? -1 : (star - nametail); 550 int skip = 1; 551 if (star == NULL) { 552 // Try %p 553 star = strstr(basename, "%p"); 554 if (star != NULL) { 555 skip = 2; 556 } 557 } 558 star_pos = (star == NULL) ? -1 : (star - nametail); 559 560 char pid[32]; 561 if (star_pos >= 0) { 562 jio_snprintf(pid, sizeof(pid), "%u", os::current_process_id()); 563 buffer_length += strlen(pid); 564 } 565 566 // Create big enough buffer. 567 char *buf = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal); 568 569 strcpy(buf, ""); 570 if (force_directory != NULL) { 571 strcat(buf, force_directory); 572 strcat(buf, os::file_separator()); 573 nametail = basename; // completely skip directory prefix 574 } 575 576 if (star_pos >= 0) { 577 // convert foo*bar.log or foo%pbar.log to foo123bar.log 578 int buf_pos = (int) strlen(buf); 579 strncpy(&buf[buf_pos], nametail, star_pos); 580 strcpy(&buf[buf_pos + star_pos], pid); 581 nametail += star_pos + skip; // skip prefix and pid format 582 } 583 584 strcat(buf, nametail); // append rest of name, or all of name 585 return buf; 586} 587 588void defaultStream::init_log() { 589 // %%% Need a MutexLocker? 590 const char* log_name = LogFile != NULL ? LogFile : "hotspot.log"; 591 const char* try_name = make_log_name(log_name, NULL); 592 fileStream* file = new(ResourceObj::C_HEAP, mtInternal) fileStream(try_name); 593 if (!file->is_open()) { 594 // Try again to open the file. 595 char warnbuf[O_BUFLEN*2]; 596 jio_snprintf(warnbuf, sizeof(warnbuf), 597 "Warning: Cannot open log file: %s\n", try_name); 598 // Note: This feature is for maintainer use only. No need for L10N. 599 jio_print(warnbuf); 600 FREE_C_HEAP_ARRAY(char, try_name, mtInternal); 601 try_name = make_log_name("hs_pid%p.log", os::get_temp_directory()); 602 jio_snprintf(warnbuf, sizeof(warnbuf), 603 "Warning: Forcing option -XX:LogFile=%s\n", try_name); 604 jio_print(warnbuf); 605 delete file; 606 file = new(ResourceObj::C_HEAP, mtInternal) fileStream(try_name); 607 FREE_C_HEAP_ARRAY(char, try_name, mtInternal); 608 } 609 if (file->is_open()) { 610 _log_file = file; 611 xmlStream* xs = new(ResourceObj::C_HEAP, mtInternal) xmlStream(file); 612 _outer_xmlStream = xs; 613 if (this == tty) xtty = xs; 614 // Write XML header. 615 xs->print_cr("<?xml version='1.0' encoding='UTF-8'?>"); 616 // (For now, don't bother to issue a DTD for this private format.) 617 jlong time_ms = os::javaTimeMillis() - tty->time_stamp().milliseconds(); 618 // %%% Should be: jlong time_ms = os::start_time_milliseconds(), if 619 // we ever get round to introduce that method on the os class 620 xs->head("hotspot_log version='%d %d'" 621 " process='%d' time_ms='"INT64_FORMAT"'", 622 LOG_MAJOR_VERSION, LOG_MINOR_VERSION, 623 os::current_process_id(), time_ms); 624 // Write VM version header immediately. 625 xs->head("vm_version"); 626 xs->head("name"); xs->text("%s", VM_Version::vm_name()); xs->cr(); 627 xs->tail("name"); 628 xs->head("release"); xs->text("%s", VM_Version::vm_release()); xs->cr(); 629 xs->tail("release"); 630 xs->head("info"); xs->text("%s", VM_Version::internal_vm_info_string()); xs->cr(); 631 xs->tail("info"); 632 xs->tail("vm_version"); 633 // Record information about the command-line invocation. 634 xs->head("vm_arguments"); // Cf. Arguments::print_on() 635 if (Arguments::num_jvm_flags() > 0) { 636 xs->head("flags"); 637 Arguments::print_jvm_flags_on(xs->text()); 638 xs->tail("flags"); 639 } 640 if (Arguments::num_jvm_args() > 0) { 641 xs->head("args"); 642 Arguments::print_jvm_args_on(xs->text()); 643 xs->tail("args"); 644 } 645 if (Arguments::java_command() != NULL) { 646 xs->head("command"); xs->text()->print_cr("%s", Arguments::java_command()); 647 xs->tail("command"); 648 } 649 if (Arguments::sun_java_launcher() != NULL) { 650 xs->head("launcher"); xs->text()->print_cr("%s", Arguments::sun_java_launcher()); 651 xs->tail("launcher"); 652 } 653 if (Arguments::system_properties() != NULL) { 654 xs->head("properties"); 655 // Print it as a java-style property list. 656 // System properties don't generally contain newlines, so don't bother with unparsing. 657 for (SystemProperty* p = Arguments::system_properties(); p != NULL; p = p->next()) { 658 xs->text()->print_cr("%s=%s", p->key(), p->value()); 659 } 660 xs->tail("properties"); 661 } 662 xs->tail("vm_arguments"); 663 // tty output per se is grouped under the <tty>...</tty> element. 664 xs->head("tty"); 665 // All further non-markup text gets copied to the tty: 666 xs->_text = this; // requires friend declaration! 667 } else { 668 delete(file); 669 // and leave xtty as NULL 670 LogVMOutput = false; 671 DisplayVMOutput = true; 672 LogCompilation = false; 673 } 674} 675 676// finish_log() is called during normal VM shutdown. finish_log_on_error() is 677// called by ostream_abort() after a fatal error. 678// 679void defaultStream::finish_log() { 680 xmlStream* xs = _outer_xmlStream; 681 xs->done("tty"); 682 683 // Other log forks are appended here, at the End of Time: 684 CompileLog::finish_log(xs->out()); // write compile logging, if any, now 685 686 xs->done("hotspot_log"); 687 xs->flush(); 688 689 fileStream* file = _log_file; 690 _log_file = NULL; 691 692 delete _outer_xmlStream; 693 _outer_xmlStream = NULL; 694 695 file->flush(); 696 delete file; 697} 698 699void defaultStream::finish_log_on_error(char *buf, int buflen) { 700 xmlStream* xs = _outer_xmlStream; 701 702 if (xs && xs->out()) { 703 704 xs->done_raw("tty"); 705 706 // Other log forks are appended here, at the End of Time: 707 CompileLog::finish_log_on_error(xs->out(), buf, buflen); // write compile logging, if any, now 708 709 xs->done_raw("hotspot_log"); 710 xs->flush(); 711 712 fileStream* file = _log_file; 713 _log_file = NULL; 714 _outer_xmlStream = NULL; 715 716 if (file) { 717 file->flush(); 718 719 // Can't delete or close the file because delete and fclose aren't 720 // async-safe. We are about to die, so leave it to the kernel. 721 // delete file; 722 } 723 } 724} 725 726intx defaultStream::hold(intx writer_id) { 727 bool has_log = has_log_file(); // check before locking 728 if (// impossible, but who knows? 729 writer_id == NO_WRITER || 730 731 // bootstrap problem 732 tty_lock == NULL || 733 734 // can't grab a lock or call Thread::current() if TLS isn't initialized 735 ThreadLocalStorage::thread() == NULL || 736 737 // developer hook 738 !SerializeVMOutput || 739 740 // VM already unhealthy 741 is_error_reported() || 742 743 // safepoint == global lock (for VM only) 744 (SafepointSynchronize::is_synchronizing() && 745 Thread::current()->is_VM_thread()) 746 ) { 747 // do not attempt to lock unless we know the thread and the VM is healthy 748 return NO_WRITER; 749 } 750 if (_writer == writer_id) { 751 // already held, no need to re-grab the lock 752 return NO_WRITER; 753 } 754 tty_lock->lock_without_safepoint_check(); 755 // got the lock 756 if (writer_id != _last_writer) { 757 if (has_log) { 758 _log_file->bol(); 759 // output a hint where this output is coming from: 760 _log_file->print_cr("<writer thread='" UINTX_FORMAT "'/>", writer_id); 761 } 762 _last_writer = writer_id; 763 } 764 _writer = writer_id; 765 return writer_id; 766} 767 768void defaultStream::release(intx holder) { 769 if (holder == NO_WRITER) { 770 // nothing to release: either a recursive lock, or we scribbled (too bad) 771 return; 772 } 773 if (_writer != holder) { 774 return; // already unlocked, perhaps via break_tty_lock_for_safepoint 775 } 776 _writer = NO_WRITER; 777 tty_lock->unlock(); 778} 779 780 781// Yuck: jio_print does not accept char*/len. 782static void call_jio_print(const char* s, size_t len) { 783 char buffer[O_BUFLEN+100]; 784 if (len > sizeof(buffer)-1) { 785 warning("increase O_BUFLEN in ostream.cpp -- output truncated"); 786 len = sizeof(buffer)-1; 787 } 788 strncpy(buffer, s, len); 789 buffer[len] = '\0'; 790 jio_print(buffer); 791} 792 793 794void defaultStream::write(const char* s, size_t len) { 795 intx thread_id = os::current_thread_id(); 796 intx holder = hold(thread_id); 797 798 if (DisplayVMOutput && 799 (_outer_xmlStream == NULL || !_outer_xmlStream->inside_attrs())) { 800 // print to output stream. It can be redirected by a vfprintf hook 801 if (s[len] == '\0') { 802 jio_print(s); 803 } else { 804 call_jio_print(s, len); 805 } 806 } 807 808 // print to log file 809 if (has_log_file()) { 810 int nl0 = _newlines; 811 xmlTextStream::write(s, len); 812 // flush the log file too, if there were any newlines 813 if (nl0 != _newlines){ 814 flush(); 815 } 816 } else { 817 update_position(s, len); 818 } 819 820 release(holder); 821} 822 823intx ttyLocker::hold_tty() { 824 if (defaultStream::instance == NULL) return defaultStream::NO_WRITER; 825 intx thread_id = os::current_thread_id(); 826 return defaultStream::instance->hold(thread_id); 827} 828 829void ttyLocker::release_tty(intx holder) { 830 if (holder == defaultStream::NO_WRITER) return; 831 defaultStream::instance->release(holder); 832} 833 834bool ttyLocker::release_tty_if_locked() { 835 intx thread_id = os::current_thread_id(); 836 if (defaultStream::instance->writer() == thread_id) { 837 // release the lock and return true so callers know if was 838 // previously held. 839 release_tty(thread_id); 840 return true; 841 } 842 return false; 843} 844 845void ttyLocker::break_tty_lock_for_safepoint(intx holder) { 846 if (defaultStream::instance != NULL && 847 defaultStream::instance->writer() == holder) { 848 if (xtty != NULL) { 849 xtty->print_cr("<!-- safepoint while printing -->"); 850 } 851 defaultStream::instance->release(holder); 852 } 853 // (else there was no lock to break) 854} 855 856void ostream_init() { 857 if (defaultStream::instance == NULL) { 858 defaultStream::instance = new(ResourceObj::C_HEAP, mtInternal) defaultStream(); 859 tty = defaultStream::instance; 860 861 // We want to ensure that time stamps in GC logs consider time 0 862 // the time when the JVM is initialized, not the first time we ask 863 // for a time stamp. So, here, we explicitly update the time stamp 864 // of tty. 865 tty->time_stamp().update_to(1); 866 } 867} 868 869void ostream_init_log() { 870 // For -Xloggc:<file> option - called in runtime/thread.cpp 871 // Note : this must be called AFTER ostream_init() 872 873 gclog_or_tty = tty; // default to tty 874 if (Arguments::gc_log_filename() != NULL) { 875 fileStream * gclog = UseGCLogFileRotation ? 876 new(ResourceObj::C_HEAP, mtInternal) 877 rotatingFileStream(Arguments::gc_log_filename()) : 878 new(ResourceObj::C_HEAP, mtInternal) 879 fileStream(Arguments::gc_log_filename()); 880 if (gclog->is_open()) { 881 // now we update the time stamp of the GC log to be synced up 882 // with tty. 883 gclog->time_stamp().update_to(tty->time_stamp().ticks()); 884 } 885 gclog_or_tty = gclog; 886 } 887 888 // If we haven't lazily initialized the logfile yet, do it now, 889 // to avoid the possibility of lazy initialization during a VM 890 // crash, which can affect the stability of the fatal error handler. 891 defaultStream::instance->has_log_file(); 892} 893 894// ostream_exit() is called during normal VM exit to finish log files, flush 895// output and free resource. 896void ostream_exit() { 897 static bool ostream_exit_called = false; 898 if (ostream_exit_called) return; 899 ostream_exit_called = true; 900 if (gclog_or_tty != tty) { 901 delete gclog_or_tty; 902 } 903 { 904 // we temporaly disable PrintMallocFree here 905 // as otherwise it'll lead to using of almost deleted 906 // tty or defaultStream::instance in logging facility 907 // of HeapFree(), see 6391258 908 DEBUG_ONLY(FlagSetting fs(PrintMallocFree, false);) 909 if (tty != defaultStream::instance) { 910 delete tty; 911 } 912 if (defaultStream::instance != NULL) { 913 delete defaultStream::instance; 914 } 915 } 916 tty = NULL; 917 xtty = NULL; 918 gclog_or_tty = NULL; 919 defaultStream::instance = NULL; 920} 921 922// ostream_abort() is called by os::abort() when VM is about to die. 923void ostream_abort() { 924 // Here we can't delete gclog_or_tty and tty, just flush their output 925 if (gclog_or_tty) gclog_or_tty->flush(); 926 if (tty) tty->flush(); 927 928 if (defaultStream::instance != NULL) { 929 static char buf[4096]; 930 defaultStream::instance->finish_log_on_error(buf, sizeof(buf)); 931 } 932} 933 934staticBufferStream::staticBufferStream(char* buffer, size_t buflen, 935 outputStream *outer_stream) { 936 _buffer = buffer; 937 _buflen = buflen; 938 _outer_stream = outer_stream; 939 // compile task prints time stamp relative to VM start 940 _stamp.update_to(1); 941} 942 943void staticBufferStream::write(const char* c, size_t len) { 944 _outer_stream->print_raw(c, (int)len); 945} 946 947void staticBufferStream::flush() { 948 _outer_stream->flush(); 949} 950 951void staticBufferStream::print(const char* format, ...) { 952 va_list ap; 953 va_start(ap, format); 954 size_t len; 955 const char* str = do_vsnprintf(_buffer, _buflen, format, ap, false, len); 956 write(str, len); 957 va_end(ap); 958} 959 960void staticBufferStream::print_cr(const char* format, ...) { 961 va_list ap; 962 va_start(ap, format); 963 size_t len; 964 const char* str = do_vsnprintf(_buffer, _buflen, format, ap, true, len); 965 write(str, len); 966 va_end(ap); 967} 968 969void staticBufferStream::vprint(const char *format, va_list argptr) { 970 size_t len; 971 const char* str = do_vsnprintf(_buffer, _buflen, format, argptr, false, len); 972 write(str, len); 973} 974 975void staticBufferStream::vprint_cr(const char* format, va_list argptr) { 976 size_t len; 977 const char* str = do_vsnprintf(_buffer, _buflen, format, argptr, true, len); 978 write(str, len); 979} 980 981bufferedStream::bufferedStream(size_t initial_size, size_t bufmax) : outputStream() { 982 buffer_length = initial_size; 983 buffer = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal); 984 buffer_pos = 0; 985 buffer_fixed = false; 986 buffer_max = bufmax; 987} 988 989bufferedStream::bufferedStream(char* fixed_buffer, size_t fixed_buffer_size, size_t bufmax) : outputStream() { 990 buffer_length = fixed_buffer_size; 991 buffer = fixed_buffer; 992 buffer_pos = 0; 993 buffer_fixed = true; 994 buffer_max = bufmax; 995} 996 997void bufferedStream::write(const char* s, size_t len) { 998 999 if(buffer_pos + len > buffer_max) { 1000 flush(); 1001 } 1002 1003 size_t end = buffer_pos + len; 1004 if (end >= buffer_length) { 1005 if (buffer_fixed) { 1006 // if buffer cannot resize, silently truncate 1007 len = buffer_length - buffer_pos - 1; 1008 } else { 1009 // For small overruns, double the buffer. For larger ones, 1010 // increase to the requested size. 1011 if (end < buffer_length * 2) { 1012 end = buffer_length * 2; 1013 } 1014 buffer = REALLOC_C_HEAP_ARRAY(char, buffer, end, mtInternal); 1015 buffer_length = end; 1016 } 1017 } 1018 memcpy(buffer + buffer_pos, s, len); 1019 buffer_pos += len; 1020 update_position(s, len); 1021} 1022 1023char* bufferedStream::as_string() { 1024 char* copy = NEW_RESOURCE_ARRAY(char, buffer_pos+1); 1025 strncpy(copy, buffer, buffer_pos); 1026 copy[buffer_pos] = 0; // terminating null 1027 return copy; 1028} 1029 1030bufferedStream::~bufferedStream() { 1031 if (!buffer_fixed) { 1032 FREE_C_HEAP_ARRAY(char, buffer, mtInternal); 1033 } 1034} 1035 1036#ifndef PRODUCT 1037 1038#if defined(SOLARIS) || defined(LINUX) || defined(_ALLBSD_SOURCE) 1039#include <sys/types.h> 1040#include <sys/socket.h> 1041#include <netinet/in.h> 1042#include <arpa/inet.h> 1043#endif 1044 1045// Network access 1046networkStream::networkStream() : bufferedStream(1024*10, 1024*10) { 1047 1048 _socket = -1; 1049 1050 int result = os::socket(AF_INET, SOCK_STREAM, 0); 1051 if (result <= 0) { 1052 assert(false, "Socket could not be created!"); 1053 } else { 1054 _socket = result; 1055 } 1056} 1057 1058int networkStream::read(char *buf, size_t len) { 1059 return os::recv(_socket, buf, (int)len, 0); 1060} 1061 1062void networkStream::flush() { 1063 if (size() != 0) { 1064 int result = os::raw_send(_socket, (char *)base(), size(), 0); 1065 assert(result != -1, "connection error"); 1066 assert(result == (int)size(), "didn't send enough data"); 1067 } 1068 reset(); 1069} 1070 1071networkStream::~networkStream() { 1072 close(); 1073} 1074 1075void networkStream::close() { 1076 if (_socket != -1) { 1077 flush(); 1078 os::socket_close(_socket); 1079 _socket = -1; 1080 } 1081} 1082 1083bool networkStream::connect(const char *ip, short port) { 1084 1085 struct sockaddr_in server; 1086 server.sin_family = AF_INET; 1087 server.sin_port = htons(port); 1088 1089 server.sin_addr.s_addr = inet_addr(ip); 1090 if (server.sin_addr.s_addr == (uint32_t)-1) { 1091 struct hostent* host = os::get_host_by_name((char*)ip); 1092 if (host != NULL) { 1093 memcpy(&server.sin_addr, host->h_addr_list[0], host->h_length); 1094 } else { 1095 return false; 1096 } 1097 } 1098 1099 1100 int result = os::connect(_socket, (struct sockaddr*)&server, sizeof(struct sockaddr_in)); 1101 return (result >= 0); 1102} 1103 1104#endif 1105