1 /* Debugging routines for the remote server for GDB. 2 Copyright (C) 2014-2020 Free Software Foundation, Inc. 3 4 This file is part of GDB. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 18 19 #include "server.h" 20 #include <chrono> 21 22 #if !defined (IN_PROCESS_AGENT) 23 int remote_debug = 0; 24 #endif 25 26 /* Output file for debugging. Default to standard error. */ 27 FILE *debug_file = stderr; 28 29 /* See debug.h. */ 30 int debug_threads; 31 32 /* Include timestamps in debugging output. */ 33 int debug_timestamp; 34 35 #if !defined (IN_PROCESS_AGENT) 36 37 /* See debug.h. */ 38 39 void 40 debug_set_output (const char *new_debug_file) 41 { 42 /* Close any existing file and reset to standard error. */ 43 if (debug_file != stderr) 44 { 45 fclose (debug_file); 46 } 47 debug_file = stderr; 48 49 /* Catch empty filenames. */ 50 if (new_debug_file == nullptr || strlen (new_debug_file) == 0) 51 return; 52 53 FILE *fptr = fopen (new_debug_file, "w"); 54 55 if (fptr == nullptr) 56 { 57 debug_printf ("Cannot open %s for writing. %s. Switching to stderr.\n", 58 new_debug_file, safe_strerror (errno)); 59 return; 60 } 61 62 debug_file = fptr; 63 } 64 65 #endif 66 67 /* Print a debugging message. 68 If the text begins a new line it is preceded by a timestamp. 69 We don't get fancy with newline checking, we just check whether the 70 previous call ended with "\n". */ 71 72 void 73 debug_vprintf (const char *format, va_list ap) 74 { 75 #if !defined (IN_PROCESS_AGENT) 76 /* N.B. Not thread safe, and can't be used, as is, with IPA. */ 77 static int new_line = 1; 78 79 if (debug_timestamp && new_line) 80 { 81 using namespace std::chrono; 82 83 steady_clock::time_point now = steady_clock::now (); 84 seconds s = duration_cast<seconds> (now.time_since_epoch ()); 85 microseconds us = duration_cast<microseconds> (now.time_since_epoch ()) - s; 86 87 fprintf (debug_file, "%ld.%06ld ", (long) s.count (), (long) us.count ()); 88 } 89 #endif 90 91 vfprintf (debug_file, format, ap); 92 93 #if !defined (IN_PROCESS_AGENT) 94 if (*format) 95 new_line = format[strlen (format) - 1] == '\n'; 96 #endif 97 } 98 99 /* Flush debugging output. 100 This is called, for example, when starting an inferior to ensure all debug 101 output thus far appears before any inferior output. */ 102 103 void 104 debug_flush (void) 105 { 106 fflush (debug_file); 107 } 108 109 /* Notify the user that the code is entering FUNCTION_NAME. 110 FUNCTION_NAME is the name of the calling function, or NULL if unknown. 111 112 This is intended to be called via the debug_enter macro. */ 113 114 void 115 do_debug_enter (const char *function_name) 116 { 117 if (function_name != NULL) 118 debug_printf (">>>> entering %s\n", function_name); 119 } 120 121 /* Notify the user that the code is exiting FUNCTION_NAME. 122 FUNCTION_NAME is the name of the calling function, or NULL if unknown. 123 124 This is intended to be called via the debug_exit macro. */ 125 126 void 127 do_debug_exit (const char *function_name) 128 { 129 if (function_name != NULL) 130 debug_printf ("<<<< exiting %s\n", function_name); 131 } 132 133 /* See debug.h. */ 134 135 ssize_t 136 debug_write (const void *buf, size_t nbyte) 137 { 138 int fd = fileno (debug_file); 139 return write (fd, buf, nbyte); 140 } 141