Proposed changes on top of v29. -- Álvaro Herrera Valdivia, Chile
>From b32ae3805bb28553c0a1cf308c6ed27f58576f3c Mon Sep 17 00:00:00 2001 From: Alvaro Herrera <alvhe...@alvh.no-ip.org> Date: Fri, 26 Mar 2021 19:12:12 -0300 Subject: [PATCH 1/5] libpq_pipeline: add -t support for PQtrace
--- .../modules/libpq_pipeline/libpq_pipeline.c | 84 +++++++++++++------ 1 file changed, 59 insertions(+), 25 deletions(-) diff --git a/src/test/modules/libpq_pipeline/libpq_pipeline.c b/src/test/modules/libpq_pipeline/libpq_pipeline.c index 846ee9f5ab..34d085035b 100644 --- a/src/test/modules/libpq_pipeline/libpq_pipeline.c +++ b/src/test/modules/libpq_pipeline/libpq_pipeline.c @@ -23,6 +23,7 @@ #include "catalog/pg_type_d.h" #include "common/fe_memutils.h" #include "libpq-fe.h" +#include "pg_getopt.h" #include "portability/instr_time.h" @@ -30,6 +31,9 @@ static void exit_nicely(PGconn *conn); const char *const progname = "libpq_pipeline"; +/* Options and defaults */ +char *tracefile = NULL; /* path to PQtrace() file */ + #define DEBUG #ifdef DEBUG @@ -1209,8 +1213,10 @@ usage(const char *progname) { fprintf(stderr, "%s tests libpq's pipeline mode.\n\n", progname); fprintf(stderr, "Usage:\n"); - fprintf(stderr, " %s tests", progname); - fprintf(stderr, " %s testname [conninfo [number_of_rows]]\n", progname); + fprintf(stderr, " %s [OPTION] tests\n", progname); + fprintf(stderr, " %s [OPTION] TESTNAME [CONNINFO [NUMBER_OF_ROWS]\n", progname); + fprintf(stderr, "\nOptions:\n"); + fprintf(stderr, " -t TRACEFILE generate a libpq trace to TRACEFILE\n"); } static void @@ -1231,37 +1237,54 @@ main(int argc, char **argv) { const char *conninfo = ""; PGconn *conn; + FILE *trace; + char *testname; int numrows = 10000; PGresult *res; + int c; - if (strcmp(argv[1], "tests") == 0) + while ((c = getopt(argc, argv, "t:")) != -1) { - print_test_list(); - exit(0); + switch (c) + { + case 't': /* trace file */ + tracefile = pg_strdup(optarg); + break; + } } - /* - * The testname parameter is mandatory; it can be followed by a conninfo - * string and number of rows. - */ - if (argc < 2 || argc > 4) + if (optind < argc) + { + testname = argv[optind]; + optind++; + } + else { usage(argv[0]); exit(1); } - if (argc >= 3) - conninfo = pg_strdup(argv[2]); + if (strcmp(testname, "tests") == 0) + { + print_test_list(); + exit(0); + } - if (argc >= 4) + if (optind < argc) + { + conninfo = argv[optind]; + optind++; + } + if (optind < argc) { errno = 0; - numrows = strtol(argv[3], NULL, 10); + numrows = strtol(argv[optind], NULL, 10); if (errno != 0 || numrows <= 0) { - fprintf(stderr, "couldn't parse \"%s\" as a positive integer\n", argv[3]); + fprintf(stderr, "couldn't parse \"%s\" as a positive integer\n", argv[optind]); exit(1); } + optind++; } /* Make a connection to the database */ @@ -1272,30 +1295,41 @@ main(int argc, char **argv) PQerrorMessage(conn)); exit_nicely(conn); } + + /* Set the trace file, if requested */ + if (tracefile != NULL) + { + trace = fopen(tracefile, "w+"); + + if (trace == NULL) + pg_fatal("could not open file \"%s\": %m", tracefile); + PQtrace(conn, trace); + PQtraceSetFlags(conn, PQTRACE_SUPPRESS_TIMESTAMPS); + } + res = PQexec(conn, "SET lc_messages TO \"C\""); if (PQresultStatus(res) != PGRES_COMMAND_OK) pg_fatal("failed to set lc_messages: %s", PQerrorMessage(conn)); - if (strcmp(argv[1], "disallowed_in_pipeline") == 0) + if (strcmp(testname, "disallowed_in_pipeline") == 0) test_disallowed_in_pipeline(conn); - else if (strcmp(argv[1], "multi_pipelines") == 0) + else if (strcmp(testname, "multi_pipelines") == 0) test_multi_pipelines(conn); - else if (strcmp(argv[1], "pipeline_abort") == 0) + else if (strcmp(testname, "pipeline_abort") == 0) test_pipeline_abort(conn); - else if (strcmp(argv[1], "pipelined_insert") == 0) + else if (strcmp(testname, "pipelined_insert") == 0) test_pipelined_insert(conn, numrows); - else if (strcmp(argv[1], "prepared") == 0) + else if (strcmp(testname, "prepared") == 0) test_prepared(conn); - else if (strcmp(argv[1], "simple_pipeline") == 0) + else if (strcmp(testname, "simple_pipeline") == 0) test_simple_pipeline(conn); - else if (strcmp(argv[1], "singlerow") == 0) + else if (strcmp(testname, "singlerow") == 0) test_singlerowmode(conn); - else if (strcmp(argv[1], "transaction") == 0) + else if (strcmp(testname, "transaction") == 0) test_transaction(conn); else { - fprintf(stderr, "\"%s\" is not a recognized test name\n", argv[1]); - usage(argv[0]); + fprintf(stderr, "\"%s\" is not a recognized test name\n", testname); exit(1); } -- 2.20.1
>From 4b62c3159fe3aa8445317a5d65b7e81d91c7fba6 Mon Sep 17 00:00:00 2001 From: Alvaro Herrera <alvhe...@alvh.no-ip.org> Date: Fri, 26 Mar 2021 19:13:04 -0300 Subject: [PATCH 2/5] put FILE * arg always first --- src/interfaces/libpq/libpq-trace.c | 234 ++++++++++++++--------------- 1 file changed, 117 insertions(+), 117 deletions(-) diff --git a/src/interfaces/libpq/libpq-trace.c b/src/interfaces/libpq/libpq-trace.c index bacb7903b9..bff542cada 100644 --- a/src/interfaces/libpq/libpq-trace.c +++ b/src/interfaces/libpq/libpq-trace.c @@ -93,7 +93,7 @@ pqTraceFormatTimestamp(char *timestr, size_t ts_len) * pqTraceOutputByte1: output 1 char message to the log */ static void -pqTraceOutputByte1(const char *data, int *cursor, FILE *pfdebug) +pqTraceOutputByte1(FILE *pfdebug, const char *data, int *cursor) { const char *v = data + *cursor; @@ -113,7 +113,7 @@ pqTraceOutputByte1(const char *data, int *cursor, FILE *pfdebug) * pqTraceOutputInt16: output a 2-byte integer message to the log */ static int -pqTraceOutputInt16(const char *data, int *cursor, FILE *pfdebug) +pqTraceOutputInt16(FILE *pfdebug, const char *data, int *cursor) { uint16 tmp; int result; @@ -130,7 +130,7 @@ pqTraceOutputInt16(const char *data, int *cursor, FILE *pfdebug) * pqTraceOutputInt32: output a 4-byte integer message to the log */ static int -pqTraceOutputInt32(const char *data, int *cursor, FILE *pfdebug) +pqTraceOutputInt32(FILE *pfdebug, const char *data, int *cursor) { int result; @@ -146,7 +146,7 @@ pqTraceOutputInt32(const char *data, int *cursor, FILE *pfdebug) * pqTraceOutputString: output a string message to the log */ static void -pqTraceOutputString(const char *data, int *cursor, FILE *pfdebug) +pqTraceOutputString(FILE *pfdebug, const char *data, int *cursor) { int len; @@ -163,7 +163,7 @@ pqTraceOutputString(const char *data, int *cursor, FILE *pfdebug) * pqTraceOutputNchar: output a string of exactly len bytes message to the log */ static void -pqTraceOutputNchar(const char *data, int *cursor, FILE *pfdebug, int len) +pqTraceOutputNchar(FILE *pfdebug, int len, const char *data, int *cursor) { int i, next; /* first char not yet printed */ @@ -195,28 +195,28 @@ pqTraceOutputNchar(const char *data, int *cursor, FILE *pfdebug, int len) /* Authentication */ static void -pqTraceOutputR(const char *message, FILE *f) +pqTraceOutputR(FILE *f, const char *message) { int cursor = 0; fprintf(f, "Authentication\t"); - pqTraceOutputInt32(message, &cursor, f); + pqTraceOutputInt32(f, message, &cursor); } /* BackendKeyData */ static void -pqTraceOutputK(const char *message, FILE *f) +pqTraceOutputK(FILE *f, const char *message) { int cursor = 0; fprintf(f, "BackendKeyData\t"); - pqTraceOutputInt32(message, &cursor, f); - pqTraceOutputInt32(message, &cursor, f); + pqTraceOutputInt32(f, message, &cursor); + pqTraceOutputInt32(f, message, &cursor); } /* Bind */ static void -pqTraceOutputB(const char *message, int end, FILE *f) +pqTraceOutputB(FILE *f, const char *message, int end) { int cursor = 0; int nparams; @@ -224,113 +224,113 @@ pqTraceOutputB(const char *message, int end, FILE *f) int i; fprintf(f, "Bind\t"); - pqTraceOutputString(message, &cursor, f); - pqTraceOutputString(message, &cursor, f); - nparams = pqTraceOutputInt16(message, &cursor, f); + pqTraceOutputString(f, message, &cursor); + pqTraceOutputString(f, message, &cursor); + nparams = pqTraceOutputInt16(f, message, &cursor); for (i = 0; i < nparams; i++) - pqTraceOutputInt16(message, &cursor, f); + pqTraceOutputInt16(f, message, &cursor); - nparams = pqTraceOutputInt16(message, &cursor, f); + nparams = pqTraceOutputInt16(f, message, &cursor); for (i = 0; i < nparams; i++) { - nbytes = pqTraceOutputInt32(message, &cursor, f); + nbytes = pqTraceOutputInt32(f, message, &cursor); if (nbytes == -1) continue; - pqTraceOutputNchar(message, &cursor, f, nbytes); + pqTraceOutputNchar(f, nbytes, message, &cursor); } - nparams = pqTraceOutputInt16(message, &cursor, f); + nparams = pqTraceOutputInt16(f, message, &cursor); for (i = 0; i < nparams; i++) - pqTraceOutputInt16(message, &cursor, f); + pqTraceOutputInt16(f, message, &cursor); } /* Close(F) or CommandComplete(B) */ static void -pqTraceOutputC(const char *message, int end, FILE *f, bool toServer) +pqTraceOutputC(FILE *f, bool toServer, const char *message, int end) { int cursor = 0; if (toServer) { fprintf(f, "Close\t"); - pqTraceOutputByte1(message, &cursor, f); - pqTraceOutputString(message, &cursor, f); + pqTraceOutputByte1(f, message, &cursor); + pqTraceOutputString(f, message, &cursor); } else { fprintf(f, "CommandComplete\t"); - pqTraceOutputString(message, &cursor, f); + pqTraceOutputString(f, message, &cursor); } } /* CopyFail */ static void -pqTraceOutputf(const char *message, int end, FILE *f) +pqTraceOutputf(FILE *f, const char *message, int end) { int cursor = 0; fprintf(f, "CopyFail\t"); - pqTraceOutputString(message, &cursor, f); + pqTraceOutputString(f, message, &cursor); } /* CopyInResponse */ static void -pqTraceOutputG(const char *message, int end, FILE *f) +pqTraceOutputG(FILE *f, const char *message, int end) { int cursor = 0; int nfields; int i; fprintf(f, "CopyInResponse\t"); - pqTraceOutputByte1(message, &cursor, f); - nfields = pqTraceOutputInt16(message, &cursor, f); + pqTraceOutputByte1(f, message, &cursor); + nfields = pqTraceOutputInt16(f, message, &cursor); for (i = 0; i < nfields; i++) - pqTraceOutputInt16(message, &cursor, f); + pqTraceOutputInt16(f, message, &cursor); } /* CopyOutResponse */ static void -pqTraceOutputH(const char *message, int end, FILE *f) +pqTraceOutputH(FILE *f, const char *message, int end) { int cursor = 0; int nfields; int i; fprintf(f, "CopyOutResponse\t"); - pqTraceOutputByte1(message, &cursor, f); - nfields = pqTraceOutputInt16(message, &cursor, f); + pqTraceOutputByte1(f, message, &cursor); + nfields = pqTraceOutputInt16(f, message, &cursor); for (i = 0; i < nfields; i++) - pqTraceOutputInt16(message, &cursor, f); + pqTraceOutputInt16(f, message, &cursor); } /* CopyBothResponse */ static void -pqTraceOutputW(const char *message, int end, FILE *f) +pqTraceOutputW(FILE *f, const char *message, int end) { int cursor = 0; fprintf(f, "CopyBothResponse\t"); - pqTraceOutputByte1(message, &cursor, f); + pqTraceOutputByte1(f, message, &cursor); while (end > cursor) - pqTraceOutputInt16(message, &cursor, f); + pqTraceOutputInt16(f, message, &cursor); } /* Describe(F) or DataRow(B) */ static void -pqTraceOutputD(const char *message, int end, FILE *f, bool toServer) +pqTraceOutputD(FILE *f, bool toServer, const char *message, int end) { int cursor = 0; if (toServer) { fprintf(f, "Describe\t"); - pqTraceOutputByte1(message, &cursor, f); - pqTraceOutputString(message, &cursor, f); + pqTraceOutputByte1(f, message, &cursor); + pqTraceOutputString(f, message, &cursor); } else { @@ -339,45 +339,45 @@ pqTraceOutputD(const char *message, int end, FILE *f, bool toServer) int i; fprintf(f, "DataRow\t"); - nfields = pqTraceOutputInt16(message, &cursor, f); + nfields = pqTraceOutputInt16(f, message, &cursor); for (i = 0; i < nfields; i++) { - len = pqTraceOutputInt32(message, &cursor, f); + len = pqTraceOutputInt32(f, message, &cursor); if (len == -1) continue; - pqTraceOutputNchar(message, &cursor, f, len); + pqTraceOutputNchar(f, len, message, &cursor); } } } /* Execute(F) or ErrorResponse(B) */ static void -pqTraceOutputE(const char *message, int end, FILE *f, bool toServer) +pqTraceOutputE(FILE *f, bool toServer, const char *message, int end) { int cursor = 0; if (toServer) { fprintf(f, "Execute\t"); - pqTraceOutputString(message, &cursor, f); - pqTraceOutputInt32(message, &cursor, f); + pqTraceOutputString(f, message, &cursor); + pqTraceOutputInt32(f, message, &cursor); } else { fprintf(f, "ErrorResponse\t"); while (end > cursor) { - pqTraceOutputByte1(message, &cursor, f); + pqTraceOutputByte1(f, message, &cursor); if (message[cursor] == '\0') continue; - pqTraceOutputString(message, &cursor, f); + pqTraceOutputString(f, message, &cursor); } } } /* FunctionCall */ static void -pqTraceOutputF(const char *message, FILE *f) +pqTraceOutputF(FILE *f, const char *message) { int cursor = 0; int nfields; @@ -385,160 +385,160 @@ pqTraceOutputF(const char *message, FILE *f) int i; fprintf(f, "FunctionCall\t"); - pqTraceOutputInt32(message, &cursor, f); - nfields = pqTraceOutputInt16(message, &cursor, f); + pqTraceOutputInt32(f, message, &cursor); + nfields = pqTraceOutputInt16(f, message, &cursor); for (i = 0; i < nfields; i++) - pqTraceOutputInt16(message, &cursor, f); + pqTraceOutputInt16(f, message, &cursor); - nfields = pqTraceOutputInt16(message, &cursor, f); + nfields = pqTraceOutputInt16(f, message, &cursor); for (i = 0; i < nfields; i++) { - nbytes = pqTraceOutputInt32(message, &cursor, f); + nbytes = pqTraceOutputInt32(f, message, &cursor); if (nbytes == -1) continue; - pqTraceOutputNchar(message, &cursor, f, nbytes); + pqTraceOutputNchar(f, nbytes, message, &cursor); } - pqTraceOutputInt16(message, &cursor, f); + pqTraceOutputInt16(f, message, &cursor); } /* FunctionCallResponse */ static void -pqTraceOutputV(const char *message, FILE *f) +pqTraceOutputV(FILE *f, const char *message) { int cursor = 0; int len; fprintf(f, "FunctionCallResponse\t"); - len = pqTraceOutputInt32(message, &cursor, f); + len = pqTraceOutputInt32(f, message, &cursor); if (len != -1) - pqTraceOutputNchar(message, &cursor, f, len); + pqTraceOutputNchar(f, len, message, &cursor); } /* NegotiateProtocolVersion */ static void -pqTraceOutputv(const char *message, FILE *f) +pqTraceOutputv(FILE *f, const char *message) { int cursor = 0; fprintf(f, "NegotiateProtocolVersion\t"); - pqTraceOutputInt32(message, &cursor, f); - pqTraceOutputInt32(message, &cursor, f); + pqTraceOutputInt32(f, message, &cursor); + pqTraceOutputInt32(f, message, &cursor); } /* NoticeResponse */ static void -pqTraceOutputN(const char *message, int end, FILE *f) +pqTraceOutputN(FILE *f, const char *message, int end) { int cursor = 0; fprintf(f, "NoticeResponse\t"); while (end > cursor) { - pqTraceOutputByte1(message, &cursor, f); + pqTraceOutputByte1(f, message, &cursor); if (message[cursor] == '\0') continue; - pqTraceOutputString(message, &cursor, f); + pqTraceOutputString(f, message, &cursor); } } /* NotificationResponse */ static void -pqTraceOutputA(const char *message, int end, FILE *f) +pqTraceOutputA(FILE *f, const char *message, int end) { int cursor = 0; fprintf(f, "NotificationResponse\t"); - pqTraceOutputInt32(message, &cursor, f); - pqTraceOutputString(message, &cursor, f); - pqTraceOutputString(message, &cursor, f); + pqTraceOutputInt32(f, message, &cursor); + pqTraceOutputString(f, message, &cursor); + pqTraceOutputString(f, message, &cursor); } /* ParameterDescription */ static void -pqTraceOutputt(const char *message, FILE *f) +pqTraceOutputt(FILE *f, const char *message) { int cursor = 0; int nfields; int i; fprintf(f, "ParameterDescription\t"); - nfields = pqTraceOutputInt16(message, &cursor, f); + nfields = pqTraceOutputInt16(f, message, &cursor); for (i = 0; i < nfields; i++) - pqTraceOutputInt32(message, &cursor, f); + pqTraceOutputInt32(f, message, &cursor); } /* ParameterStatus */ static void -pqTraceOutputS(const char *message, int end, FILE *f) +pqTraceOutputS(FILE *f, const char *message, int end) { int cursor = 0; fprintf(f, "ParameterStatus\t"); - pqTraceOutputString(message, &cursor, f); - pqTraceOutputString(message, &cursor, f); + pqTraceOutputString(f, message, &cursor); + pqTraceOutputString(f, message, &cursor); } /* Parse */ static void -pqTraceOutputP(const char *message, int end, FILE *f) +pqTraceOutputP(FILE *f, const char *message, int end) { int cursor = 0; int nparams; int i; fprintf(f, "Parse\t"); - pqTraceOutputString(message, &cursor, f); - pqTraceOutputString(message, &cursor, f); - nparams = pqTraceOutputInt16(message, &cursor, f); + pqTraceOutputString(f, message, &cursor); + pqTraceOutputString(f, message, &cursor); + nparams = pqTraceOutputInt16(f, message, &cursor); for (i = 0; i < nparams; i++) - pqTraceOutputInt32(message, &cursor, f); + pqTraceOutputInt32(f, message, &cursor); } /* Query */ static void -pqTraceOutputQ(const char *message, int end, FILE *f) +pqTraceOutputQ(FILE *f, const char *message, int end) { int cursor = 0; fprintf(f, "Query\t"); - pqTraceOutputString(message, &cursor, f); + pqTraceOutputString(f, message, &cursor); } /* ReadyForQuery */ static void -pqTraceOutputZ(const char *message, FILE *f) +pqTraceOutputZ(FILE *f, const char *message) { int cursor = 0; fprintf(f, "ReadyForQuery\t"); - pqTraceOutputByte1(message, &cursor, f); + pqTraceOutputByte1(f, message, &cursor); } /* RowDescription */ static void -pqTraceOutputT(const char *message, int end, FILE *f) +pqTraceOutputT(FILE *f, const char *message, int end) { int cursor = 0; int nfields; int i; fprintf(f, "RowDescription\t"); - nfields = pqTraceOutputInt16(message, &cursor, f); + nfields = pqTraceOutputInt16(f, message, &cursor); for (i = 0; i < nfields; i++) { - pqTraceOutputString(message, &cursor, f); - pqTraceOutputInt32(message, &cursor, f); - pqTraceOutputInt16(message, &cursor, f); - pqTraceOutputInt32(message, &cursor, f); - pqTraceOutputInt16(message, &cursor, f); - pqTraceOutputInt32(message, &cursor, f); - pqTraceOutputInt16(message, &cursor, f); + pqTraceOutputString(f, message, &cursor); + pqTraceOutputInt32(f, message, &cursor); + pqTraceOutputInt16(f, message, &cursor); + pqTraceOutputInt32(f, message, &cursor); + pqTraceOutputInt16(f, message, &cursor); + pqTraceOutputInt32(f, message, &cursor); + pqTraceOutputInt16(f, message, &cursor); } } @@ -569,76 +569,76 @@ pqTraceOutputMessage(PGconn *conn, const char *message, bool toServer) switch(id) { case 'R': /* Authentication */ - pqTraceOutputR(message + LogCursor, conn->Pfdebug); + pqTraceOutputR(conn->Pfdebug, message + LogCursor); break; case 'K': /* secret key data from the backend */ - pqTraceOutputK(message + LogCursor, conn->Pfdebug); + pqTraceOutputK(conn->Pfdebug, message + LogCursor); break; case 'B': /* Bind */ - pqTraceOutputB(message + LogCursor, LogEnd, conn->Pfdebug); + pqTraceOutputB(conn->Pfdebug, message + LogCursor, LogEnd); break; case 'C': /* Close(F) or Command Complete(B) */ - pqTraceOutputC(message + LogCursor, LogEnd, conn->Pfdebug, toServer); + pqTraceOutputC(conn->Pfdebug, toServer, message + LogCursor, LogEnd); break; case 'd': /* Copy Data */ /* Drop COPY data to reduce the overhead of logging. */ break; case 'f': /* Copy Fail */ - pqTraceOutputf(message + LogCursor, LogEnd, conn->Pfdebug); + pqTraceOutputf(conn->Pfdebug, message + LogCursor, LogEnd); break; case 'G': /* Start Copy In */ - pqTraceOutputG(message + LogCursor, LogEnd, conn->Pfdebug); + pqTraceOutputG(conn->Pfdebug, message + LogCursor, LogEnd); break; case 'H': /* Flush(F) or Start Copy Out(B) */ if (!toServer) - pqTraceOutputH(message + LogCursor, LogEnd, conn->Pfdebug); + pqTraceOutputH(conn->Pfdebug, message + LogCursor, LogEnd); else fprintf(conn->Pfdebug, "Flush"); break; case 'W': /* Start Copy Both */ - pqTraceOutputW(message + LogCursor, LogEnd, conn->Pfdebug); + pqTraceOutputW(conn->Pfdebug, message + LogCursor, LogEnd); break; case 'D': /* Describe(F) or Data Row(B) */ - pqTraceOutputD(message + LogCursor, LogEnd, conn->Pfdebug, toServer); + pqTraceOutputD(conn->Pfdebug, toServer, message + LogCursor, LogEnd); break; case 'E': /* Execute(F) or Error Response(B) */ - pqTraceOutputE(message + LogCursor, LogEnd, conn->Pfdebug, toServer); + pqTraceOutputE(conn->Pfdebug, toServer, message + LogCursor, LogEnd); break; case 'F': /* Function Call */ - pqTraceOutputF(message + LogCursor, conn->Pfdebug); + pqTraceOutputF(conn->Pfdebug, message + LogCursor); break; case 'V': /* Function Call response */ - pqTraceOutputV(message + LogCursor, conn->Pfdebug); + pqTraceOutputV(conn->Pfdebug, message + LogCursor); break; case 'v': /* Negotiate Protocol Version */ - pqTraceOutputv(message + LogCursor, conn->Pfdebug); + pqTraceOutputv(conn->Pfdebug, message + LogCursor); break; case 'N': /* Notice Response */ - pqTraceOutputN(message + LogCursor, LogEnd, conn->Pfdebug); + pqTraceOutputN(conn->Pfdebug, message + LogCursor, LogEnd); break; case 'A': /* Notification Response */ - pqTraceOutputA(message + LogCursor, LogEnd, conn->Pfdebug); + pqTraceOutputA(conn->Pfdebug, message + LogCursor, LogEnd); break; case 't': /* Parameter Description */ - pqTraceOutputt(message + LogCursor, conn->Pfdebug); + pqTraceOutputt(conn->Pfdebug, message + LogCursor); break; case 'S': /* Parameter Status(B) or Sync(F) */ if (!toServer) - pqTraceOutputS(message + LogCursor, LogEnd, conn->Pfdebug); + pqTraceOutputS(conn->Pfdebug, message + LogCursor, LogEnd); else fprintf(conn->Pfdebug, "Sync"); break; case 'P': /* Parse */ - pqTraceOutputP(message + LogCursor, LogEnd, conn->Pfdebug); + pqTraceOutputP(conn->Pfdebug, message + LogCursor, LogEnd); break; case 'Q': /* Query */ - pqTraceOutputQ(message + LogCursor, LogEnd, conn->Pfdebug); + pqTraceOutputQ(conn->Pfdebug, message + LogCursor, LogEnd); break; case 'Z': /* Ready For Query */ - pqTraceOutputZ(message + LogCursor, conn->Pfdebug); + pqTraceOutputZ(conn->Pfdebug, message + LogCursor); break; case 'T': /* Row Description */ - pqTraceOutputT(message + LogCursor, LogEnd, conn->Pfdebug); + pqTraceOutputT(conn->Pfdebug, message + LogCursor, LogEnd); break; case '2': /* Bind Complete */ fprintf(conn->Pfdebug, "BindComplete"); @@ -702,9 +702,9 @@ pqTraceOutputNoTypeByteMessage(PGconn *conn, const char *message) { case 16: /* CancelRequest */ fprintf(conn->Pfdebug, "CancelRequest\t"); - pqTraceOutputInt32(message, &LogCursor, conn->Pfdebug); - pqTraceOutputInt32(message, &LogCursor, conn->Pfdebug); - pqTraceOutputInt32(message, &LogCursor, conn->Pfdebug); + pqTraceOutputInt32(conn->Pfdebug, message, &LogCursor); + pqTraceOutputInt32(conn->Pfdebug, message, &LogCursor); + pqTraceOutputInt32(conn->Pfdebug, message, &LogCursor); break; case 8 : /* GSSENCRequest or SSLRequest */ /* These messages do not reach here. */ -- 2.20.1
>From d44009a25de3af549dfa528a4fa44c9ebf785c42 Mon Sep 17 00:00:00 2001 From: Alvaro Herrera <alvhe...@alvh.no-ip.org> Date: Fri, 26 Mar 2021 19:13:16 -0300 Subject: [PATCH 3/5] use F/B instead of </> --- src/interfaces/libpq/libpq-trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interfaces/libpq/libpq-trace.c b/src/interfaces/libpq/libpq-trace.c index bff542cada..94f28f04a8 100644 --- a/src/interfaces/libpq/libpq-trace.c +++ b/src/interfaces/libpq/libpq-trace.c @@ -548,7 +548,7 @@ pqTraceOutputMessage(PGconn *conn, const char *message, bool toServer) char timestr[128]; char id; int length; - char *prefix = toServer ? ">" : "<"; + char *prefix = toServer ? "F" : "B"; int LogCursor = 0; int LogEnd; -- 2.20.1
>From 39a5e0c6b5559a0fb9a6c376e493e4ee4bc980fb Mon Sep 17 00:00:00 2001 From: Alvaro Herrera <alvhe...@alvh.no-ip.org> Date: Fri, 26 Mar 2021 20:04:53 -0300 Subject: [PATCH 4/5] pass *cursor to printing routines --- src/interfaces/libpq/libpq-trace.c | 309 +++++++++++++---------------- 1 file changed, 134 insertions(+), 175 deletions(-) diff --git a/src/interfaces/libpq/libpq-trace.c b/src/interfaces/libpq/libpq-trace.c index 94f28f04a8..06d8d981a3 100644 --- a/src/interfaces/libpq/libpq-trace.c +++ b/src/interfaces/libpq/libpq-trace.c @@ -106,7 +106,7 @@ pqTraceOutputByte1(FILE *pfdebug, const char *data, int *cursor) fprintf(pfdebug, " \\x%02x", *v); else fprintf(pfdebug, " %c", *v); - ++*cursor; + *cursor += 1; } /* @@ -195,142 +195,125 @@ pqTraceOutputNchar(FILE *pfdebug, int len, const char *data, int *cursor) /* Authentication */ static void -pqTraceOutputR(FILE *f, const char *message) +pqTraceOutputR(FILE *f, const char *message, int *cursor) { - int cursor = 0; - fprintf(f, "Authentication\t"); - pqTraceOutputInt32(f, message, &cursor); + pqTraceOutputInt32(f, message, cursor); } /* BackendKeyData */ static void -pqTraceOutputK(FILE *f, const char *message) +pqTraceOutputK(FILE *f, const char *message, int *cursor) { - int cursor = 0; - fprintf(f, "BackendKeyData\t"); - pqTraceOutputInt32(f, message, &cursor); - pqTraceOutputInt32(f, message, &cursor); + pqTraceOutputInt32(f, message, cursor); + pqTraceOutputInt32(f, message, cursor); } /* Bind */ static void -pqTraceOutputB(FILE *f, const char *message, int end) +pqTraceOutputB(FILE *f, const char *message, int *cursor) { - int cursor = 0; int nparams; - int nbytes; - int i; fprintf(f, "Bind\t"); - pqTraceOutputString(f, message, &cursor); - pqTraceOutputString(f, message, &cursor); - nparams = pqTraceOutputInt16(f, message, &cursor); + pqTraceOutputString(f, message, cursor); + pqTraceOutputString(f, message, cursor); + nparams = pqTraceOutputInt16(f, message, cursor); - for (i = 0; i < nparams; i++) - pqTraceOutputInt16(f, message, &cursor); + for (int i = 0; i < nparams; i++) + pqTraceOutputInt16(f, message, cursor); - nparams = pqTraceOutputInt16(f, message, &cursor); + nparams = pqTraceOutputInt16(f, message, cursor); - for (i = 0; i < nparams; i++) + for (int i = 0; i < nparams; i++) { - nbytes = pqTraceOutputInt32(f, message, &cursor); + int nbytes; + + nbytes = pqTraceOutputInt32(f, message, cursor); if (nbytes == -1) continue; - pqTraceOutputNchar(f, nbytes, message, &cursor); + pqTraceOutputNchar(f, nbytes, message, cursor); } - nparams = pqTraceOutputInt16(f, message, &cursor); - for (i = 0; i < nparams; i++) - pqTraceOutputInt16(f, message, &cursor); + nparams = pqTraceOutputInt16(f, message, cursor); + for (int i = 0; i < nparams; i++) + pqTraceOutputInt16(f, message, cursor); } /* Close(F) or CommandComplete(B) */ static void -pqTraceOutputC(FILE *f, bool toServer, const char *message, int end) +pqTraceOutputC(FILE *f, bool toServer, const char *message, int *cursor) { - int cursor = 0; - if (toServer) { fprintf(f, "Close\t"); - pqTraceOutputByte1(f, message, &cursor); - pqTraceOutputString(f, message, &cursor); + pqTraceOutputByte1(f, message, cursor); + pqTraceOutputString(f, message, cursor); } else { fprintf(f, "CommandComplete\t"); - pqTraceOutputString(f, message, &cursor); + pqTraceOutputString(f, message, cursor); } } /* CopyFail */ static void -pqTraceOutputf(FILE *f, const char *message, int end) +pqTraceOutputf(FILE *f, const char *message, int *cursor) { - int cursor = 0; - fprintf(f, "CopyFail\t"); - pqTraceOutputString(f, message, &cursor); + pqTraceOutputString(f, message, cursor); } /* CopyInResponse */ static void -pqTraceOutputG(FILE *f, const char *message, int end) +pqTraceOutputG(FILE *f, const char *message, int *cursor) { - int cursor = 0; int nfields; - int i; fprintf(f, "CopyInResponse\t"); - pqTraceOutputByte1(f, message, &cursor); - nfields = pqTraceOutputInt16(f, message, &cursor); + pqTraceOutputByte1(f, message, cursor); + nfields = pqTraceOutputInt16(f, message, cursor); - for (i = 0; i < nfields; i++) - pqTraceOutputInt16(f, message, &cursor); + for (int i = 0; i < nfields; i++) + pqTraceOutputInt16(f, message, cursor); } /* CopyOutResponse */ static void -pqTraceOutputH(FILE *f, const char *message, int end) +pqTraceOutputH(FILE *f, const char *message, int *cursor) { - int cursor = 0; int nfields; - int i; fprintf(f, "CopyOutResponse\t"); - pqTraceOutputByte1(f, message, &cursor); - nfields = pqTraceOutputInt16(f, message, &cursor); + pqTraceOutputByte1(f, message, cursor); + nfields = pqTraceOutputInt16(f, message, cursor); - for (i = 0; i < nfields; i++) - pqTraceOutputInt16(f, message, &cursor); + for (int i = 0; i < nfields; i++) + pqTraceOutputInt16(f, message, cursor); } /* CopyBothResponse */ static void -pqTraceOutputW(FILE *f, const char *message, int end) +pqTraceOutputW(FILE *f, const char *message, int *cursor, int length) { - int cursor = 0; - fprintf(f, "CopyBothResponse\t"); - pqTraceOutputByte1(f, message, &cursor); + pqTraceOutputByte1(f, message, cursor); - while (end > cursor) - pqTraceOutputInt16(f, message, &cursor); + while (length > *cursor) + pqTraceOutputInt16(f, message, cursor); } /* Describe(F) or DataRow(B) */ static void -pqTraceOutputD(FILE *f, bool toServer, const char *message, int end) +pqTraceOutputD(FILE *f, bool toServer, const char *message, int *cursor) { - int cursor = 0; - if (toServer) { fprintf(f, "Describe\t"); - pqTraceOutputByte1(f, message, &cursor); - pqTraceOutputString(f, message, &cursor); + pqTraceOutputByte1(f, message, cursor); + pqTraceOutputString(f, message, cursor); } else { @@ -339,206 +322,183 @@ pqTraceOutputD(FILE *f, bool toServer, const char *message, int end) int i; fprintf(f, "DataRow\t"); - nfields = pqTraceOutputInt16(f, message, &cursor); + nfields = pqTraceOutputInt16(f, message, cursor); for (i = 0; i < nfields; i++) { - len = pqTraceOutputInt32(f, message, &cursor); + len = pqTraceOutputInt32(f, message, cursor); if (len == -1) continue; - pqTraceOutputNchar(f, len, message, &cursor); + pqTraceOutputNchar(f, len, message, cursor); } } } /* Execute(F) or ErrorResponse(B) */ static void -pqTraceOutputE(FILE *f, bool toServer, const char *message, int end) +pqTraceOutputE(FILE *f, bool toServer, const char *message, int *cursor, int length) { - int cursor = 0; - if (toServer) { fprintf(f, "Execute\t"); - pqTraceOutputString(f, message, &cursor); - pqTraceOutputInt32(f, message, &cursor); + pqTraceOutputString(f, message, cursor); + pqTraceOutputInt32(f, message, cursor); } else { fprintf(f, "ErrorResponse\t"); - while (end > cursor) + for (;;) { - pqTraceOutputByte1(f, message, &cursor); - if (message[cursor] == '\0') - continue; - pqTraceOutputString(f, message, &cursor); + pqTraceOutputByte1(f, message, cursor); + if (message[*cursor - 1] == '\0') + break; + pqTraceOutputString(f, message, cursor); } } } /* FunctionCall */ static void -pqTraceOutputF(FILE *f, const char *message) +pqTraceOutputF(FILE *f, const char *message, int *cursor) { - int cursor = 0; int nfields; int nbytes; - int i; fprintf(f, "FunctionCall\t"); - pqTraceOutputInt32(f, message, &cursor); - nfields = pqTraceOutputInt16(f, message, &cursor); + pqTraceOutputInt32(f, message, cursor); + nfields = pqTraceOutputInt16(f, message, cursor); - for (i = 0; i < nfields; i++) - pqTraceOutputInt16(f, message, &cursor); + for (int i = 0; i < nfields; i++) + pqTraceOutputInt16(f, message, cursor); - nfields = pqTraceOutputInt16(f, message, &cursor); + nfields = pqTraceOutputInt16(f, message, cursor); - for (i = 0; i < nfields; i++) + for (int i = 0; i < nfields; i++) { - nbytes = pqTraceOutputInt32(f, message, &cursor); + nbytes = pqTraceOutputInt32(f, message, cursor); if (nbytes == -1) continue; - pqTraceOutputNchar(f, nbytes, message, &cursor); + pqTraceOutputNchar(f, nbytes, message, cursor); } - pqTraceOutputInt16(f, message, &cursor); + pqTraceOutputInt16(f, message, cursor); } /* FunctionCallResponse */ static void -pqTraceOutputV(FILE *f, const char *message) +pqTraceOutputV(FILE *f, const char *message, int *cursor) { - int cursor = 0; int len; fprintf(f, "FunctionCallResponse\t"); - len = pqTraceOutputInt32(f, message, &cursor); + len = pqTraceOutputInt32(f, message, cursor); if (len != -1) - pqTraceOutputNchar(f, len, message, &cursor); + pqTraceOutputNchar(f, len, message, cursor); } /* NegotiateProtocolVersion */ static void -pqTraceOutputv(FILE *f, const char *message) +pqTraceOutputv(FILE *f, const char *message, int *cursor) { - int cursor = 0; - fprintf(f, "NegotiateProtocolVersion\t"); - pqTraceOutputInt32(f, message, &cursor); - pqTraceOutputInt32(f, message, &cursor); + pqTraceOutputInt32(f, message, cursor); + pqTraceOutputInt32(f, message, cursor); } /* NoticeResponse */ static void -pqTraceOutputN(FILE *f, const char *message, int end) +pqTraceOutputN(FILE *f, const char *message, int *cursor, int length) { - int cursor = 0; - fprintf(f, "NoticeResponse\t"); - while (end > cursor) + for (;;) { - pqTraceOutputByte1(f, message, &cursor); - if (message[cursor] == '\0') - continue; - pqTraceOutputString(f, message, &cursor); + pqTraceOutputByte1(f, message, cursor); + if (message[*cursor - 1] == '\0') + break; + pqTraceOutputString(f, message, cursor); } } /* NotificationResponse */ static void -pqTraceOutputA(FILE *f, const char *message, int end) +pqTraceOutputA(FILE *f, const char *message, int *cursor) { - int cursor = 0; - fprintf(f, "NotificationResponse\t"); - pqTraceOutputInt32(f, message, &cursor); - pqTraceOutputString(f, message, &cursor); - pqTraceOutputString(f, message, &cursor); + pqTraceOutputInt32(f, message, cursor); + pqTraceOutputString(f, message, cursor); + pqTraceOutputString(f, message, cursor); } /* ParameterDescription */ static void -pqTraceOutputt(FILE *f, const char *message) +pqTraceOutputt(FILE *f, const char *message, int *cursor) { - int cursor = 0; int nfields; - int i; fprintf(f, "ParameterDescription\t"); - nfields = pqTraceOutputInt16(f, message, &cursor); + nfields = pqTraceOutputInt16(f, message, cursor); - for (i = 0; i < nfields; i++) - pqTraceOutputInt32(f, message, &cursor); + for (int i = 0; i < nfields; i++) + pqTraceOutputInt32(f, message, cursor); } /* ParameterStatus */ static void -pqTraceOutputS(FILE *f, const char *message, int end) +pqTraceOutputS(FILE *f, const char *message, int *cursor) { - int cursor = 0; - fprintf(f, "ParameterStatus\t"); - pqTraceOutputString(f, message, &cursor); - pqTraceOutputString(f, message, &cursor); + pqTraceOutputString(f, message, cursor); + pqTraceOutputString(f, message, cursor); } /* Parse */ static void -pqTraceOutputP(FILE *f, const char *message, int end) +pqTraceOutputP(FILE *f, const char *message, int *cursor) { - int cursor = 0; int nparams; - int i; fprintf(f, "Parse\t"); - pqTraceOutputString(f, message, &cursor); - pqTraceOutputString(f, message, &cursor); - nparams = pqTraceOutputInt16(f, message, &cursor); + pqTraceOutputString(f, message, cursor); + pqTraceOutputString(f, message, cursor); + nparams = pqTraceOutputInt16(f, message, cursor); - for (i = 0; i < nparams; i++) - pqTraceOutputInt32(f, message, &cursor); + for (int i = 0; i < nparams; i++) + pqTraceOutputInt32(f, message, cursor); } /* Query */ static void -pqTraceOutputQ(FILE *f, const char *message, int end) +pqTraceOutputQ(FILE *f, const char *message, int *cursor) { - int cursor = 0; - fprintf(f, "Query\t"); - pqTraceOutputString(f, message, &cursor); + pqTraceOutputString(f, message, cursor); } /* ReadyForQuery */ static void -pqTraceOutputZ(FILE *f, const char *message) +pqTraceOutputZ(FILE *f, const char *message, int *cursor) { - int cursor = 0; - fprintf(f, "ReadyForQuery\t"); - pqTraceOutputByte1(f, message, &cursor); + pqTraceOutputByte1(f, message, cursor); } /* RowDescription */ static void -pqTraceOutputT(FILE *f, const char *message, int end) +pqTraceOutputT(FILE *f, const char *message, int *cursor) { - int cursor = 0; int nfields; - int i; fprintf(f, "RowDescription\t"); - nfields = pqTraceOutputInt16(f, message, &cursor); + nfields = pqTraceOutputInt16(f, message, cursor); - for (i = 0; i < nfields; i++) + for (int i = 0; i < nfields; i++) { - pqTraceOutputString(f, message, &cursor); - pqTraceOutputInt32(f, message, &cursor); - pqTraceOutputInt16(f, message, &cursor); - pqTraceOutputInt32(f, message, &cursor); - pqTraceOutputInt16(f, message, &cursor); - pqTraceOutputInt32(f, message, &cursor); - pqTraceOutputInt16(f, message, &cursor); + pqTraceOutputString(f, message, cursor); + pqTraceOutputInt32(f, message, cursor); + pqTraceOutputInt16(f, message, cursor); + pqTraceOutputInt32(f, message, cursor); + pqTraceOutputInt16(f, message, cursor); + pqTraceOutputInt32(f, message, cursor); + pqTraceOutputInt16(f, message, cursor); } } @@ -550,95 +510,94 @@ pqTraceOutputMessage(PGconn *conn, const char *message, bool toServer) int length; char *prefix = toServer ? "F" : "B"; int LogCursor = 0; - int LogEnd; if ((conn->traceFlags & PQTRACE_SUPPRESS_TIMESTAMPS) == 0) + { pqTraceFormatTimestamp(timestr, sizeof(timestr)); - else - timestr[0] = '\0'; + fprintf(conn->Pfdebug, "%s\t", timestr); + } id = message[LogCursor++]; - memcpy(&length, message + LogCursor , 4); + memcpy(&length, message + LogCursor, 4); length = (int) pg_ntoh32(length); LogCursor += 4; - LogEnd = length - 4; - fprintf(conn->Pfdebug, "%s\t%s\t%d\t", timestr, prefix, length); + fprintf(conn->Pfdebug, "%s\t%d\t", prefix, length); switch(id) { case 'R': /* Authentication */ - pqTraceOutputR(conn->Pfdebug, message + LogCursor); + pqTraceOutputR(conn->Pfdebug, message, &LogCursor); break; case 'K': /* secret key data from the backend */ - pqTraceOutputK(conn->Pfdebug, message + LogCursor); + pqTraceOutputK(conn->Pfdebug, message, &LogCursor); break; case 'B': /* Bind */ - pqTraceOutputB(conn->Pfdebug, message + LogCursor, LogEnd); + pqTraceOutputB(conn->Pfdebug, message, &LogCursor); break; case 'C': /* Close(F) or Command Complete(B) */ - pqTraceOutputC(conn->Pfdebug, toServer, message + LogCursor, LogEnd); + pqTraceOutputC(conn->Pfdebug, toServer, message, &LogCursor); break; case 'd': /* Copy Data */ /* Drop COPY data to reduce the overhead of logging. */ break; case 'f': /* Copy Fail */ - pqTraceOutputf(conn->Pfdebug, message + LogCursor, LogEnd); + pqTraceOutputf(conn->Pfdebug, message, &LogCursor); break; case 'G': /* Start Copy In */ - pqTraceOutputG(conn->Pfdebug, message + LogCursor, LogEnd); + pqTraceOutputG(conn->Pfdebug, message, &LogCursor); break; case 'H': /* Flush(F) or Start Copy Out(B) */ if (!toServer) - pqTraceOutputH(conn->Pfdebug, message + LogCursor, LogEnd); + pqTraceOutputH(conn->Pfdebug, message, &LogCursor); else fprintf(conn->Pfdebug, "Flush"); break; case 'W': /* Start Copy Both */ - pqTraceOutputW(conn->Pfdebug, message + LogCursor, LogEnd); + pqTraceOutputW(conn->Pfdebug, message, &LogCursor, length); break; case 'D': /* Describe(F) or Data Row(B) */ - pqTraceOutputD(conn->Pfdebug, toServer, message + LogCursor, LogEnd); + pqTraceOutputD(conn->Pfdebug, toServer, message, &LogCursor); break; case 'E': /* Execute(F) or Error Response(B) */ - pqTraceOutputE(conn->Pfdebug, toServer, message + LogCursor, LogEnd); + pqTraceOutputE(conn->Pfdebug, toServer, message, &LogCursor, length); break; case 'F': /* Function Call */ - pqTraceOutputF(conn->Pfdebug, message + LogCursor); + pqTraceOutputF(conn->Pfdebug, message, &LogCursor); break; case 'V': /* Function Call response */ - pqTraceOutputV(conn->Pfdebug, message + LogCursor); + pqTraceOutputV(conn->Pfdebug, message, &LogCursor); break; case 'v': /* Negotiate Protocol Version */ - pqTraceOutputv(conn->Pfdebug, message + LogCursor); + pqTraceOutputv(conn->Pfdebug, message, &LogCursor); break; case 'N': /* Notice Response */ - pqTraceOutputN(conn->Pfdebug, message + LogCursor, LogEnd); + pqTraceOutputN(conn->Pfdebug, message, &LogCursor, length); break; case 'A': /* Notification Response */ - pqTraceOutputA(conn->Pfdebug, message + LogCursor, LogEnd); + pqTraceOutputA(conn->Pfdebug, message, &LogCursor); break; case 't': /* Parameter Description */ - pqTraceOutputt(conn->Pfdebug, message + LogCursor); + pqTraceOutputt(conn->Pfdebug, message, &LogCursor); break; case 'S': /* Parameter Status(B) or Sync(F) */ if (!toServer) - pqTraceOutputS(conn->Pfdebug, message + LogCursor, LogEnd); + pqTraceOutputS(conn->Pfdebug, message, &LogCursor); else fprintf(conn->Pfdebug, "Sync"); break; case 'P': /* Parse */ - pqTraceOutputP(conn->Pfdebug, message + LogCursor, LogEnd); + pqTraceOutputP(conn->Pfdebug, message, &LogCursor); break; case 'Q': /* Query */ - pqTraceOutputQ(conn->Pfdebug, message + LogCursor, LogEnd); + pqTraceOutputQ(conn->Pfdebug, message, &LogCursor); break; case 'Z': /* Ready For Query */ - pqTraceOutputZ(conn->Pfdebug, message + LogCursor); + pqTraceOutputZ(conn->Pfdebug, message, &LogCursor); break; case 'T': /* Row Description */ - pqTraceOutputT(conn->Pfdebug, message + LogCursor, LogEnd); + pqTraceOutputT(conn->Pfdebug, message, &LogCursor); break; case '2': /* Bind Complete */ fprintf(conn->Pfdebug, "BindComplete"); -- 2.20.1
>From 4d645bdf08de419b207b0064986d81f758900809 Mon Sep 17 00:00:00 2001 From: Alvaro Herrera <alvhe...@alvh.no-ip.org> Date: Fri, 26 Mar 2021 20:05:10 -0300 Subject: [PATCH 5/5] add length check --- src/interfaces/libpq/libpq-trace.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/interfaces/libpq/libpq-trace.c b/src/interfaces/libpq/libpq-trace.c index 06d8d981a3..6c58a578ac 100644 --- a/src/interfaces/libpq/libpq-trace.c +++ b/src/interfaces/libpq/libpq-trace.c @@ -637,6 +637,16 @@ pqTraceOutputMessage(PGconn *conn, const char *message, bool toServer) } fputc('\n', conn->Pfdebug); + + /* + * Verify the printing routine did it right. Note that the one-byte + * message identifier is not included in the length, but our cursor + * does include it. + */ + if (LogCursor - 1 != length) + fprintf(conn->Pfdebug, + "mismatched message length: consumed %d, expected %d\n", + LogCursor - 1, length); } void -- 2.20.1