[PATCH] xrow: print corrupted rows on decoding error.

Serge Petrenko sergepetrenko at tarantool.org
Fri Mar 15 19:02:38 MSK 2019


Add row hex printing to log on verbose level. This would be useful
during investigation of errors related to invalid msgpack packet
arrival.

Related to #4040
---
https://github.com/tarantool/tarantool/tree/sp/xrow-decode-verbose-err


 src/box/xrow.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/src/box/xrow.c b/src/box/xrow.c
index bddae1d5b..8a5254902 100644
--- a/src/box/xrow.c
+++ b/src/box/xrow.c
@@ -88,14 +88,29 @@ mp_decode_vclock(const char **data, struct vclock *vclock)
 	return 0;
 }
 
+static inline void
+say_dump_row_hex(const char *start, const char *end)
+{
+	char *buf = (char *)malloc(3 * (end - start) + 1);
+	char *pos = buf;
+	for (const char *cur = start; cur < end; ++cur) {
+		pos += sprintf(pos, "%02hhX ", *cur);
+	}
+	*pos = 0;
+	say_verbose("Corrupted row is: %s", buf);
+	free(buf);
+}
+
 int
 xrow_header_decode(struct xrow_header *header, const char **pos,
 		   const char *end, bool end_is_exact)
 {
 	memset(header, 0, sizeof(struct xrow_header));
 	const char *tmp = *pos;
+	const char * const start = *pos;
 	if (mp_check(&tmp, end) != 0) {
 error:
+		say_dump_row_hex(start, end);
 		diag_set(ClientError, ER_INVALID_MSGPACK, "packet header");
 		return -1;
 	}
@@ -163,6 +178,7 @@ error:
 	if (*pos < end && header->type != IPROTO_NOP) {
 		const char *body = *pos;
 		if (mp_check(pos, end)) {
+			say_dump_row_hex(start, end);
 			diag_set(ClientError, ER_INVALID_MSGPACK, "packet body");
 			return -1;
 		}
@@ -171,6 +187,7 @@ error:
 		header->body[0].iov_len = *pos - body;
 	}
 	if (end_is_exact && *pos < end) {
+		say_dump_row_hex(start,end);
 		diag_set(ClientError, ER_INVALID_MSGPACK, "packet body");
 		return -1;
 	}
@@ -532,6 +549,7 @@ xrow_decode_sql(const struct xrow_header *row, struct sql_request *request)
 
 	if (mp_typeof(*data) != MP_MAP || mp_check_map(data, end) > 0) {
 error:
+		say_dump_row_hex(row->body[0].iov_base, end);
 		diag_set(ClientError, ER_INVALID_MSGPACK, "packet body");
 		return -1;
 	}
@@ -603,6 +621,7 @@ xrow_decode_dml(struct xrow_header *row, struct request *request,
 
 	if (mp_typeof(*data) != MP_MAP || mp_check_map(data, end) > 0) {
 error:
+		say_dump_row_hex(row->body[0].iov_base, end);
 		diag_set(ClientError, ER_INVALID_MSGPACK, "packet body");
 		return -1;
 	}
@@ -662,11 +681,13 @@ error:
 		}
 	}
 	if (data != end) {
+		say_dump_row_hex(row->body[0].iov_base, end);
 		diag_set(ClientError, ER_INVALID_MSGPACK, "packet end");
 		return -1;
 	}
 done:
 	if (key_map) {
+		say_dump_row_hex(row->body[0].iov_base, end);
 		enum iproto_key key = (enum iproto_key) bit_ctz_u64(key_map);
 		diag_set(ClientError, ER_MISSING_REQUEST_FIELD,
 			 iproto_key_name(key));
@@ -809,6 +830,7 @@ xrow_decode_call(const struct xrow_header *row, struct call_request *request)
 
 	if (mp_typeof(*data) != MP_MAP || mp_check_map(data, end) > 0) {
 error:
+		say_dump_row_hex(row->body[0].iov_base, end);
 		diag_set(ClientError, ER_INVALID_MSGPACK, "packet body");
 		return -1;
 	}
@@ -848,6 +870,7 @@ error:
 		}
 	}
 	if (data != end) {
+		say_dump_row_hex(row->body[0].iov_base, end);
 		diag_set(ClientError, ER_INVALID_MSGPACK, "packet end");
 		return -1;
 	}
@@ -888,6 +911,7 @@ xrow_decode_auth(const struct xrow_header *row, struct auth_request *request)
 
 	if (mp_typeof(*data) != MP_MAP || mp_check_map(data, end) > 0) {
 error:
+		say_dump_row_hex(row->body[0].iov_base, end);
 		diag_set(ClientError, ER_INVALID_MSGPACK, "packet body");
 		return -1;
 	}
@@ -920,6 +944,7 @@ error:
 		}
 	}
 	if (data != end) {
+		say_dump_row_hex(row->body[0].iov_base, end);
 		diag_set(ClientError, ER_INVALID_MSGPACK, "packet end");
 		return -1;
 	}
@@ -1080,6 +1105,7 @@ xrow_decode_ballot(struct xrow_header *row, struct ballot *ballot)
 	}
 	return 0;
 err:
+	say_dump_row_hex(row->body[0].iov_base, end);
 	diag_set(ClientError, ER_INVALID_MSGPACK, "packet body");
 	return -1;
 }
@@ -1129,6 +1155,7 @@ xrow_decode_subscribe(struct xrow_header *row, struct tt_uuid *replicaset_uuid,
 	const char *end = data + row->body[0].iov_len;
 	const char *d = data;
 	if (mp_check(&d, end) != 0 || mp_typeof(*data) != MP_MAP) {
+		say_dump_row_hex(row->body[0].iov_base, end);
 		diag_set(ClientError, ER_INVALID_MSGPACK, "request body");
 		return -1;
 	}
-- 
2.17.2 (Apple Git-113)




More information about the Tarantool-patches mailing list