From f0e1119996b549dcb5e3013f805cd2cd066ed2c9 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 19 Aug 2016 11:32:28 -0700 Subject: [PATCH 1/3] Fix refcounting bugs --- src/core/ext/transport/chttp2/transport/frame_data.c | 1 + src/core/ext/transport/chttp2/transport/parsing.c | 2 +- src/core/lib/iomgr/error.h | 2 +- src/core/lib/transport/transport.h | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/frame_data.c b/src/core/ext/transport/chttp2/transport/frame_data.c index 18e55b29160..388a5aba2bd 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.c +++ b/src/core/ext/transport/chttp2/transport/frame_data.c @@ -56,6 +56,7 @@ void grpc_chttp2_data_parser_destroy(grpc_exec_ctx *exec_ctx, exec_ctx, parser->parsing_frame, GRPC_ERROR_CREATE("Parser destroyed"), 1); } + GRPC_ERROR_UNREF(parser->error); } grpc_error *grpc_chttp2_data_parser_begin_frame(grpc_chttp2_data_parser *parser, diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c index ee01d3beb7f..4d9e25d9853 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.c +++ b/src/core/ext/transport/chttp2/transport/parsing.c @@ -444,7 +444,7 @@ static grpc_error *init_data_frame_parser( } else if (grpc_error_get_int(err, GRPC_ERROR_INT_STREAM_ID, NULL)) { /* handle stream errors by closing the stream */ grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, - true, false, GRPC_ERROR_REF(err)); + true, false, err); gpr_slice_buffer_add( &transport_global->qbuf, grpc_chttp2_rst_stream_create(transport_global->incoming_stream_id, diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h index bc7781250e8..e02b12f2f4c 100644 --- a/src/core/lib/iomgr/error.h +++ b/src/core/lib/iomgr/error.h @@ -148,7 +148,7 @@ grpc_error *grpc_error_create(const char *file, int line, const char *desc, #define GRPC_ERROR_CREATE_REFERENCING(desc, errs, count) \ grpc_error_create(__FILE__, __LINE__, desc, errs, count) -//#define GRPC_ERROR_REFCOUNT_DEBUG +#define GRPC_ERROR_REFCOUNT_DEBUG #ifdef GRPC_ERROR_REFCOUNT_DEBUG grpc_error *grpc_error_ref(grpc_error *err, const char *file, int line, const char *func); diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index 392a7ca422e..d0d0c2a461d 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -55,7 +55,7 @@ typedef struct grpc_transport grpc_transport; for a stream. */ typedef struct grpc_stream grpc_stream; -#define GRPC_STREAM_REFCOUNT_DEBUG +//#define GRPC_STREAM_REFCOUNT_DEBUG typedef struct grpc_stream_refcount { gpr_refcount refs; From 4e41e360d31e71b933e0f8fadfc8995d3d01f8db Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 19 Aug 2016 13:12:54 -0700 Subject: [PATCH 2/3] Add tracer for pending tags --- src/core/lib/iomgr/error.h | 2 +- src/core/lib/surface/completion_queue.c | 31 +++++++++++++++++++++++++ src/core/lib/surface/completion_queue.h | 3 +++ src/core/lib/surface/init.c | 3 +++ 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h index e02b12f2f4c..bc7781250e8 100644 --- a/src/core/lib/iomgr/error.h +++ b/src/core/lib/iomgr/error.h @@ -148,7 +148,7 @@ grpc_error *grpc_error_create(const char *file, int line, const char *desc, #define GRPC_ERROR_CREATE_REFERENCING(desc, errs, count) \ grpc_error_create(__FILE__, __LINE__, desc, errs, count) -#define GRPC_ERROR_REFCOUNT_DEBUG +//#define GRPC_ERROR_REFCOUNT_DEBUG #ifdef GRPC_ERROR_REFCOUNT_DEBUG grpc_error *grpc_error_ref(grpc_error *err, const char *file, int line, const char *func); diff --git a/src/core/lib/surface/completion_queue.c b/src/core/lib/surface/completion_queue.c index 2412f78a064..5654b86d8b3 100644 --- a/src/core/lib/surface/completion_queue.c +++ b/src/core/lib/surface/completion_queue.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include "src/core/lib/iomgr/pollset.h" @@ -50,6 +51,9 @@ #include "src/core/lib/surface/event_string.h" int grpc_trace_operation_failures; +#ifndef NDEBUG +int grpc_trace_pending_tags; +#endif typedef struct { grpc_pollset_worker **worker; @@ -338,6 +342,25 @@ static bool cq_is_next_finished(grpc_exec_ctx *exec_ctx, void *arg) { return gpr_time_cmp(a->deadline, gpr_now(a->deadline.clock_type)) < 0; } +#ifndef NDEBUG +static void dump_pending_tags(grpc_completion_queue *cc) { + if (!grpc_trace_pending_tags) return; + + gpr_strvec v; + gpr_strvec_init(&v); + gpr_strvec_add(&v, gpr_strdup("PENDING TAGS:")); + for (size_t i = 0; i < cc->outstanding_tag_count; i++) { + char *s; + gpr_asprintf(&s, " %p", cc->outstanding_tags[i]); + gpr_strvec_add(&v, s); + } + char *out = gpr_strvec_flatten(&v, NULL); + gpr_strvec_destroy(&v); + gpr_log(GPR_DEBUG, "%s", out); + gpr_free(out); +} +#endif + grpc_event grpc_completion_queue_next(grpc_completion_queue *cc, gpr_timespec deadline, void *reserved) { grpc_event ret; @@ -357,6 +380,10 @@ grpc_event grpc_completion_queue_next(grpc_completion_queue *cc, reserved)); GPR_ASSERT(!reserved); +#ifndef NDEBUG + dump_pending_tags(cc); +#endif + deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC); cq_is_finished_arg is_finished_arg = {cc, deadline, NULL, NULL}; @@ -510,6 +537,10 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag, } GPR_ASSERT(!reserved); +#ifndef NDEBUG + dump_pending_tags(cc); +#endif + deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC); cq_is_finished_arg is_finished_arg = {cc, deadline, NULL, tag}; diff --git a/src/core/lib/surface/completion_queue.h b/src/core/lib/surface/completion_queue.h index 3049284f686..e9d840df777 100644 --- a/src/core/lib/surface/completion_queue.h +++ b/src/core/lib/surface/completion_queue.h @@ -44,6 +44,9 @@ extern int grpc_cq_pluck_trace; extern int grpc_cq_event_timeout_trace; extern int grpc_trace_operation_failures; +#ifndef NDEBUG +extern int grpc_trace_pending_tags; +#endif typedef struct grpc_cq_completion { /** user supplied tag */ diff --git a/src/core/lib/surface/init.c b/src/core/lib/surface/init.c index edda0c85fa9..ac111253efd 100644 --- a/src/core/lib/surface/init.c +++ b/src/core/lib/surface/init.c @@ -173,6 +173,9 @@ void grpc_init(void) { // Default timeout trace to 1 grpc_cq_event_timeout_trace = 1; grpc_register_tracer("op_failure", &grpc_trace_operation_failures); +#ifndef NDEBUG + grpc_register_tracer("pending_tags", &grpc_trace_pending_tags); +#endif grpc_security_pre_init(); grpc_iomgr_init(); grpc_executor_init(); From 49c644ca6a382e69f7c85b486601784aff94b81e Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 19 Aug 2016 13:52:23 -0700 Subject: [PATCH 3/3] Fix bugs, make it easier to find them --- .../ext/transport/chttp2/transport/chttp2_transport.c | 2 +- src/core/lib/surface/completion_queue.c | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 2ca76b51538..161f26b39fe 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1587,7 +1587,7 @@ void grpc_chttp2_mark_stream_closed( stream_global->read_closed_error = GRPC_ERROR_REF(error); stream_global->read_closed = true; stream_global->published_metadata[0] = true; - stream_global->published_metadata[0] = true; + stream_global->published_metadata[1] = true; decrement_active_streams_locked(exec_ctx, transport_global, stream_global); } if (close_writes && !stream_global->write_closed) { diff --git a/src/core/lib/surface/completion_queue.c b/src/core/lib/surface/completion_queue.c index 5654b86d8b3..28450d966c2 100644 --- a/src/core/lib/surface/completion_queue.c +++ b/src/core/lib/surface/completion_queue.c @@ -359,6 +359,8 @@ static void dump_pending_tags(grpc_completion_queue *cc) { gpr_log(GPR_DEBUG, "%s", out); gpr_free(out); } +#else +static void dump_pending_tags(grpc_completion_queue *cc) {} #endif grpc_event grpc_completion_queue_next(grpc_completion_queue *cc, @@ -380,9 +382,7 @@ grpc_event grpc_completion_queue_next(grpc_completion_queue *cc, reserved)); GPR_ASSERT(!reserved); -#ifndef NDEBUG dump_pending_tags(cc); -#endif deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC); @@ -427,6 +427,7 @@ grpc_event grpc_completion_queue_next(grpc_completion_queue *cc, gpr_mu_unlock(cc->mu); memset(&ret, 0, sizeof(ret)); ret.type = GRPC_QUEUE_TIMEOUT; + dump_pending_tags(cc); break; } first_loop = 0; @@ -452,6 +453,7 @@ grpc_event grpc_completion_queue_next(grpc_completion_queue *cc, GRPC_ERROR_UNREF(err); memset(&ret, 0, sizeof(ret)); ret.type = GRPC_QUEUE_TIMEOUT; + dump_pending_tags(cc); break; } } @@ -537,9 +539,7 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag, } GPR_ASSERT(!reserved); -#ifndef NDEBUG dump_pending_tags(cc); -#endif deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC); @@ -592,6 +592,7 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag, memset(&ret, 0, sizeof(ret)); /* TODO(ctiller): should we use a different result here */ ret.type = GRPC_QUEUE_TIMEOUT; + dump_pending_tags(cc); break; } now = gpr_now(GPR_CLOCK_MONOTONIC); @@ -600,6 +601,7 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag, gpr_mu_unlock(cc->mu); memset(&ret, 0, sizeof(ret)); ret.type = GRPC_QUEUE_TIMEOUT; + dump_pending_tags(cc); break; } first_loop = 0; @@ -625,6 +627,7 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag, GRPC_ERROR_UNREF(err); memset(&ret, 0, sizeof(ret)); ret.type = GRPC_QUEUE_TIMEOUT; + dump_pending_tags(cc); break; } }