The following cut-down version of printf() avoids using stdio or ostreams. This is to guarantee no recursive calls into the allocator and to bound the stack space consumed. (The pthread manager thread in linuxthreads has a very small stack, so fprintf can't be called.)
| 852 | // manager thread in linuxthreads has a very small stack, |
| 853 | // so fprintf can't be called.) |
| 854 | static void TracePrintf(int fd, const char *fmt, ...) { |
| 855 | char buf[64]; |
| 856 | int i = 0; |
| 857 | va_list ap; |
| 858 | va_start(ap, fmt); |
| 859 | const char *p = fmt; |
| 860 | char numbuf[25]; |
| 861 | numbuf[sizeof(numbuf)-1] = 0; |
| 862 | while (*p != '\0') { // until end of format string |
| 863 | char *s = &numbuf[sizeof(numbuf)-1]; |
| 864 | if (p[0] == '%' && p[1] != 0) { // handle % formats |
| 865 | int64 l = 0; |
| 866 | unsigned long base = 0; |
| 867 | if (*++p == 's') { // %s |
| 868 | s = va_arg(ap, char *); |
| 869 | } else if (*p == 'l' && p[1] == 'd') { // %ld |
| 870 | l = va_arg(ap, long); |
| 871 | base = 10; |
| 872 | p++; |
| 873 | } else if (*p == 'l' && p[1] == 'u') { // %lu |
| 874 | l = va_arg(ap, unsigned long); |
| 875 | base = 10; |
| 876 | p++; |
| 877 | } else if (*p == 'z' && p[1] == 'u') { // %zu |
| 878 | l = va_arg(ap, size_t); |
| 879 | base = 10; |
| 880 | p++; |
| 881 | } else if (*p == 'u') { // %u |
| 882 | l = va_arg(ap, unsigned int); |
| 883 | base = 10; |
| 884 | } else if (*p == 'd') { // %d |
| 885 | l = va_arg(ap, int); |
| 886 | base = 10; |
| 887 | } else if (*p == 'p') { // %p |
| 888 | l = va_arg(ap, intptr_t); |
| 889 | base = 16; |
| 890 | } else { |
| 891 | write(STDERR_FILENO, "Unimplemented TracePrintf format\n", 33); |
| 892 | write(STDERR_FILENO, p, 2); |
| 893 | write(STDERR_FILENO, "\n", 1); |
| 894 | abort(); |
| 895 | } |
| 896 | p++; |
| 897 | if (base != 0) { |
| 898 | bool minus = (l < 0 && base == 10); |
| 899 | uint64 ul = minus? -l : l; |
| 900 | do { |
| 901 | *--s = "0123456789abcdef"[ul % base]; |
| 902 | ul /= base; |
| 903 | } while (ul != 0); |
| 904 | if (base == 16) { |
| 905 | *--s = 'x'; |
| 906 | *--s = '0'; |
| 907 | } else if (minus) { |
| 908 | *--s = '-'; |
| 909 | } |
| 910 | } |
| 911 | } else { // handle normal characters |
no test coverage detected