3434#include <execinfo.h>
3535#endif
3636
37- #ifdef __linux__
38- #define PTR_SANE (p ) ((p) && (char*)(p) >= heap_start && (char*)(p) <= heap_end)
39- static char * heap_start ;
40- char * __bss_start ;
41- #else
42- #define PTR_SANE (p ) (p)
43- #endif /* __linux */
44-
45-
46- void my_init_stacktrace ()
47- {
48- #ifdef __linux__
49- heap_start = (char * ) & __bss_start ;
50- #endif /* __linux */
51- }
52-
53- #ifdef __linux__
54-
55- static void print_buffer (char * buffer , size_t count )
56- {
57- const char s []= " " ;
58- for (; count && * buffer ; -- count )
59- {
60- my_write_stderr (isprint (* buffer ) ? buffer : s , 1 );
61- ++ buffer ;
62- }
63- }
64-
65- /**
66- Access the pages of this process through /proc/self/task/<tid>/mem
67- in order to safely print the contents of a memory address range.
68-
69- @param addr The address at the start of the memory region.
70- @param max_len The length of the memory region.
71-
72- @return Zero on success.
73- */
74- static int safe_print_str (const char * addr , int max_len )
75- {
76- int fd ;
77- pid_t tid ;
78- off_t offset ;
79- ssize_t nbytes = 0 ;
80- size_t total , count ;
81- char buf [256 ];
82-
83- tid = (pid_t ) syscall (SYS_gettid );
84-
85- sprintf (buf , "/proc/self/task/%d/mem" , tid );
86-
87- if ((fd = open (buf , O_RDONLY )) < 0 )
88- return -1 ;
89-
90- /* Ensure that off_t can hold a pointer. */
91- compile_time_assert (sizeof (off_t ) >= sizeof (intptr ));
92-
93- total = max_len ;
94- offset = (intptr ) addr ;
95-
96- /* Read up to the maximum number of bytes. */
97- while (total )
98- {
99- count = MY_MIN (sizeof (buf ), total );
100-
101- if ((nbytes = pread (fd , buf , count , offset )) < 0 )
102- {
103- /* Just in case... */
104- if (errno == EINTR )
105- continue ;
106- else
107- break ;
108- }
109-
110- /* Advance offset into memory. */
111- total -= nbytes ;
112- offset += nbytes ;
113- addr += nbytes ;
114-
115- /* Output the printable characters. */
116- print_buffer (buf , nbytes );
117-
118- /* Break if less than requested... */
119- if ((count - nbytes ))
120- break ;
121- }
122-
123- if (nbytes == -1 )
124- my_safe_printf_stderr ("Can't read from address %p" , addr );
125-
126- close (fd );
127-
128- return 0 ;
129- }
130-
131- #endif
132-
13337/*
13438 Attempt to print a char * pointer as a string.
13539
13640 SYNOPSIS
137- Prints either until the end of string ('\0'), or max_len characters have
138- been printed.
41+ Prints until max_len characters have been printed.
13942
14043 RETURN VALUE
14144 0 Pointer was within the heap address space.
@@ -150,24 +53,25 @@ static int safe_print_str(const char *addr, int max_len)
15053
15154int my_safe_print_str (const char * val , int max_len )
15255{
153- #ifdef __linux__
154- char * heap_end ;
155-
156- // Try and make use of /proc filesystem to safely print memory contents.
157- if (!safe_print_str (val , max_len ))
158- return 0 ;
159-
160- heap_end = (char * ) sbrk (0 );
161- #endif
162-
163- if (!PTR_SANE (val ))
56+ const char * orig_val = val ;
57+ if (!val )
16458 {
165- my_safe_printf_stderr ("%s" , "is an invalid pointer " );
59+ my_safe_printf_stderr ("%s" , "(null) " );
16660 return 1 ;
16761 }
16862
169- for (; max_len && PTR_SANE (val ) && * val ; -- max_len )
170- my_write_stderr ((val ++ ), 1 );
63+ for (; max_len ; -- max_len )
64+ {
65+ if (my_write_stderr ((val ++ ), 1 ) != 1 )
66+ {
67+ if ((errno == EFAULT ) && (val == orig_val + 1 ))
68+ {
69+ // We can not read the address from very beginning
70+ my_safe_printf_stderr ("Can't access address %p" , orig_val );
71+ }
72+ break ;
73+ }
74+ }
17175 my_safe_printf_stderr ("%s" , "\n" );
17276
17377 return 0 ;
@@ -507,11 +411,6 @@ static EXCEPTION_POINTERS *exception_ptrs;
507411#define MODULE64_SIZE_WINXP 576
508412#define STACKWALK_MAX_FRAMES 64
509413
510- void my_init_stacktrace ()
511- {
512- }
513-
514-
515414void my_set_exception_pointers (EXCEPTION_POINTERS * ep )
516415{
517416 exception_ptrs = ep ;
0 commit comments