From: Julian Seward Date: Wed, 10 Jan 2007 15:43:36 +0000 (+0000) Subject: Merge r6502 (Generate valid XML even for very long fn names) X-Git-Tag: svn/VALGRIND_3_2_2~17 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e1d12385c6684fb6dadf0eb9ed2ef2b0fe63f691;p=thirdparty%2Fvalgrind.git Merge r6502 (Generate valid XML even for very long fn names) git-svn-id: svn://svn.valgrind.org/valgrind/branches/VALGRIND_3_2_BRANCH@6503 --- diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c index aa60e8f953..feff0967ee 100644 --- a/coregrind/m_debuginfo/debuginfo.c +++ b/coregrind/m_debuginfo/debuginfo.c @@ -589,38 +589,73 @@ Bool VG_(get_filename_linenum) ( Addr a, } -/* Print into buf info on code address, function name and filename */ +/* VG_(describe_IP): print into buf info on code address, function + name and filename. */ + +/* Copy str into buf starting at n, but not going past buf[n_buf-1] + and always ensuring that buf is zero-terminated. */ static Int putStr ( Int n, Int n_buf, Char* buf, Char* str ) { + vg_assert(n_buf > 0); + vg_assert(n >= 0 && n < n_buf); for (; n < n_buf-1 && *str != 0; n++,str++) buf[n] = *str; + vg_assert(n >= 0 && n < n_buf); buf[n] = '\0'; return n; } -static Int putStrEsc ( Int n, Int n_buf, Char* buf, Char* str ) + +/* Same as putStr, but escaping chars for XML output, and + also not adding more than count chars to n_buf. */ + +static Int putStrEsc ( Int n, Int n_buf, Int count, Char* buf, Char* str ) { Char alt[2]; + vg_assert(n_buf > 0); + vg_assert(count >= 0 && count < n_buf); + vg_assert(n >= 0 && n < n_buf); for (; *str != 0; str++) { + vg_assert(count >= 0); + if (count <= 0) + goto done; switch (*str) { - case '&': n = putStr( n, n_buf, buf, "&"); break; - case '<': n = putStr( n, n_buf, buf, "<"); break; - case '>': n = putStr( n, n_buf, buf, ">"); break; - default: alt[0] = *str; - alt[1] = 0; - n = putStr( n, n_buf, buf, alt ); - break; + case '&': + if (count < 5) goto done; + n = putStr( n, n_buf, buf, "&"); + count -= 5; + break; + case '<': + if (count < 4) goto done; + n = putStr( n, n_buf, buf, "<"); + count -= 4; + break; + case '>': + if (count < 4) goto done; + n = putStr( n, n_buf, buf, ">"); + count -= 4; + break; + default: + if (count < 1) goto done; + alt[0] = *str; + alt[1] = 0; + n = putStr( n, n_buf, buf, alt ); + count -= 1; + break; } } + done: + vg_assert(count >= 0); /* should not go -ve in loop */ + vg_assert(n >= 0 && n < n_buf); return n; } Char* VG_(describe_IP)(Addr eip, Char* buf, Int n_buf) { # define APPEND(_str) \ - n = putStr(n, n_buf, buf, _str); -# define APPEND_ESC(_str) \ - n = putStrEsc(n, n_buf, buf, _str); + n = putStr(n, n_buf, buf, _str) +# define APPEND_ESC(_count,_str) \ + n = putStrEsc(n, n_buf, (_count), buf, (_str)) # define BUF_LEN 4096 UInt lineno; @@ -645,7 +680,12 @@ Char* VG_(describe_IP)(Addr eip, Char* buf, Int n_buf) HChar* maybe_newline = human_readable ? "\n " : ""; HChar* maybe_newline2 = human_readable ? "\n " : ""; - /* Print in XML format, dumping in as much info as we know. */ + /* Print in XML format, dumping in as much info as we know. + Ensure all tags are balanced even if the individual strings + are too long. Allocate 1/10 of BUF_LEN to the object name, + 6/10s to the function name, 1/10 to the directory name and + 1/10 to the file name, leaving 1/10 for all the fixed-length + stuff. */ APPEND(""); VG_(sprintf)(ibuf,"0x%llx", (ULong)eip); APPEND(maybe_newline); @@ -653,25 +693,25 @@ Char* VG_(describe_IP)(Addr eip, Char* buf, Int n_buf) if (know_objname) { APPEND(maybe_newline); APPEND(""); - APPEND_ESC(buf_obj); + APPEND_ESC(1*BUF_LEN/10, buf_obj); APPEND(""); } if (know_fnname) { APPEND(maybe_newline); APPEND(""); - APPEND_ESC(buf_fn); + APPEND_ESC(6*BUF_LEN/10, buf_fn); APPEND(""); } if (know_srcloc) { if (know_dirinfo) { APPEND(maybe_newline); APPEND(""); - APPEND(buf_dirname); + APPEND_ESC(1*BUF_LEN/10, buf_dirname); APPEND(""); } APPEND(maybe_newline); APPEND(""); - APPEND_ESC(buf_srcloc); + APPEND_ESC(1*BUF_LEN/10, buf_srcloc); APPEND(""); APPEND(maybe_newline); APPEND("");