The open source OpenXR runtime
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

u/logging: Refactor logging printing functions

authored by

Jakob Bornecrantz and committed by
Ryan Pavlik
b33e6569 d13f59f6

+119 -133
+119 -133
src/xrt/auxiliary/util/u_logging.c
··· 12 12 #include "xrt/xrt_config_build.h" 13 13 14 14 #include "util/u_debug.h" 15 + #include "util/u_truncate_printf.h" 15 16 16 17 #include <assert.h> 17 18 #include <stdio.h> 18 19 #include <stdarg.h> 20 + 21 + 22 + /* 23 + * 24 + * Defines. 25 + * 26 + */ 27 + 28 + /* 29 + * Avoid 4K stack variables. 30 + * https://learn.microsoft.com/en-us/windows/win32/devnotes/-win32-chkstk 31 + */ 32 + #define LOG_BUFFER_SIZE (3 * 1024) 19 33 20 34 21 35 /* ··· 159 173 160 174 /* 161 175 * 162 - * General logging functions. 176 + * Platform specific functions. 163 177 * 164 178 */ 165 179 ··· 182 196 return ANDROID_LOG_INFO; 183 197 } 184 198 185 - void 186 - u_log(const char *file, int line, const char *func, enum u_logging_level level, const char *format, ...) 187 - { 188 - // print_prefix(func, level); 189 - android_LogPriority prio = u_log_convert_priority(level); 190 - va_list args; 191 - va_start(args, format); 192 - DISPATCH_SINK(file, line, func, level, format, args); 193 - __android_log_vprint(prio, func, format, args); 194 - va_end(args); 195 - } 196 - 197 - void 198 - u_log_xdev(const char *file, 199 - int line, 200 - const char *func, 201 - enum u_logging_level level, 202 - struct xrt_device *xdev, 203 - const char *format, 204 - ...) 205 - { 206 - android_LogPriority prio = u_log_convert_priority(level); 207 - va_list args; 208 - va_start(args, format); 209 - DISPATCH_SINK(file, line, func, level, format, args); 210 - __android_log_vprint(prio, func, format, args); 211 - va_end(args); 212 - } 213 - 214 - 215 199 #elif defined(XRT_OS_WINDOWS) 216 200 217 201 #include <debugapi.h> 218 202 219 - static int 220 - print_prefix(int remainingBuf, char *buf, const char *func, enum u_logging_level level) 221 - { 222 - int printed = 0; 223 - switch (level) { 224 - case U_LOGGING_TRACE: printed = sprintf_s(buf, remainingBuf, "TRACE "); break; 225 - case U_LOGGING_DEBUG: printed = sprintf_s(buf, remainingBuf, "DEBUG "); break; 226 - case U_LOGGING_INFO: printed = sprintf_s(buf, remainingBuf, " INFO "); break; 227 - case U_LOGGING_WARN: printed = sprintf_s(buf, remainingBuf, " WARN "); break; 228 - case U_LOGGING_ERROR: printed = sprintf_s(buf, remainingBuf, "ERROR "); break; 229 - case U_LOGGING_RAW: break; 230 - default: break; 231 - } 232 - 233 - if (level != U_LOGGING_RAW && func != NULL) { 234 - printed += sprintf_s(buf + printed, remainingBuf - printed, "[%s] ", func); 235 - } 236 - return printed; 237 - } 238 - 239 - void 240 - u_log(const char *file, int line, const char *func, enum u_logging_level level, const char *format, ...) 241 - { 242 - 243 - char buf[16384] = {0}; 244 - 245 - int remainingBuffer = sizeof(buf) - 2; // 2 for \n\0 246 - int printed = print_prefix(remainingBuffer, buf, func, level); 247 - 248 - va_list args; 249 - va_start(args, format); 250 - DISPATCH_SINK(file, line, func, level, format, args); 251 - printed += vsprintf_s(buf + printed, remainingBuffer - printed, format, args); 252 - va_end(args); 253 - buf[printed++] = '\n'; 254 - buf[printed++] = '\0'; 255 - OutputDebugStringA(buf); 256 - fprintf(stderr, "%s", buf); 257 - } 258 - 259 - void 260 - u_log_xdev(const char *file, 261 - int line, 262 - const char *func, 263 - enum u_logging_level level, 264 - struct xrt_device *xdev, 265 - const char *format, 266 - ...) 267 - { 268 - 269 - char buf[16384] = {0}; 270 - 271 - int remainingBuffer = sizeof(buf) - 2; // 2 for \n\0 272 - int printed = print_prefix(remainingBuffer, buf, func, level); 273 - 274 - va_list args; 275 - va_start(args, format); 276 - DISPATCH_SINK(file, line, func, level, format, args); 277 - printed += vsprintf_s(buf + printed, remainingBuffer - printed, format, args); 278 - va_end(args); 279 - buf[printed++] = '\n'; 280 - buf[printed++] = '\0'; 281 - OutputDebugStringA(buf); 282 - fprintf(stderr, "%s", buf); 283 - } 284 - 285 - 286 203 #else 287 204 288 205 #include <unistd.h> 206 + 207 + #endif 208 + 289 209 290 210 /* 291 211 * ··· 293 213 * 294 214 */ 295 215 216 + #define CHECK_RET_AND_UPDATE_STATE() \ 217 + do { \ 218 + if (ret < 0) { \ 219 + return ret; \ 220 + } \ 221 + \ 222 + printed += ret; /* Is not negative, checked above. */ \ 223 + remaining -= ret; \ 224 + buf += ret; /* Continue in the buffer from where we left off. */ \ 225 + } while (false); 296 226 297 227 #ifdef XRT_FEATURE_COLOR_LOG 298 228 #define COLOR_TRACE "\033[2m" ··· 302 232 #define COLOR_ERROR "\033[31m" 303 233 #define COLOR_RESET "\033[0m" 304 234 305 - static void 306 - print_prefix_color(const char *func, enum u_logging_level level) 235 + static int 236 + print_prefix_color(const char *func, enum u_logging_level level, char *buf, int remaining) 307 237 { 308 238 switch (level) { 309 - case U_LOGGING_TRACE: fprintf(stderr, COLOR_TRACE "TRACE " COLOR_RESET); break; 310 - case U_LOGGING_DEBUG: fprintf(stderr, COLOR_DEBUG "DEBUG " COLOR_RESET); break; 311 - case U_LOGGING_INFO: fprintf(stderr, COLOR_INFO " INFO " COLOR_RESET); break; 312 - case U_LOGGING_WARN: fprintf(stderr, COLOR_WARN " WARN " COLOR_RESET); break; 313 - case U_LOGGING_ERROR: fprintf(stderr, COLOR_ERROR "ERROR " COLOR_RESET); break; 314 - case U_LOGGING_RAW: break; 315 - default: break; 239 + case U_LOGGING_TRACE: return u_truncate_snprintf(buf, remaining, COLOR_TRACE "TRACE " COLOR_RESET); 240 + case U_LOGGING_DEBUG: return u_truncate_snprintf(buf, remaining, COLOR_DEBUG "DEBUG " COLOR_RESET); 241 + case U_LOGGING_INFO: return u_truncate_snprintf(buf, remaining, COLOR_INFO " INFO " COLOR_RESET); 242 + case U_LOGGING_WARN: return u_truncate_snprintf(buf, remaining, COLOR_WARN " WARN " COLOR_RESET); 243 + case U_LOGGING_ERROR: return u_truncate_snprintf(buf, remaining, COLOR_ERROR "ERROR " COLOR_RESET); 244 + case U_LOGGING_RAW: return 0; 245 + default: return 0; 316 246 } 317 247 } 318 248 #endif 319 249 320 - static void 321 - print_prefix_mono(const char *func, enum u_logging_level level) 250 + static int 251 + print_prefix_mono(const char *func, enum u_logging_level level, char *buf, int remaining) 322 252 { 323 253 switch (level) { 324 - case U_LOGGING_TRACE: fprintf(stderr, "TRACE "); break; 325 - case U_LOGGING_DEBUG: fprintf(stderr, "DEBUG "); break; 326 - case U_LOGGING_INFO: fprintf(stderr, " INFO "); break; 327 - case U_LOGGING_WARN: fprintf(stderr, " WARN "); break; 328 - case U_LOGGING_ERROR: fprintf(stderr, "ERROR "); break; 329 - case U_LOGGING_RAW: break; 330 - default: break; 254 + case U_LOGGING_TRACE: return u_truncate_snprintf(buf, remaining, "TRACE "); 255 + case U_LOGGING_DEBUG: return u_truncate_snprintf(buf, remaining, "DEBUG "); 256 + case U_LOGGING_INFO: return u_truncate_snprintf(buf, remaining, " INFO "); 257 + case U_LOGGING_WARN: return u_truncate_snprintf(buf, remaining, " WARN "); 258 + case U_LOGGING_ERROR: return u_truncate_snprintf(buf, remaining, "ERROR "); 259 + case U_LOGGING_RAW: return 0; 260 + default: return 0; 331 261 } 332 262 } 333 263 334 - static void 335 - print_prefix(const char *func, enum u_logging_level level) 264 + static int 265 + print_prefix(const char *func, enum u_logging_level level, char *buf, int remaining) 336 266 { 267 + int printed = 0; 268 + int ret = 0; 269 + 337 270 #ifdef XRT_FEATURE_COLOR_LOG 338 271 if (isatty(STDERR_FILENO)) { 339 - print_prefix_color(func, level); 272 + ret = print_prefix_color(func, level, buf, remaining); 340 273 } else { 341 - print_prefix_mono(func, level); 274 + ret = print_prefix_mono(func, level, buf, remaining); 342 275 } 343 276 #else 344 - print_prefix_mono(func, level); 277 + ret = print_prefix_mono(func, level, buf, remaining); 345 278 #endif 346 279 280 + // Does what it says. 281 + CHECK_RET_AND_UPDATE_STATE(); 282 + 283 + // Print the function name. 347 284 if (level != U_LOGGING_RAW && func != NULL) { 348 - fprintf(stderr, "[%s] ", func); 285 + ret = u_truncate_snprintf(buf, remaining, "[%s] ", func); 349 286 } 287 + 288 + // Does what it says. 289 + CHECK_RET_AND_UPDATE_STATE(); 290 + 291 + // Total printed characters. 292 + return printed; 293 + } 294 + 295 + static int 296 + do_print(const char *file, int line, const char *func, enum u_logging_level level, const char *format, va_list args) 297 + { 298 + char storage[LOG_BUFFER_SIZE]; 299 + 300 + int remaining = sizeof(storage) - 2; // 2 for \n\0 301 + int printed = 0; 302 + char *buf = storage; // We update the pointer. 303 + int ret = 0; 304 + 305 + // The prefix of the log. 306 + ret = print_prefix(func, level, buf, remaining); 307 + 308 + // Does what it says. 309 + CHECK_RET_AND_UPDATE_STATE(); 310 + 311 + ret = u_truncate_vsnprintf(buf, remaining, format, args); 312 + 313 + // Does what it says. 314 + CHECK_RET_AND_UPDATE_STATE(); 315 + 316 + /* 317 + * The variable storage now holds the entire null-terminated message, 318 + * but without a new-line character, proceed to output it. 319 + */ 320 + assert(storage[printed] == '\0'); 321 + 322 + 323 + #ifdef XRT_OS_ANDROID 324 + 325 + android_LogPriority prio = u_log_convert_priority(level); 326 + __android_log_write(prio, func, storage); 327 + 328 + #elif defined XRT_OS_WINDOWS || defined XRT_OS_LINUX 329 + 330 + #if defined XRT_OS_WINDOWS 331 + OutputDebugStringA(storage); // No newline. 332 + #endif 333 + 334 + // We want a newline, so add it, then null-terminate again. 335 + storage[printed++] = '\n'; 336 + storage[printed] = '\0'; // Don't count zero termination as printed. 337 + 338 + fwrite(storage, printed, 1, stderr); 339 + 340 + #else 341 + #error "Port needed for logging function" 342 + #endif 343 + 344 + return printed; 350 345 } 351 346 352 347 ··· 359 354 void 360 355 u_log(const char *file, int line, const char *func, enum u_logging_level level, const char *format, ...) 361 356 { 362 - print_prefix(func, level); 363 - 364 357 va_list args; 365 358 va_start(args, format); 366 359 DISPATCH_SINK(file, line, func, level, format, args); 367 - vfprintf(stderr, format, args); 360 + do_print(file, line, func, level, format, args); 368 361 va_end(args); 369 - 370 - fprintf(stderr, "\n"); 371 362 } 372 363 373 364 void ··· 379 370 const char *format, 380 371 ...) 381 372 { 382 - print_prefix(func, level); 383 - 384 373 va_list args; 385 374 va_start(args, format); 386 375 DISPATCH_SINK(file, line, func, level, format, args); 387 - vfprintf(stderr, format, args); 376 + do_print(file, line, func, level, format, args); 388 377 va_end(args); 389 - 390 - fprintf(stderr, "\n"); 391 378 } 392 - #endif