sewardj | de4a1d0 | 2002-03-22 01:27:54 +0000 | [diff] [blame] | 1 | |
| 2 | /*--------------------------------------------------------------------*/ |
| 3 | /*--- For sending error/informative messages. ---*/ |
nethercote | 85cdd34 | 2004-08-01 22:36:40 +0000 | [diff] [blame] | 4 | /*--- vg_messages.c ---*/ |
sewardj | de4a1d0 | 2002-03-22 01:27:54 +0000 | [diff] [blame] | 5 | /*--------------------------------------------------------------------*/ |
| 6 | |
| 7 | /* |
njn | b9c427c | 2004-12-01 14:14:42 +0000 | [diff] [blame] | 8 | This file is part of Valgrind, a dynamic binary instrumentation |
| 9 | framework. |
sewardj | de4a1d0 | 2002-03-22 01:27:54 +0000 | [diff] [blame] | 10 | |
njn | 5361242 | 2005-03-12 16:22:54 +0000 | [diff] [blame] | 11 | Copyright (C) 2000-2005 Julian Seward |
sewardj | de4a1d0 | 2002-03-22 01:27:54 +0000 | [diff] [blame] | 12 | jseward@acm.org |
sewardj | de4a1d0 | 2002-03-22 01:27:54 +0000 | [diff] [blame] | 13 | |
| 14 | This program is free software; you can redistribute it and/or |
| 15 | modify it under the terms of the GNU General Public License as |
| 16 | published by the Free Software Foundation; either version 2 of the |
| 17 | License, or (at your option) any later version. |
| 18 | |
| 19 | This program is distributed in the hope that it will be useful, but |
| 20 | WITHOUT ANY WARRANTY; without even the implied warranty of |
| 21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 22 | General Public License for more details. |
| 23 | |
| 24 | You should have received a copy of the GNU General Public License |
| 25 | along with this program; if not, write to the Free Software |
| 26 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
| 27 | 02111-1307, USA. |
| 28 | |
njn25 | e49d8e7 | 2002-09-23 09:36:25 +0000 | [diff] [blame] | 29 | The GNU General Public License is contained in the file COPYING. |
sewardj | de4a1d0 | 2002-03-22 01:27:54 +0000 | [diff] [blame] | 30 | */ |
| 31 | |
| 32 | |
nethercote | f1e5e15 | 2004-09-01 23:58:16 +0000 | [diff] [blame] | 33 | #include "core.h" |
sewardj | 1cf558c | 2005-04-25 01:36:56 +0000 | [diff] [blame] | 34 | #include "pub_core_debuglog.h" /* VG_(debugLog_vprintf) */ |
sewardj | de4a1d0 | 2002-03-22 01:27:54 +0000 | [diff] [blame] | 35 | |
thughes | 6233a38 | 2004-08-21 11:10:44 +0000 | [diff] [blame] | 36 | #include <time.h> |
| 37 | #include <sys/time.h> |
| 38 | |
njn | 14319cc | 2005-03-13 06:26:22 +0000 | [diff] [blame] | 39 | /* Size of a buffer used for creating messages. */ |
| 40 | #define M_MSGBUF 10000 |
sewardj | de4a1d0 | 2002-03-22 01:27:54 +0000 | [diff] [blame] | 41 | |
njn | 695c16e | 2005-03-27 03:40:28 +0000 | [diff] [blame] | 42 | static char mbuf[M_MSGBUF]; |
| 43 | static int n_mbuf; |
sewardj | de4a1d0 | 2002-03-22 01:27:54 +0000 | [diff] [blame] | 44 | |
sewardj | 1cf558c | 2005-04-25 01:36:56 +0000 | [diff] [blame] | 45 | static void add_to_buf ( HChar c, void *p ) |
sewardj | de4a1d0 | 2002-03-22 01:27:54 +0000 | [diff] [blame] | 46 | { |
njn | 695c16e | 2005-03-27 03:40:28 +0000 | [diff] [blame] | 47 | if (n_mbuf >= (M_MSGBUF-1)) return; |
| 48 | mbuf[n_mbuf++] = c; |
| 49 | mbuf[n_mbuf] = 0; |
sewardj | de4a1d0 | 2002-03-22 01:27:54 +0000 | [diff] [blame] | 50 | } |
| 51 | |
thughes | 6233a38 | 2004-08-21 11:10:44 +0000 | [diff] [blame] | 52 | static void add_timestamp ( Char *buf ) |
| 53 | { |
| 54 | struct timeval tv; |
| 55 | struct tm tm; |
| 56 | |
| 57 | if ( gettimeofday( &tv, NULL ) == 0 && |
| 58 | localtime_r( &tv.tv_sec, &tm ) == &tm ) { |
| 59 | VG_(sprintf)( buf, "%04d-%02d-%02d %02d:%02d:%02d.%03d ", |
| 60 | tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, |
| 61 | tm.tm_hour, tm.tm_min, tm.tm_sec, tv.tv_usec / 1000 ); |
| 62 | } |
| 63 | else { |
| 64 | VG_(strcpy)( buf, "" ); |
| 65 | } |
| 66 | |
| 67 | return; |
| 68 | } |
| 69 | |
sewardj | 2c5ffbe | 2005-03-12 13:32:06 +0000 | [diff] [blame] | 70 | static int add_to_msg ( const Char *format, ... ) |
sewardj | de4a1d0 | 2002-03-22 01:27:54 +0000 | [diff] [blame] | 71 | { |
fitzhardinge | 39de4b4 | 2003-10-31 07:12:21 +0000 | [diff] [blame] | 72 | int count; |
sewardj | de4a1d0 | 2002-03-22 01:27:54 +0000 | [diff] [blame] | 73 | va_list vargs; |
| 74 | va_start(vargs,format); |
sewardj | 1cf558c | 2005-04-25 01:36:56 +0000 | [diff] [blame] | 75 | count = VG_(debugLog_vprintf) ( add_to_buf, NULL, format, vargs ); |
sewardj | de4a1d0 | 2002-03-22 01:27:54 +0000 | [diff] [blame] | 76 | va_end(vargs); |
fitzhardinge | 39de4b4 | 2003-10-31 07:12:21 +0000 | [diff] [blame] | 77 | return count; |
| 78 | } |
| 79 | |
sewardj | 2c5ffbe | 2005-03-12 13:32:06 +0000 | [diff] [blame] | 80 | static int start_msg ( VgMsgKind kind ) |
njn | c5a7909 | 2005-03-12 04:59:51 +0000 | [diff] [blame] | 81 | { |
| 82 | Char ts[32]; |
| 83 | Char c; |
| 84 | static const Char pfx[] = ">>>>>>>>>>>>>>>>"; |
njn | 695c16e | 2005-03-27 03:40:28 +0000 | [diff] [blame] | 85 | n_mbuf = 0; |
| 86 | mbuf[n_mbuf] = 0; |
njn | c5a7909 | 2005-03-12 04:59:51 +0000 | [diff] [blame] | 87 | |
| 88 | if (VG_(clo_time_stamp)) |
| 89 | add_timestamp(ts); |
| 90 | else |
| 91 | VG_(strcpy)(ts, ""); |
| 92 | switch (kind) { |
| 93 | case Vg_UserMsg: c = '='; break; |
| 94 | case Vg_DebugMsg: c = '-'; break; |
| 95 | case Vg_DebugExtraMsg: c = '+'; break; |
| 96 | case Vg_ClientMsg: c = '*'; break; |
| 97 | default: c = '?'; break; |
| 98 | } |
| 99 | // The pfx trick prints one or more '>' characters in front of the |
| 100 | // messages when running Valgrind under Valgrind, one per level of |
| 101 | // self-hosting. |
| 102 | return add_to_msg( "%s%c%c%s%d%c%c ", |
| 103 | &pfx[sizeof(pfx)-1-RUNNING_ON_VALGRIND], |
| 104 | c,c, ts, VG_(getpid)(), c,c ); |
| 105 | } |
| 106 | |
sewardj | 2c5ffbe | 2005-03-12 13:32:06 +0000 | [diff] [blame] | 107 | static |
njn | c5a7909 | 2005-03-12 04:59:51 +0000 | [diff] [blame] | 108 | int end_msg ( void ) |
| 109 | { |
| 110 | int count = 0; |
| 111 | if (VG_(clo_log_fd) >= 0) { |
| 112 | add_to_buf('\n',0); |
njn | 695c16e | 2005-03-27 03:40:28 +0000 | [diff] [blame] | 113 | VG_(send_bytes_to_logging_sink) ( mbuf, VG_(strlen)(mbuf) ); |
njn | c5a7909 | 2005-03-12 04:59:51 +0000 | [diff] [blame] | 114 | count = 1; |
| 115 | } |
| 116 | return count; |
| 117 | } |
| 118 | |
sewardj | b5f6f51 | 2005-03-10 23:59:00 +0000 | [diff] [blame] | 119 | int VG_(vmessage) ( VgMsgKind kind, const Char* format, va_list vargs ) |
fitzhardinge | 39de4b4 | 2003-10-31 07:12:21 +0000 | [diff] [blame] | 120 | { |
| 121 | int count; |
njn | c5a7909 | 2005-03-12 04:59:51 +0000 | [diff] [blame] | 122 | count = start_msg ( kind ); |
sewardj | 1cf558c | 2005-04-25 01:36:56 +0000 | [diff] [blame] | 123 | count += VG_(debugLog_vprintf) ( add_to_buf, NULL, format, vargs ); |
njn | c5a7909 | 2005-03-12 04:59:51 +0000 | [diff] [blame] | 124 | count += end_msg(); |
fitzhardinge | 39de4b4 | 2003-10-31 07:12:21 +0000 | [diff] [blame] | 125 | return count; |
sewardj | de4a1d0 | 2002-03-22 01:27:54 +0000 | [diff] [blame] | 126 | } |
| 127 | |
| 128 | /* Send a simple single-part message. */ |
sewardj | b5f6f51 | 2005-03-10 23:59:00 +0000 | [diff] [blame] | 129 | int VG_(message) ( VgMsgKind kind, const Char* format, ... ) |
sewardj | de4a1d0 | 2002-03-22 01:27:54 +0000 | [diff] [blame] | 130 | { |
fitzhardinge | 39de4b4 | 2003-10-31 07:12:21 +0000 | [diff] [blame] | 131 | int count; |
sewardj | de4a1d0 | 2002-03-22 01:27:54 +0000 | [diff] [blame] | 132 | va_list vargs; |
| 133 | va_start(vargs,format); |
fitzhardinge | 39de4b4 | 2003-10-31 07:12:21 +0000 | [diff] [blame] | 134 | count = VG_(vmessage) ( kind, format, vargs ); |
sewardj | de4a1d0 | 2002-03-22 01:27:54 +0000 | [diff] [blame] | 135 | va_end(vargs); |
fitzhardinge | 39de4b4 | 2003-10-31 07:12:21 +0000 | [diff] [blame] | 136 | return count; |
sewardj | de4a1d0 | 2002-03-22 01:27:54 +0000 | [diff] [blame] | 137 | } |
| 138 | |
sewardj | 570f890 | 2002-11-03 11:44:36 +0000 | [diff] [blame] | 139 | /* Do the low-level send of a message to the logging sink. */ |
| 140 | void VG_(send_bytes_to_logging_sink) ( Char* msg, Int nbytes ) |
| 141 | { |
| 142 | Int rc; |
| 143 | if (VG_(logging_to_filedes)) { |
nethercote | f854867 | 2004-06-21 12:42:35 +0000 | [diff] [blame] | 144 | VG_(write)( VG_(clo_log_fd), msg, nbytes ); |
sewardj | 570f890 | 2002-11-03 11:44:36 +0000 | [diff] [blame] | 145 | } else { |
nethercote | f854867 | 2004-06-21 12:42:35 +0000 | [diff] [blame] | 146 | rc = VG_(write_socket)( VG_(clo_log_fd), msg, nbytes ); |
sewardj | 570f890 | 2002-11-03 11:44:36 +0000 | [diff] [blame] | 147 | if (rc == -1) { |
| 148 | /* for example, the listener process died. Switch back to |
| 149 | stderr. */ |
| 150 | VG_(logging_to_filedes) = True; |
| 151 | VG_(clo_log_to) = VgLogTo_Fd; |
nethercote | f854867 | 2004-06-21 12:42:35 +0000 | [diff] [blame] | 152 | VG_(clo_log_fd) = 2; |
| 153 | VG_(write)( VG_(clo_log_fd), msg, nbytes ); |
sewardj | 570f890 | 2002-11-03 11:44:36 +0000 | [diff] [blame] | 154 | } |
sewardj | de4a1d0 | 2002-03-22 01:27:54 +0000 | [diff] [blame] | 155 | } |
| 156 | } |
| 157 | |
sewardj | de4a1d0 | 2002-03-22 01:27:54 +0000 | [diff] [blame] | 158 | /*--------------------------------------------------------------------*/ |
nethercote | c91ce8d | 2004-08-09 11:15:10 +0000 | [diff] [blame] | 159 | /*--- end ---*/ |
sewardj | de4a1d0 | 2002-03-22 01:27:54 +0000 | [diff] [blame] | 160 | /*--------------------------------------------------------------------*/ |