From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: From: Serge Petrenko Subject: [PATCH] xrow: print corrupted rows on decoding error. Date: Fri, 15 Mar 2019 19:02:38 +0300 Message-Id: <20190315160238.37882-1-sergepetrenko@tarantool.org> To: vdavydov.dev@gmail.com Cc: tarantool-patches@freelists.org, Serge Petrenko List-ID: 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)