1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
12 //static Lock debuglock;
14 // Clang requires this function to not be inlined (see below).
15 static void go_vprintf(const char*, va_list)
16 __attribute__((noinline
));
18 // write to goroutine-local buffer if diverting output,
19 // or else standard error.
21 gwrite(const void *v
, intgo n
)
25 if(g
== nil
|| g
->writebuf
== nil
) {
26 // Avoid -D_FORTIFY_SOURCE problems.
27 int rv
__attribute__((unused
));
29 rv
= runtime_write(2, v
, n
);
38 runtime_memmove(g
->writebuf
, v
, n
);
44 runtime_dump(byte
*p
, int32 n
)
49 runtime_printpointer((byte
*)(uintptr
)(p
[i
]>>4));
50 runtime_printpointer((byte
*)(uintptr
)(p
[i
]&0xf));
61 runtime_prints(const char *s
)
63 gwrite(s
, runtime_findnull((const byte
*)s
));
66 #if defined (__clang__) && (defined (__i386__) || defined (__x86_64__))
67 // LLVM's code generator does not currently support split stacks for vararg
68 // functions, so we disable the feature for this function under Clang. This
69 // appears to be OK as long as:
70 // - this function only calls non-inlined, internal-linkage (hence no dynamic
71 // loader) functions compiled with split stacks (i.e. go_vprintf), which can
72 // allocate more stack space as required;
73 // - this function itself does not occupy more than BACKOFF bytes of stack space
74 // (see libgcc/config/i386/morestack.S).
75 // These conditions are currently known to be satisfied by Clang on x86-32 and
76 // x86-64. Note that signal handlers receive slightly less stack space than they
77 // would normally do if they happen to be called while this function is being
78 // run. If this turns out to be a problem we could consider increasing BACKOFF.
81 runtime_printf(const char *s
, ...)
82 __attribute__((no_split_stack
));
85 runtime_snprintf(byte
*buf
, int32 n
, const char *s
, ...)
86 __attribute__((no_split_stack
));
91 runtime_printf(const char *s
, ...)
101 runtime_snprintf(byte
*buf
, int32 n
, const char *s
, ...)
113 m
= g
->writebuf
- buf
;
119 // Very simple printf. Only for debugging prints.
120 // Do not add to this without checking with Rob.
122 go_vprintf(const char *s
, va_list va
)
126 //runtime_lock(&debuglock);
137 runtime_printslice(va_arg(va
, Slice
));
140 runtime_printbyte(va_arg(va
, int32
));
143 runtime_printint(va_arg(va
, int32
));
146 runtime_printint(va_arg(va
, int64
));
149 runtime_printeface(va_arg(va
, Eface
));
152 runtime_printfloat(va_arg(va
, float64
));
155 runtime_printcomplex(va_arg(va
, complex double));
158 runtime_printiface(va_arg(va
, Iface
));
161 runtime_printpointer(va_arg(va
, void*));
164 runtime_prints(va_arg(va
, char*));
167 runtime_printstring(va_arg(va
, String
));
170 runtime_printbool(va_arg(va
, int));
173 runtime_printuint(va_arg(va
, uint64
));
176 runtime_printhex(va_arg(va
, uint32
));
179 runtime_printhex(va_arg(va
, uint64
));
187 //runtime_unlock(&debuglock);
191 runtime_printpc(void *p
__attribute__ ((unused
)))
193 runtime_prints("PC=");
194 runtime_printhex((uint64
)(uintptr
)runtime_getcallerpc(p
));
198 runtime_printbool(_Bool v
)
208 runtime_printbyte(int8 c
)
214 runtime_printfloat(double v
)
233 n
= 7; // digits printed
237 if(isinf(1/v
) && 1/v
< 0)
268 // format +d.dddd+edd
288 buf
[n
+4] = (e
/100) + '0';
289 buf
[n
+5] = (e
/10)%10 + '0';
290 buf
[n
+6] = (e
%10) + '0';
295 runtime_printcomplex(complex double v
)
298 runtime_printfloat(creal(v
));
299 runtime_printfloat(cimag(v
));
304 runtime_printuint(uint64 v
)
309 for(i
=nelem(buf
)-1; i
>0; i
--) {
315 gwrite(buf
+i
, nelem(buf
)-i
);
319 runtime_printint(int64 v
)
325 runtime_printuint(v
);
329 runtime_printhex(uint64 v
)
331 static const char *dig
= "0123456789abcdef";
337 buf
[--i
] = dig
[v
%16];
342 gwrite(buf
+i
, nelem(buf
)-i
);
346 runtime_printpointer(void *p
)
348 runtime_printhex((uintptr
)p
);
352 runtime_printstring(String v
)
354 // if(v.len > runtime_maxstring) {
355 // gwrite("[string too long]", 17);
359 gwrite(v
.str
, v
.len
);
363 __go_print_space(void)