1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/glue/Debug.h"
8 #include "mozilla/Fuzzing.h"
9 #include "mozilla/Sprintf.h"
20 # include <android/log.h>
24 static void vprintf_stderr_buffered(const char* aFmt
, va_list aArgs
) {
25 // Avoid interleaving by writing to an on-stack buffer and then writing in one
26 // go with fputs, as long as the output fits into the buffer.
29 va_copy(argsCpy
, aArgs
);
30 int n
= VsprintfLiteral(buffer
, aFmt
, aArgs
);
31 if (n
< int(sizeof(buffer
))) {
32 fputs(buffer
, stderr
);
34 // Message too long for buffer. Just print it, not worrying about
35 // interleaving. (We could malloc, but the underlying write() syscall could
36 // get interleaved if the output is too big anyway.)
37 vfprintf(stderr
, aFmt
, argsCpy
);
45 MFBT_API
void vprintf_stderr(const char* aFmt
, va_list aArgs
) {
46 if (IsDebuggerPresent()) {
47 int lengthNeeded
= _vscprintf(aFmt
, aArgs
);
50 auto buf
= mozilla::MakeUnique
<char[]>(lengthNeeded
);
53 va_copy(argsCpy
, aArgs
);
54 vsnprintf(buf
.get(), lengthNeeded
, aFmt
, argsCpy
);
55 buf
[lengthNeeded
- 1] = '\0';
57 OutputDebugStringA(buf
.get());
62 vprintf_stderr_buffered(aFmt
, aArgs
);
65 #elif defined(ANDROID)
66 MFBT_API
void vprintf_stderr(const char* aFmt
, va_list aArgs
) {
67 __android_log_vprint(ANDROID_LOG_INFO
, "Gecko", aFmt
, aArgs
);
69 #elif defined(FUZZING_SNAPSHOT)
70 MFBT_API
void vprintf_stderr(const char* aFmt
, va_list aArgs
) {
72 auto msgbuf
= mozilla::Vsmprintf(aFmt
, aArgs
);
73 nyx_puts(msgbuf
.get());
75 vprintf_stderr_buffered(aFmt
, aArgs
);
79 MFBT_API
void vprintf_stderr(const char* aFmt
, va_list aArgs
) {
80 vprintf_stderr_buffered(aFmt
, aArgs
);
84 MFBT_API
void printf_stderr(const char* aFmt
, ...) {
87 vprintf_stderr(aFmt
, args
);
91 MFBT_API
void fprintf_stderr(FILE* aFile
, const char* aFmt
, ...) {
94 if (aFile
== stderr
) {
95 vprintf_stderr(aFmt
, args
);
97 vfprintf(aFile
, aFmt
, args
);
102 MFBT_API
void print_stderr(std::stringstream
& aStr
) {
104 // On Android logcat output is truncated to 1024 chars per line, and
105 // we usually use std::stringstream to build up giant multi-line gobs
106 // of output. So to avoid the truncation we find the newlines and
107 // print the lines individually.
109 while (std::getline(aStr
, line
)) {
110 printf_stderr("%s\n", line
.c_str());
113 printf_stderr("%s", aStr
.str().c_str());
117 MFBT_API
void fprint_stderr(FILE* aFile
, std::stringstream
& aStr
) {
118 if (aFile
== stderr
) {
121 fprintf_stderr(aFile
, "%s", aStr
.str().c_str());