[PATCH v4 11/37] unwind: report expected backtracing error

Masatake YAMATO yamato at redhat.com
Wed Apr 16 06:33:09 UTC 2014


When a file mmap'ed to the target process is unlink'ed, backtracing
the stack is failed. Current implementation reports it as
"backtracing_error". To reduce bug reports, this patch
changes the message to "expected_backtracing_error".

Here is the reproducer.

    $ cat ./p-deleted.c
    #include <unistd.h>

    int
    main(int argc, char **argv)
    {
      if (! ((argv[0][0] == '.') && (argv[0][1] == '/')))
	return 1;

      if (unlink(argv[0]) < 0)
	return 1;
      return 0;
    }

    $ LD_LIBRARY_PATH=/usr/local/lib ../strace -e unlink -k ./p-deleted
    LD_LIBRARY_PATH=/usr/local/lib ../strace -e unlink -k ./p-deleted
    unlink("./p-deleted")                   = 0
     > /usr/lib64/libc-2.18.so(unlink+0x7) [0xe7f17]
     > /home/yamato/var/strace/t_unwind/p-deleted (deleted)(+0x0) [0x575]
     > /usr/lib64/libc-2.18.so(__libc_start_main+0xf5) [0x21d65]
     > backtracing_error [0x7ffff1365590]
    +++ exited with 0 +++

p-deleted is deleted therefore backtracing_error is reported.  This
patch records the deleted marker when making mmap cache and refers the
recorded information in the case "backtracing_error" to switch the
message.

Here is the output of this patch:

    $ LD_LIBRARY_PATH=/usr/local/lib ../strace -e unlink -k ./p-deleted
    LD_LIBRARY_PATH=/usr/local/lib ../strace -e unlink -k ./p-deleted
    unlink("./p-deleted")                   = 0
     > /usr/lib64/libc-2.18.so(unlink+0x7) [0xe7f17]
     > /home/yamato/var/strace/t_unwind/p-deleted (deleted)(+0x0) [0x575]
     > /usr/lib64/libc-2.18.so(__libc_start_main+0xf5) [0x21d65]
     > expected_backtracing_error [0x7ffff1365590]
    +++ exited with 0 +++

Restriction:

    This is not the perfect solution. If a file is unlink'ed after making
    the mmap cache and before unwinding, strace cannot have a chance to record
    the deleted marker.

In this version of patch, hardcode magic number used in comparing "(delete)"
string is replaced with strlen. Suggested by Dmitry V. Levin <ldv at altlinux.org>.

In old version of patch, I throw away the deleted entry from mmap
cache to avoid to report "backtracing_error". In this patch I keep it;
and just switch the error message. Inspired by the review comment
from Dmitry V. Levin <ldv at altlinux.org>.

Signed-off-by: Masatake YAMATO <yamato at redhat.com>
---
 unwind.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/unwind.c b/unwind.c
index 42c885e..0e90a92 100644
--- a/unwind.c
+++ b/unwind.c
@@ -48,6 +48,7 @@ struct mmap_cache_t {
 	unsigned long end_addr;
 	unsigned long mmap_offset;
 	char* binary_filename;
+	bool deleted;
 };
 
 /*
@@ -134,6 +135,10 @@ build_mmap_cache(struct tcb* tcp)
 	struct mmap_cache_t *cache_head;
 	FILE *fp;
 
+	const char *deleted = " (deleted)";
+	size_t blen;
+	size_t dlen;
+
 	sprintf(filename, "/proc/%d/maps", tcp->pid);
 	fp = fopen(filename, "r");
 	if (!fp) {
@@ -170,6 +175,13 @@ build_mmap_cache(struct tcb* tcp)
 		cur_entry->mmap_offset = mmap_offset;
 		cur_entry->binary_filename = strdup(binary_path);
 
+		dlen = strlen(deleted);
+		blen = strlen(binary_path);
+		if (blen >= dlen && strcmp(binary_path + blen - dlen, deleted) == 0)
+			cur_entry->deleted = true;
+		else
+			cur_entry->deleted = false;
+
 		/*
 		 * sanity check to make sure that we're storing
 		 * non-overlapping regions in ascending order
@@ -271,6 +283,7 @@ stacktrace_walk(struct tcb *tcp,
 	char * symbol_name;
 	struct mmap_cache_t* cur_mmap_cache;
 	unsigned long true_offset;
+	bool berror_expected = false;
 
 	if (!tcp->mmap_cache)
 		error_msg_and_die("bug: mmap_cache is NULL");
@@ -313,6 +326,9 @@ stacktrace_walk(struct tcb *tcp,
 						die_out_of_memory();
 				}
 
+				if (cur_mmap_cache->deleted)
+					berror_expected = true;
+
 				true_offset = ip - cur_mmap_cache->start_addr +
 					cur_mmap_cache->mmap_offset;
 				if (symbol_name[0]) {
@@ -349,7 +365,10 @@ stacktrace_walk(struct tcb *tcp,
 		}
 		if (lower > upper) {
 			error_action(data,
-				     "backtracing_error", ip);
+				     berror_expected
+				     ?"expected_backtracing_error"
+				     :"unexpected_backtracing_error",
+				     ip);
 			goto ret;
 		}
 
-- 
1.9.0





More information about the Strace-devel mailing list