c196af8b创建于 2021年3月8日历史提交
diff --git a/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/Makefile b/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/Makefile
index 321b61c..9b678ff 100644
--- a/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/Makefile
+++ b/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/Makefile
@@ -13,7 +13,14 @@
 EXTENSION  = pldbgapi
 MODULE_big = plugin_debugger
 
+top_builddir = ../../../..
+
+override CPPFLAGS := -I$(top_builddir)/src/common/pl/plpgsql/src -fPIC $(CPPFLAGS)
+#LDFLAGS += -pie
+CFLAGS += -Wl,-z,relro,-z,now
+
 OBJS	   = plpgsql_debugger.o plugin_debugger.o dbgcomm.o pldbgapi.o
+
 ifdef INCLUDE_PACKAGE_SUPPORT
 OBJS += spl_debugger.o
 endif
@@ -28,7 +35,6 @@ PGXS := $(shell $(PG_CONFIG) --pgxs)
 include $(PGXS)
 else
 subdir       = contrib/pldebugger
-top_builddir = ../..
 include $(top_builddir)/src/Makefile.global
 include $(top_srcdir)/contrib/contrib-global.mk
 endif
@@ -37,7 +43,6 @@ endif
 # it is installed into include/server, but when building without pgxs,
 # with the pldebugger directory being directly in the server source tree's
 # contrib directory, we need to tell the compiler where to find it.
-plpgsql_debugger.o: CFLAGS += -I$(top_builddir)/src/pl/plpgsql/src
 
 ################################################################################
 ## If we're building against EnterpriseDB's Advanced Server, also build a
@@ -52,7 +57,7 @@ plpgsql_debugger.o: CFLAGS += -I$(top_builddir)/src/pl/plpgsql/src
 ## To enable this, you need to run make as "make INCLUDE_PACKAGE_SUPPORT=1"
 ## 
 ifdef INCLUDE_PACKAGE_SUPPORT
-spl_debugger.c:  plpgsql_debugger.c
+spl_debugger.cpp:  plpgsql_debugger.cpp
 	sed -e 's/plpgsql_/spl_/g' $(module_srcdir)plpgsql_debugger.c > spl_debugger.c
 
 spl_debugger.o: 	CFLAGS += -DINCLUDE_PACKAGE_SUPPORT=1 -I$(top_builddir)/src/pl/edb-spl/src
diff --git a/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/dbgcomm.cpp b/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/dbgcomm.cpp
index 3ad3129..35f0e96 100644
--- a/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/dbgcomm.cpp
+++ b/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/dbgcomm.cpp
@@ -25,7 +25,7 @@
 
 #include "miscadmin.h"
 #include "storage/backendid.h"
-#include "storage/lwlock.h"
+#include "storage/lock/lwlock.h"
 #include "storage/pmsignal.h"
 #include "storage/shmem.h"
 #include "storage/sinvaladt.h"
@@ -68,12 +68,12 @@
 #define DBGCOMM_PROXY_CONNECTING	2	/* proxy is connecting to our port */
 #define DBGCOMM_CONNECTING_TO_PROXY	3	/* target is connecting to a proxy */
 
-typedef struct
-{
-	BackendId		backendid;
+typedef struct {
+    int proxyId;
 	int			status;
-	int			pid;
+    uint64 sessionId;
 	int			port;
+    Oid userid;
 } dbgcomm_target_slot_t;
 
 static dbgcomm_target_slot_t *dbgcomm_slots = NULL;
@@ -90,7 +90,7 @@ static dbgcomm_target_slot_t *dbgcomm_slots = NULL;
 static void dbgcomm_init(void);
 static uint32 resolveHostName(const char *hostName);
 static int findFreeTargetSlot(void);
-static int findTargetSlot(BackendId backendid);
+static int findTargetSlot(int proxyId);
 
 /**********************************************************************
  * Initialization routines
@@ -118,7 +118,8 @@ dbgcomm_init(void)
 		return;
 
 	LWLockAcquire(getPLDebuggerLock(), LW_EXCLUSIVE);
-	dbgcomm_slots = ShmemInitStruct("Debugger Connection slots", sizeof(dbgcomm_target_slot_t) * NumTargetSlots, &found);
+	dbgcomm_slots = (dbgcomm_target_slot_t*)ShmemInitStruct("Debugger Connection slots",
+					sizeof(dbgcomm_target_slot_t) * NumTargetSlots, &found);
 	if (dbgcomm_slots == NULL)
 		elog(ERROR, "out of shared memory");
 
@@ -127,8 +128,9 @@ dbgcomm_init(void)
 		int i;
 		for (i = 0; i < NumTargetSlots; i++)
 		{
-			dbgcomm_slots[i].backendid = InvalidBackendId;
+            dbgcomm_slots[i].proxyId = -1;
 			dbgcomm_slots[i].status = DBGCOMM_IDLE;
+            dbgcomm_slots[i].userid = GetUserId();
 		}
 	}
 	LWLockRelease(getPLDebuggerLock());
@@ -153,8 +155,7 @@ dbgcomm_init(void)
  * We assume that the proxyPort came from a breakpoint or some other reliable
  * source, so that we don't allow connecting to any random port in the system.
  */
-int
-dbgcomm_connect_to_proxy(int proxyPort)
+int dbgcomm_connect_to_proxy(int proxyId)
 {
 	int			sockfd;
 	struct sockaddr_in   remoteaddr = {0};
@@ -217,12 +218,12 @@ dbgcomm_connect_to_proxy(int proxyPort)
 	}
 	dbgcomm_slots[slot].port = ntohs(localaddr.sin_port);
 	dbgcomm_slots[slot].status = DBGCOMM_CONNECTING_TO_PROXY;
-	dbgcomm_slots[slot].backendid = MyBackendId;
-	dbgcomm_slots[slot].pid = MyProcPid;
+    dbgcomm_slots[slot].proxyId = slot;
+    dbgcomm_slots[slot].sessionId = MY_SESS_ID;
 	LWLockRelease(getPLDebuggerLock());
 
 	remoteaddr.sin_family 	   = AF_INET;
-	remoteaddr.sin_port        = htons(proxyPort);
+    remoteaddr.sin_port        = htons(proxyId);
 	remoteaddr.sin_addr.s_addr = resolveHostName( "127.0.0.1" );
 
 	/* Now connect to the other end. */
@@ -231,14 +232,14 @@ dbgcomm_connect_to_proxy(int proxyPort)
 	{
 		ereport(COMMERROR,
 				(errcode_for_socket_access(),
-				 errmsg("could not connect to debugging proxy at port %d: %m", proxyPort)));
+                errmsg("could not connect to debugging proxy Id: %d", proxyId)));
 		/*
 		 * Reset our entry in the array. On success, this will be done by
 		 * the proxy.
 		 */
 		LWLockAcquire(getPLDebuggerLock(), LW_EXCLUSIVE);
 		dbgcomm_slots[slot].status = DBGCOMM_IDLE;
-		dbgcomm_slots[slot].backendid = InvalidBackendId;
+        dbgcomm_slots[slot].proxyId = -1;
 		dbgcomm_slots[slot].port = 0;
 		LWLockRelease(getPLDebuggerLock());
 		return -1;
@@ -321,12 +322,12 @@ dbgcomm_listen_for_proxy(void)
 	}
 	dbgcomm_slots[slot].port = localport;
 	dbgcomm_slots[slot].status = DBGCOMM_LISTENING_FOR_PROXY;
-	dbgcomm_slots[slot].backendid = MyBackendId;
-	dbgcomm_slots[slot].pid = MyProcPid;
+    dbgcomm_slots[slot].proxyId = slot;
+    dbgcomm_slots[slot].sessionId = MY_SESS_ID;
 	LWLockRelease(getPLDebuggerLock());
 
 	/* Notify the client application that this backend is waiting for a proxy. */
-	elog(NOTICE, "PLDBGBREAK:%d", MyBackendId);
+    elog(NOTICE, "YOUR PROXY PORT ID IS:%d", slot);
 
 	/* wait for the other end to connect to us */
 	done = false;
@@ -345,7 +346,7 @@ dbgcomm_listen_for_proxy(void)
 		if (dbgcomm_slots[slot].status == DBGCOMM_PROXY_CONNECTING &&
 			dbgcomm_slots[slot].port == ntohs(remoteaddr.sin_port))
 		{
-			dbgcomm_slots[slot].backendid = InvalidBackendId;
+            dbgcomm_slots[slot].proxyId = -1;
 			dbgcomm_slots[slot].status = DBGCOMM_IDLE;
 			done = true;
 		}
@@ -369,8 +370,7 @@ dbgcomm_listen_for_proxy(void)
  * Connect to given target backend that's waiting for us. Returns a socket
  * that is open for communication. Uses ereport(ERROR) on error.
  */
-int
-dbgcomm_connect_to_target(BackendId targetBackend)
+int dbgcomm_connect_to_target(int targetProxyId)
 {
 	int			sockfd;
 	struct sockaddr_in   remoteaddr = {0};
@@ -422,9 +422,12 @@ dbgcomm_connect_to_target(BackendId targetBackend)
 	 * let it know we're connecting to it from this port.
 	 */
 	LWLockAcquire(getPLDebuggerLock(), LW_EXCLUSIVE);
-	slot = findTargetSlot(targetBackend);
-	if (slot < 0 || dbgcomm_slots[slot].status != DBGCOMM_LISTENING_FOR_PROXY)
-	{
+    slot = findTargetSlot(targetProxyId);
+    if (slot < 0 || dbgcomm_slots[slot].status != DBGCOMM_LISTENING_FOR_PROXY) {
+        closesocket(sockfd);
+        ereport(ERROR, (errmsg("target backend is not listening for a connection")));
+    }
+    if (dbgcomm_slots[slot].userid != GetUserId() && !superuser()) {
 		closesocket(sockfd);
 		ereport(ERROR,
 				(errmsg("target backend is not listening for a connection")));
@@ -455,8 +458,7 @@ dbgcomm_connect_to_target(BackendId targetBackend)
  * Waits for one connection from a target backend to the given socket. Returns
  * a socket that is open for communication. Uses ereport(ERROR) on error.
  */
-int
-dbgcomm_accept_target(int sockfd, int *targetPid)
+int dbgcomm_accept_target(int sockfd, uint64* targetSessId)
 {
 	int			serverSocket;
 	int			i;
@@ -523,7 +525,7 @@ dbgcomm_accept_target(int sockfd, int *targetPid)
 			if (dbgcomm_slots[i].status == DBGCOMM_CONNECTING_TO_PROXY &&
 				dbgcomm_slots[i].port == ntohs(remoteaddr.sin_port))
 			{
-				*targetPid = dbgcomm_slots[i].pid;
+                *targetSessId = dbgcomm_slots[i].sessionId;
 				dbgcomm_slots[i].status = DBGCOMM_IDLE;
 				break;
 			}
@@ -615,16 +617,14 @@ findFreeTargetSlot(void)
 
 	for (i = 0; i < NumTargetSlots; i++)
 	{
-		if (dbgcomm_slots[i].backendid == InvalidBackendId)
+        if (dbgcomm_slots[i].proxyId == -1)
 			return i;
-		if (dbgcomm_slots[i].backendid == MyBackendId)
-		{
+        if (dbgcomm_slots[i].sessionId == MY_SESS_ID) {
 			/*
 			 * If we've failed to deallocate our slot earlier, reuse this slot.
 			 * This shouldn't happen.
 			 */
-			elog(LOG, "found leftover debugging target slot for backend %d",
-				 MyBackendId);
+            elog(LOG, "found leftover debugging target slot for session %ld", MY_SESS_ID);
 			return i;
 		}
 	}
@@ -637,14 +637,13 @@ findFreeTargetSlot(void)
  *
  * Note: Caller must be holding the lock.
  */
-static int
-findTargetSlot(BackendId backendid)
+static int findTargetSlot(int proxyId)
 {
 	int		i;
 
 	for (i = 0; i < NumTargetSlots; i++)
 	{
-		if (dbgcomm_slots[i].backendid == backendid)
+        if (dbgcomm_slots[i].proxyId == proxyId)
 			return i;
 	}
 	return -1;
@@ -674,7 +673,7 @@ static uint32 resolveHostName( const char * hostName )
     else
 		hostAddress = inet_addr( hostName );
 
-    if(( hostAddress == -1 ) || ( hostAddress == INADDR_NONE ))
+    if(( hostAddress == (uint32)(-1) ) || ( hostAddress == INADDR_NONE ))
 		return( 0 );
 	else
 		return( hostAddress );
diff --git a/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/dbgcomm.h b/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/dbgcomm.h
index 3503c4a..333f4b2 100644
--- a/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/dbgcomm.h
+++ b/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/dbgcomm.h
@@ -9,17 +9,22 @@
  * Licensed under the Artistic License, see 
  *		http://www.opensource.org/licenses/artistic-license.php
  * for full details
+ *
+ * --------------------------------------------------------------------
+ * OpenGauss Modification:
+ *     We have changed the name and type of several function parameters of 'dbgcomm_target_slot_t' struct.
+ *
  */
 #ifndef DBGCOMM_H
 #define DBGCOMM_H
 
 extern void dbgcomm_reserve(void);
 
-extern int dbgcomm_connect_to_proxy(int proxyPort);
+extern int dbgcomm_connect_to_proxy(int proxyId);
 extern int dbgcomm_listen_for_proxy(void);
 
 extern int dbgcomm_listen_for_target(int *port);
-extern int dbgcomm_accept_target(int sockfd, int *targetPid);
-extern int dbgcomm_connect_to_target(BackendId targetBackend);
+extern int dbgcomm_accept_target(int sockfd, uint64* targetSessId);
+extern int dbgcomm_connect_to_target(int targetProxyId);
 
 #endif
diff --git a/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/globalbp.h b/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/globalbp.h
index eecd011..613cae2 100644
--- a/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/globalbp.h
+++ b/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/globalbp.h
@@ -9,6 +9,12 @@
  * Licensed under the Artistic License, see 
  *		http://www.opensource.org/licenses/artistic-license.php
  * for full details
+ *
+ * -----------------------------------------------------------------------------
+ * OpenGauss Modifications:
+ *     We changed the name and type of var 'targetPid' of struct BreakpointKey,
+ *     to adapt to openGauss thread pool mode.
+ *
  */
 #ifndef GLOBALBP_H
 #define GLOBALBP_H
@@ -18,7 +24,7 @@
 typedef enum
 {
 	BP_LOCAL = 0,
-	BP_GLOBAL
+	BP_GLOBAL              /* be removed. */
 } eBreakpointScope;
 
 /* 
@@ -41,7 +47,7 @@ typedef struct BreakpointKey
 	Oid			databaseId;
 	Oid			functionId;
 	int			lineNumber;
-	int			targetPid;		/* -1 means any process */
+    uint64 targetSessId;   /* uint64(-1) means any process */
 } BreakpointKey;
 
 typedef struct Breakpoint
diff --git a/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/pldbgapi--1.0.sql b/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/pldbgapi--1.0.sql
index 5095845..46b844b 100644
--- a/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/pldbgapi--1.0.sql
+++ b/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/pldbgapi--1.0.sql
@@ -6,6 +6,13 @@
 -- Licensed under the Artistic License, see 
 --		http://www.opensource.org/licenses/artistic-license.php
 -- for full details
+--
+-- OpenGauss Modification:
+--    We have made the following modifications on the source code to adapt to openGauss:
+--    add        pldbg_on, pldbg_off
+--    rewrite    pldbg_get_source
+--    remove     pldbg_create_listener, pldbg_deposit_value, pldbg_get_target_info, pldbg_select_frame,
+--               pldbg_set_global_breakpoint, pldbg_wait_for_breakpoint, pldbg_wait_for_target
 
 \echo Installing pldebugger as unpackaged objects. If you are using PostgreSQL
 \echo version 9.1 or above, use "CREATE EXTENSION pldbgapi" instead.
@@ -14,8 +21,10 @@ CREATE TYPE breakpoint AS ( func OID, linenumber INTEGER, targetName TEXT );
 CREATE TYPE frame      AS ( level INT, targetname TEXT, func OID, linenumber INTEGER, args TEXT );
 
 CREATE TYPE var		   AS ( name TEXT, varClass char, lineNumber INTEGER, isUnique bool, isConst bool, isNotNull bool, dtype OID, value TEXT );
-CREATE TYPE proxyInfo  AS ( serverVersionStr TEXT, serverVersionNum INT, proxyAPIVer INT, serverProcessID INT );
+CREATE TYPE proxyInfo AS ( serverVersionStr TEXT, serverVersionNum INT, proxyAPIVer INT, serverProcessID BIGINT );
 
+CREATE FUNCTION pldbg_on() RETURNS boolean AS '$libdir/plugin_debugger' LANGUAGE C STRICT;
+CREATE FUNCTION pldbg_off() RETURNS boolean AS '$libdir/plugin_debugger' LANGUAGE C STRICT;
 CREATE FUNCTION pldbg_oid_debug( functionOID OID ) RETURNS INTEGER AS '$libdir/plugin_debugger' LANGUAGE C STRICT;
 
 -- for backwards-compatibility
@@ -24,21 +33,15 @@ CREATE FUNCTION plpgsql_oid_debug( functionOID OID ) RETURNS INTEGER AS $$ SELEC
 CREATE FUNCTION pldbg_abort_target( session INTEGER ) RETURNS SETOF boolean AS  '$libdir/plugin_debugger' LANGUAGE C STRICT;
 CREATE FUNCTION pldbg_attach_to_port( portNumber INTEGER ) RETURNS INTEGER AS '$libdir/plugin_debugger' LANGUAGE C STRICT;
 CREATE FUNCTION pldbg_continue( session INTEGER ) RETURNS breakpoint AS '$libdir/plugin_debugger' LANGUAGE C STRICT;
-CREATE FUNCTION pldbg_create_listener() RETURNS INTEGER AS '$libdir/plugin_debugger' LANGUAGE C STRICT;
-CREATE FUNCTION pldbg_deposit_value( session INTEGER, varName TEXT, lineNumber INTEGER, value TEXT ) RETURNS boolean AS  '$libdir/plugin_debugger' LANGUAGE C STRICT;
 CREATE FUNCTION pldbg_drop_breakpoint( session INTEGER, func OID, linenumber INTEGER ) RETURNS boolean AS  '$libdir/plugin_debugger' LANGUAGE C STRICT;
 CREATE FUNCTION pldbg_get_breakpoints( session INTEGER ) RETURNS SETOF breakpoint AS '$libdir/plugin_debugger' LANGUAGE C STRICT;
-CREATE FUNCTION pldbg_get_source( session INTEGER, func OID ) RETURNS TEXT AS '$libdir/plugin_debugger' LANGUAGE C STRICT;
+CREATE FUNCTION pldbg_get_source( func OID ) RETURNS TEXT AS 'SELECT prosrc from pg_proc where oid=($1)' LANGUAGE SQL;
 CREATE FUNCTION pldbg_get_stack( session INTEGER ) RETURNS SETOF frame AS '$libdir/plugin_debugger' LANGUAGE C STRICT;
 CREATE FUNCTION pldbg_get_proxy_info( ) RETURNS proxyInfo AS '$libdir/plugin_debugger' LANGUAGE C STRICT;
 CREATE FUNCTION pldbg_get_variables( session INTEGER ) RETURNS SETOF var AS '$libdir/plugin_debugger' LANGUAGE C STRICT;
-CREATE FUNCTION pldbg_select_frame( session INTEGER, frame INTEGER ) RETURNS breakpoint AS '$libdir/plugin_debugger' LANGUAGE C STRICT;
 CREATE FUNCTION pldbg_set_breakpoint( session INTEGER, func OID, linenumber INTEGER ) RETURNS boolean AS  '$libdir/plugin_debugger' LANGUAGE C STRICT;
-CREATE FUNCTION pldbg_set_global_breakpoint( session INTEGER, func OID, linenumber INTEGER, targetPID INTEGER ) RETURNS boolean AS  '$libdir/plugin_debugger' LANGUAGE C;
 CREATE FUNCTION pldbg_step_into( session INTEGER ) RETURNS breakpoint AS '$libdir/plugin_debugger' LANGUAGE C STRICT;
 CREATE FUNCTION pldbg_step_over( session INTEGER ) RETURNS breakpoint AS '$libdir/plugin_debugger' LANGUAGE C STRICT;
-CREATE FUNCTION pldbg_wait_for_breakpoint( session INTEGER ) RETURNS breakpoint  AS '$libdir/plugin_debugger' LANGUAGE C STRICT;
-CREATE FUNCTION pldbg_wait_for_target( session INTEGER ) RETURNS INTEGER AS '$libdir/plugin_debugger' LANGUAGE C STRICT;
 
 /*
  * pldbg_get_target_info() function can be used to return information about
@@ -68,88 +71,3 @@ CREATE TYPE targetinfo AS ( target OID, schema OID, nargs INT, argTypes oidvecto
   argDefVals TEXT[]
 );
 
--- Create the pldbg_get_target_info() function. We use an inline code block
--- so that we can check and create it slightly differently if running on
--- an EnterpriseDB server.
-
-DO $do$
-
-declare
-  isedb bool;
-  createstmt text;
-begin
-
-  isedb = (SELECT version() LIKE 'EnterpriseDB%');
-
-  createstmt := $create_stmt$
-
-CREATE FUNCTION pldbg_get_target_info(signature text, targetType "char") returns targetinfo AS $$
-  SELECT p.oid AS target,
-         pronamespace AS schema,
-         pronargs::int4 AS nargs,
-         -- The returned argtypes column is of type oidvector, but unlike
-         -- proargtypes, it's supposed to include OUT params. So we
-         -- essentially have to return proallargtypes, converted to an
-         -- oidvector. There is no oid[] -> oidvector cast, so we have to
-         -- do it via text.
-         CASE WHEN proallargtypes IS NOT NULL THEN
-           translate(proallargtypes::text, ',{}', ' ')::oidvector
-         ELSE
-           proargtypes
-         END AS argtypes,
-         proname AS targetname,
-         proargmodes AS argmodes,
-         proargnames AS proargnames,
-         prolang AS targetlang,
-         quote_ident(nspname) || '.' || quote_ident(proname) AS fqname,
-         proretset AS returnsset,
-         prorettype AS returntype,
-$create_stmt$;
-
--- Add the three EDB-columns to the query (as dummies if we're installing
--- to PostgreSQL)
-IF isedb THEN
-  createstmt := createstmt ||
-$create_stmt$
-         p.protype='0' AS isfunc,
-         CASE WHEN n.nspparent <> 0 THEN n.oid ELSE 0 END AS pkg,
-	 edb_get_func_defvals(p.oid) AS argdefvals
-$create_stmt$;
-ELSE
-  createstmt := createstmt ||
-$create_stmt$
-         't'::bool AS isfunc,
-         0::oid AS pkg,
-	 NULL::text[] AS argdefvals
-$create_stmt$;
-END IF;
-  -- End of conditional part
-
-  createstmt := createstmt ||
-$create_stmt$
-  FROM pg_proc p, pg_namespace n
-  WHERE p.pronamespace = n.oid
-  AND p.oid = $1::oid
-  -- We used to support querying by function name or trigger name/oid as well,
-  -- but that was never used in the client, so the support for that has been
-  -- removed. The targeType argument remains as a legacy of that. You're
-  -- expected to pass 'o' as target type, but it doesn't do anything.
-  AND $2 = 'o'
-$$ LANGUAGE SQL;
-$create_stmt$;
-
-  execute createstmt;
-
--- Add a couple of EDB specific functions
-IF isedb THEN
-   CREATE FUNCTION edb_oid_debug(functionOID oid) RETURNS integer AS $$
-     select pldbg_oid_debug($1);
-   $$ LANGUAGE SQL;
-
-   CREATE FUNCTION pldbg_get_pkg_cons(packageOID oid) RETURNS oid AS $$
-     select oid from pg_proc where pronamespace=$1 and proname='cons';
-   $$ LANGUAGE SQL;
-END IF;
-
-end;
-$do$;
diff --git a/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/pldbgapi--unpackaged--1.0.sql b/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/pldbgapi--unpackaged--1.0.sql
index 21d32df..a195443 100644
--- a/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/pldbgapi--unpackaged--1.0.sql
+++ b/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/pldbgapi--unpackaged--1.0.sql
@@ -6,40 +6,20 @@ ALTER EXTENSION pldbgapi ADD TYPE targetinfo;
 ALTER EXTENSION pldbgapi ADD TYPE var;
 ALTER EXTENSION pldbgapi ADD TYPE proxyInfo;
 
+ALTER EXTENSION pldbgapi ADD FUNCTION plpgsql_on();
+ALTER EXTENSION pldbgapi ADD FUNCTION plpgsql_off();
 ALTER EXTENSION pldbgapi ADD FUNCTION plpgsql_oid_debug( functionOID OID );
 
 ALTER EXTENSION pldbgapi ADD FUNCTION pldbg_abort_target( session INTEGER );
 ALTER EXTENSION pldbgapi ADD FUNCTION pldbg_attach_to_port( portNumber INTEGER );
 ALTER EXTENSION pldbgapi ADD FUNCTION pldbg_continue( session INTEGER );
-ALTER EXTENSION pldbgapi ADD FUNCTION pldbg_create_listener();
-ALTER EXTENSION pldbgapi ADD FUNCTION pldbg_deposit_value( session INTEGER, varName TEXT, lineNumber INTEGER, value TEXT );
 ALTER EXTENSION pldbgapi ADD FUNCTION pldbg_drop_breakpoint( session INTEGER, func OID, linenumber INTEGER );
 ALTER EXTENSION pldbgapi ADD FUNCTION pldbg_get_breakpoints( session INTEGER );
-ALTER EXTENSION pldbgapi ADD FUNCTION pldbg_get_source( session INTEGER, func OID );
+ALTER EXTENSION pldbgapi ADD FUNCTION pldbg_get_source( func OID );
 ALTER EXTENSION pldbgapi ADD FUNCTION pldbg_get_stack( session INTEGER );
 ALTER EXTENSION pldbgapi ADD FUNCTION pldbg_get_proxy_info( );
 ALTER EXTENSION pldbgapi ADD FUNCTION pldbg_get_variables( session INTEGER );
-ALTER EXTENSION pldbgapi ADD FUNCTION pldbg_select_frame( session INTEGER, frame INTEGER );
 ALTER EXTENSION pldbgapi ADD FUNCTION pldbg_set_breakpoint( session INTEGER, func OID, linenumber INTEGER );
-ALTER EXTENSION pldbgapi ADD FUNCTION pldbg_set_global_breakpoint( session INTEGER, func OID, linenumber INTEGER, targetPID INTEGER );
 ALTER EXTENSION pldbgapi ADD FUNCTION pldbg_step_into( session INTEGER );
 ALTER EXTENSION pldbgapi ADD FUNCTION pldbg_step_over( session INTEGER );
-ALTER EXTENSION pldbgapi ADD FUNCTION pldbg_wait_for_breakpoint( session INTEGER );
-ALTER EXTENSION pldbgapi ADD FUNCTION pldbg_wait_for_target( session INTEGER );
-ALTER EXTENSION pldbgapi ADD FUNCTION pldbg_get_target_info( signature TEXT, targetType "char" );
 
-DO $do$
-
-declare
-  isedb bool;
-begin
-
-  isedb = (SELECT version() LIKE 'EnterpriseDB%');
-
-  -- Add a couple of EDB specific functions
-  IF isedb THEN
-    ALTER EXTENSION pldbgapi ADD edb_oid_debug( functionOID oid );
-    ALTER EXTENSION pldbgapi ADD pldbg_get_pkg_cons( packageOID oid );
-  END IF;
-
-$do$;
diff --git a/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/pldbgapi.cpp b/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/pldbgapi.cpp
index 0958779..a4627d9 100644
--- a/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/pldbgapi.cpp
+++ b/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/pldbgapi.cpp
@@ -86,6 +86,12 @@
  * Licensed under the Artistic License, see 
  *		http://www.opensource.org/licenses/artistic-license.php
  * for full details
+ *
+ * ----------------------------------------------------------------------------
+ * OpenGauss Modifications:
+ *     For a better system performance, we add two APIs, pldbg_on() and pldbg_off(), to start up or shut down PLDEBUGGER.
+ *     Some of the original APIs are reserved but not used in debugging process. For details, please see 
+ *     file pldbgapi--1.0.sql.
  */
 
 #include "postgres.h"
@@ -106,10 +112,10 @@
 #include <unistd.h>							/* For close()					*/
 #include <sys/socket.h>
 #include <netinet/in.h>
-#include <arpa/inet.h>
 
 #include "globalbp.h"
 #include "dbgcomm.h"
+#include "pldebugger.h"
 
 /* Include header for GETSTRUCT */
 #if (PG_VERSION_NUM >= 90300)
@@ -128,9 +134,10 @@ PG_MODULE_MAGIC;
 /*******************************************************************************
  * Proxy functions
  *******************************************************************************/
+PG_FUNCTION_INFO_V1( pldbg_on );					/* start pldebugger, init debug context			*/
+PG_FUNCTION_INFO_V1( pldbg_off );					/* close pldebugger, clear debug context		*/
 
 PG_FUNCTION_INFO_V1( pldbg_attach_to_port );		/* Attach to debugger server at the given port	*/
-PG_FUNCTION_INFO_V1( pldbg_wait_for_breakpoint );  	/* Wait for the target to reach a breakpoint	*/
 PG_FUNCTION_INFO_V1( pldbg_step_into );				/* Steop into a function/procedure call			*/
 PG_FUNCTION_INFO_V1( pldbg_step_over );				/* Step over a function/procedure call			*/
 PG_FUNCTION_INFO_V1( pldbg_continue );				/* Continue execution until next breakpoint		*/
@@ -140,75 +147,32 @@ PG_FUNCTION_INFO_V1( pldbg_get_variables );			/* Get a list of variable names/ty
 PG_FUNCTION_INFO_V1( pldbg_get_stack );				/* Get the call stack from the target			*/
 PG_FUNCTION_INFO_V1( pldbg_set_breakpoint );		/* CREATE BREAKPOINT equivalent (deprecated)	*/
 PG_FUNCTION_INFO_V1( pldbg_drop_breakpoint );		/* DROP BREAKPOINT equivalent (deprecated)		*/
-PG_FUNCTION_INFO_V1( pldbg_select_frame );			/* Change the focus to a different stack frame	*/
-PG_FUNCTION_INFO_V1( pldbg_deposit_value );		 	/* Change the value of an in-scope variable		*/
 PG_FUNCTION_INFO_V1( pldbg_abort_target );			/* Abort execution of the target - throws error */
 PG_FUNCTION_INFO_V1( pldbg_get_proxy_info );		/* Get server version, proxy API version, ...   */
 
 PG_FUNCTION_INFO_V1( pldbg_create_listener );		/* Create a listener for global breakpoints		*/
 PG_FUNCTION_INFO_V1( pldbg_wait_for_target );		/* Wait for a global breakpoint to fire			*/
 PG_FUNCTION_INFO_V1( pldbg_set_global_breakpoint );	/* Create a global breakpoint					*/
-
-/*******************************************************************************
- * Structure debugSession
- *
- *	A debugger client may attach to many target sessions at the same time. We
- *	keep track of each connection in a debugSession structure. When the client
- *	makes a connection, we allocate a new debugSession structure and return 
- *	a handle to that structure to the caller.  He gives us back the handle 
- *	whenever he calls another proxy function. A handle is just a smallish 
- *  integer value that we use to track each session - we use a hash to map
- *  handles into debugSession pointers.
- */
-
-typedef struct
-{
-	int			serverSocket;	/* Socket connected to the debugger server */
-	int			serverPort;		/* Port number where debugger server is listening */
-	int			listener;		/* Socket where we wait for global breakpoints */
-	char	   *breakpointString;
-} debugSession;
-
-/*******************************************************************************
- * Stucture sessionHashEntry
- *
- *	As mentioned above (see debugSession), a debugger proxy can manage many
- *	debug sessions at once.  To keep track of each session, we create a
- *	debugSession object and return a handle to that object to the caller.  The
- *	handle is an opaque value - it's just an integer value.  To convert a
- *	handle into an actual debugSession pointer, we create a hash that maps
- *	handles into debugSession pointers.
- *
- *  Each member of the hash is shaped like a sessionHashEntry object.
- */
-typedef int32  sessionHandle;
-
-typedef struct
-{
-	sessionHandle	m_handle;
-	debugSession   *m_session;
-} sessionHashEntry;
-
-static debugSession * mostRecentSession;
-static HTAB			* sessionHash;
+PG_FUNCTION_INFO_V1( pldbg_wait_for_breakpoint );  	/* Wait for the target to reach a breakpoint	*/
+PG_FUNCTION_INFO_V1( pldbg_deposit_value );		 	/* Change the value of an in-scope variable		*/
+PG_FUNCTION_INFO_V1( pldbg_select_frame );			/* Change the focus to a different stack frame	*/
 
 /*******************************************************************************
  * The following symbols represent the magic strings that we send to the 
  * debugger server running in the target process
  */
-
-#define PLDBG_GET_VARIABLES		"i\n"
-#define PLDBG_GET_BREAKPOINTS 	"l\n"
-#define PLDBG_GET_STACK       	"$\n"
-#define PLDBG_STEP_INTO			"s\n"
-#define PLDBG_STEP_OVER			"o\n"
-#define PLDBG_CONTINUE			"c\n"
-#define PLDBG_ABORT				"x"			
-#define PLDBG_SELECT_FRAME		"^"			/* Followed by frame number 				*/
-#define PLDBG_SET_BREAKPOINT		"b"			/* Followed by pkgoid:funcoid:linenumber 	*/
-#define PLDBG_CLEAR_BREAKPOINT	"f"			/* Followed by pkgoid:funcoid:linenumber 	*/
-#define PLDBG_GET_SOURCE			"#" 		/* Followed by pkgoid:funcoid				*/
-#define PLDBG_DEPOSIT				"d"			/* Followed by var.line=value				*/
+#define PLDBGAPI_GET_VARIABLES		"i\n"
+#define PLDBGAPI_GET_BREAKPOINTS 	"l\n"
+#define PLDBGAPI_GET_STACK       	"$\n"
+#define PLDBGAPI_STEP_INTO		"s\n"
+#define PLDBGAPI_STEP_OVER		"o\n"
+#define PLDBGAPI_CONTINUE		"c\n"
+#define PLDBGAPI_ABORT			"x"			
+#define PLDBGAPI_SELECT_FRAME		"^"			/* Followed by frame number 				*/
+#define PLDBGAPI_SET_BREAKPOINT		"b"			/* Followed by pkgoid:funcoid:linenumber 	*/
+#define PLDBGAPI_CLEAR_BREAKPOINT	"f"			/* Followed by pkgoid:funcoid:linenumber 	*/
+#define PLDBGAPI_GET_SOURCE		"#"	 		/* Followed by pkgoid:funcoid				*/
+#define PLDBGAPI_DEPOSIT		"d"			/* Followed by var.line=value				*/
 
 #define PROXY_API_VERSION		3			/* API version number						*/
 
@@ -224,27 +188,30 @@ static HTAB			* sessionHash;
 #define GET_STR( textp ) 		DatumGetCString( DirectFunctionCall1( textout, PointerGetDatum( textp )))
 #define PG_GETARG_SESSION( n )  (sessionHandle)PG_GETARG_UINT32( n )
 
-Datum pldbg_select_frame( PG_FUNCTION_ARGS );
-Datum pldbg_attach_to_port( PG_FUNCTION_ARGS );
-Datum pldbg_get_source( PG_FUNCTION_ARGS );
-Datum pldbg_get_breakpoints( PG_FUNCTION_ARGS );
-Datum pldbg_get_variables( PG_FUNCTION_ARGS );
-Datum pldbg_get_stack( PG_FUNCTION_ARGS );
-Datum pldbg_wait_for_breakpoint( PG_FUNCTION_ARGS );
-Datum pldbg_set_breakpoint( PG_FUNCTION_ARGS );
-Datum pldbg_drop_breakpoint( PG_FUNCTION_ARGS );
-Datum pldbg_step_into( PG_FUNCTION_ARGS );
-Datum pldbg_step_over( PG_FUNCTION_ARGS );
-Datum pldbg_continue(  PG_FUNCTION_ARGS );
-Datum pldbg_deposit_value( PG_FUNCTION_ARGS );
-Datum pldbg_get_proxy_info( PG_FUNCTION_ARGS );
-Datum pldbg_get_pkg_cons( PG_FUNCTION_ARGS );
-Datum pldbg_abort_target( PG_FUNCTION_ARGS );
-
-Datum pldbg_create_listener( PG_FUNCTION_ARGS );
-Datum pldbg_wait_for_target( PG_FUNCTION_ARGS );
-Datum pldbg_set_global_breakpoint( PG_FUNCTION_ARGS );
 
+extern "C" Datum pldbg_on( PG_FUNCTION_ARGS );
+extern "C" Datum pldbg_off( PG_FUNCTION_ARGS );
+extern "C" Datum pldbg_attach_to_port( PG_FUNCTION_ARGS );
+extern "C" Datum pldbg_get_source( PG_FUNCTION_ARGS );
+extern "C" Datum pldbg_get_breakpoints( PG_FUNCTION_ARGS );
+extern "C" Datum pldbg_get_variables( PG_FUNCTION_ARGS );
+extern "C" Datum pldbg_get_stack( PG_FUNCTION_ARGS );
+extern "C" Datum pldbg_set_breakpoint( PG_FUNCTION_ARGS );
+extern "C" Datum pldbg_drop_breakpoint( PG_FUNCTION_ARGS );
+extern "C" Datum pldbg_step_into( PG_FUNCTION_ARGS );
+extern "C" Datum pldbg_step_over( PG_FUNCTION_ARGS );
+extern "C" Datum pldbg_continue(  PG_FUNCTION_ARGS );
+extern "C" Datum pldbg_get_proxy_info( PG_FUNCTION_ARGS );
+extern "C" Datum pldbg_abort_target( PG_FUNCTION_ARGS );
+
+extern "C" Datum pldbg_create_listener( PG_FUNCTION_ARGS );
+extern "C" Datum pldbg_wait_for_target( PG_FUNCTION_ARGS );
+extern "C" Datum pldbg_set_global_breakpoint( PG_FUNCTION_ARGS );
+extern "C" Datum pldbg_select_frame( PG_FUNCTION_ARGS );
+extern "C" Datum pldbg_wait_for_breakpoint( PG_FUNCTION_ARGS );
+extern "C" Datum pldbg_deposit_value( PG_FUNCTION_ARGS );
+
+Datum pldbg_get_pkg_cons(PG_FUNCTION_ARGS);
 /************************************************************
  * Local function forward declarations
  ************************************************************/
@@ -253,22 +220,60 @@ static void 		   * readn( int serverHandle, void * dst, size_t len );
 static void 		   * writen( int serverHandle, void * dst, size_t len );
 static void   		  	 sendBytes( debugSession * session, void * src, size_t len );
 static void   		  	 sendUInt32( debugSession * session, uint32 val );
-static void   		  	 sendString( debugSession * session, char * src );
+void   		  	 sendString( debugSession * session, char * src );
 static bool   		  	 getBool( debugSession * session );
 static uint32 		  	 getUInt32( debugSession * session );
 static char 		   * getNString( debugSession * session );
-static void 		  	 initializeModule( void );
+void 		  	 registCallbackInSessExit( void );
 static void 		  	 cleanupAtExit( int code, Datum arg );
-static void 			 initSessionHash();
 static debugSession    * defaultSession( sessionHandle handle );
 static sessionHandle     addSession( debugSession * session );
 static debugSession    * findSession( sessionHandle handle );
 static TupleDesc	  	 getResultTupleDesc( FunctionCallInfo fcinfo );
-
+void clearSocketContent(debugSession* session);
 
 /*******************************************************************************
  * Exported functions
  *******************************************************************************/
+/*******************************************************************************
+ * pldbg_on, pldbg_off
+ * start up or close the pldebugger on the target session, so we can attach the breakpoint and start debugging process.
+ *
+ * pldbg_on() is the API to start the pldebugger, it can be manually called and will also auto loaded through other APIs
+ *
+ * function added by openGauss
+ */
+Datum pldbg_on(PG_FUNCTION_ARGS)
+{
+    if (IS_PLDEBUGGER_ON) {
+        ereport(NOTICE, (errmsg("pldebugger is alreadly on.")));
+        PG_RETURN_BOOL(true);
+    }
+    init_pldebugger_role(PLDBG_SERVER);
+    PG_RETURN_BOOL(true);
+}
+
+/*
+ * pldbg_off() is the API to shut down the pldebuggre, it will be triggered when the session exits, or the pldebugger
+ * will keep running during the active session, which is not good for the proformance. So it is better to manually call
+ * pldbg_off() when debugger is not used.
+ *
+ * function added by openGauss
+ */
+Datum pldbg_off(PG_FUNCTION_ARGS)
+{
+    if (!IS_PLDEBUGGER_ON) {
+        ereport(NOTICE, (errmsg("pldebugger server or client is not on.")));
+        PG_RETURN_BOOL(true);
+    }
+    if (IS_PLDEBUGGER_SERVER) {
+        pldbg_server_shutdown();
+    } else if (IS_PLDEBUGGER_CLIENT) {
+        pldbg_client_shutdown();
+    }
+    destroy_pldebugger_context();
+    PG_RETURN_BOOL(true);
+}
 
 /*******************************************************************************
  * pldbg_attach_to_port( portNumber INTEGER ) RETURNS INTEGER
@@ -288,13 +293,16 @@ static TupleDesc	  	 getResultTupleDesc( FunctionCallInfo fcinfo );
 
 Datum pldbg_attach_to_port( PG_FUNCTION_ARGS )
 {
+	if (!IS_PLDEBUGGER_CLIENT) {
+		init_pldebugger_role(PLDBG_CLIENT);
+	}
+
 	int32		targetBackend = PG_GETARG_INT32( 0 );
 	debugSession *session;
 
-	initializeModule();
-
-	session = MemoryContextAllocZero( TopMemoryContext, sizeof( *session ));
+	session = (debugSession*)MemoryContextAllocZero( PldbgMemoryContext, sizeof( *session ));
 	session->listener   = -1;
+        session->state = DBG_SESS_ACTIVE;
 
 	session->serverSocket = dbgcomm_connect_to_target(targetBackend);
 
@@ -308,7 +316,7 @@ Datum pldbg_attach_to_port( PG_FUNCTION_ARGS )
 	 * the local breakpoint that it hit. Read it. We will hand it to the client
 	 * if it calls wait_for_breakpoint().
 	 */
-	session->breakpointString = MemoryContextStrdup(TopMemoryContext,
+	session->breakpointString = MemoryContextStrdup(PldbgMemoryContext,
 													getNString(session));
 
 	/*
@@ -323,12 +331,14 @@ Datum pldbg_attach_to_port( PG_FUNCTION_ARGS )
 
 Datum pldbg_create_listener( PG_FUNCTION_ARGS ) 
 {
-	debugSession * session = MemoryContextAllocZero( TopMemoryContext, sizeof( *session ));
-
-	initializeModule();
+    if (!IS_PLDEBUGGER_CLIENT) {
+		init_pldebugger_role(PLDBG_CLIENT);
+	}
+	debugSession * session = (debugSession*)MemoryContextAllocZero( PldbgMemoryContext, sizeof( *session ));
 
 	session->listener = dbgcomm_listen_for_target(&session->serverPort);
 	session->serverSocket = -1;
+	session->state = DBG_SESS_ACTIVE;
 
 	mostRecentSession = session;
 
@@ -354,15 +364,15 @@ Datum pldbg_wait_for_target( PG_FUNCTION_ARGS )
 {
 	debugSession *session = defaultSession(PG_GETARG_SESSION( 0 ));
 	int			serverSocket;
-	int			serverPID;
+    uint64         serverSessId;
 
 	/*
 	 * Now mark all of our global breakpoints as 'available' (that is, not
 	 * busy)
 	 */
-	BreakpointFreeSession( MyProc->pid );
+    BreakpointFreeSession(MY_SESS_ID);
 
-	serverSocket = dbgcomm_accept_target(session->listener, &serverPID);
+    serverSocket = dbgcomm_accept_target(session->listener, &serverSessId);
 	if (serverSocket < 0)
 		ereport(ERROR,
 				(errmsg("could not accept a connection from debugging target")));
@@ -374,10 +384,10 @@ Datum pldbg_wait_for_target( PG_FUNCTION_ARGS )
 	 * the local breakpoint that it hit. Read it. We will hand it to the client
 	 * if it calls wait_for_breakpoint().
 	 */
-	session->breakpointString = MemoryContextStrdup(TopMemoryContext,
+	session->breakpointString = MemoryContextStrdup(PldbgMemoryContext,
 													getNString(session));
 
-	PG_RETURN_UINT32( serverPID );
+    PG_RETURN_INT64(serverSessId);
 }
 
 /*******************************************************************************
@@ -402,7 +412,7 @@ Datum pldbg_set_global_breakpoint( PG_FUNCTION_ARGS )
 				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
 				 errmsg("given session is not a listener")));
 
-	breakpoint.key.databaseId = MyProc->databaseId;
+	breakpoint.key.databaseId = t_thrd.proc->databaseId;
 	breakpoint.key.functionId = PG_GETARG_OID( 1 );
 
 	if( PG_ARGISNULL( 2 ))
@@ -411,13 +421,13 @@ Datum pldbg_set_global_breakpoint( PG_FUNCTION_ARGS )
 		breakpoint.key.lineNumber = PG_GETARG_INT32( 2 );
 
 	if( PG_ARGISNULL( 3 ))
-		breakpoint.key.targetPid = -1;
+        breakpoint.key.targetSessId = -1;
 	else
-		breakpoint.key.targetPid  = PG_GETARG_INT32( 3 );
+        breakpoint.key.targetSessId  = PG_GETARG_INT32(3);
 
 	breakpoint.data.isTmp     = TRUE;
 	breakpoint.data.proxyPort = session->serverPort;
-	breakpoint.data.proxyPid  = MyProc->pid;
+    breakpoint.data.proxyPid  = MY_SESS_ID;
 
 	if( !BreakpointInsert( BP_GLOBAL, &breakpoint.key, &breakpoint.data ))
 		ereport(ERROR,
@@ -427,19 +437,6 @@ Datum pldbg_set_global_breakpoint( PG_FUNCTION_ARGS )
 	PG_RETURN_BOOL( true );
 }
 
-/*******************************************************************************
- * pldbg_wait_for_breakpoint( sessionID INTEGER ) RETURNS breakpoint
- *
- *	This function waits for the debug target to reach a breakpoint.  You should
- *	call this function immediately after pldbg_attach_to_port() returns a
- *	session ID.  pldbg_wait_for_breakpoint() is nearly identical to
- *	pldbg_step_into(), pldbg_step_over(), and pldbg_continue(), (they all wait
- *	for the target) but	this function does not send a command to the target
- *	first.
- *
- *	This function returns a tuple of type 'breakpoint' - such a tuple contains
- *	the function OID and line number where the target is currently stopped.
- */
 
 static Datum buildBreakpointDatum( char * breakpointString )
 {
@@ -457,6 +454,19 @@ static Datum buildBreakpointDatum( char * breakpointString )
 	return( HeapTupleGetDatum( result ));
 }
 
+/*******************************************************************************
+ * pldbg_wait_for_breakpoint( sessionID INTEGER ) RETURNS breakpoint
+ *
+ *	This function waits for the debug target to reach a breakpoint.  You should
+ *	call this function immediately after pldbg_attach_to_port() returns a
+ *	session ID.  pldbg_wait_for_breakpoint() is nearly identical to
+ *	pldbg_step_into(), pldbg_step_over(), and pldbg_continue(), (they all wait
+ *	for the target) but	this function does not send a command to the target
+ *	first.
+ *
+ *	This function returns a tuple of type 'breakpoint' - such a tuple contains
+ *	the function OID and line number where the target is currently stopped.
+ */
 Datum pldbg_wait_for_breakpoint( PG_FUNCTION_ARGS )
 {
 	debugSession * session           = defaultSession( PG_GETARG_SESSION( 0 ));
@@ -486,7 +496,7 @@ Datum pldbg_step_into( PG_FUNCTION_ARGS )
 {
 	debugSession * session = defaultSession( PG_GETARG_SESSION( 0 ));
 
-	sendString( session, PLDBG_STEP_INTO );
+	sendString( session, PLDBGAPI_STEP_INTO );
 
 	PG_RETURN_DATUM( buildBreakpointDatum( getNString( session )));
 }
@@ -508,7 +518,7 @@ Datum pldbg_step_over( PG_FUNCTION_ARGS )
 {
 	debugSession * session = defaultSession( PG_GETARG_SESSION( 0 ));
 
-	sendString( session, PLDBG_STEP_OVER );
+	sendString( session, PLDBGAPI_STEP_OVER );
 
 	PG_RETURN_DATUM( buildBreakpointDatum( getNString( session )));
 }
@@ -526,8 +536,9 @@ Datum pldbg_step_over( PG_FUNCTION_ARGS )
 Datum pldbg_continue( PG_FUNCTION_ARGS )
 {
 	debugSession * session = defaultSession( PG_GETARG_SESSION( 0 ));
-	
-	sendString( session, PLDBG_CONTINUE );
+
+	clearSocketContent(session);
+	sendString( session, PLDBGAPI_CONTINUE );
 
 	PG_RETURN_DATUM( buildBreakpointDatum( getNString( session )));
 }
@@ -542,10 +553,12 @@ Datum pldbg_continue( PG_FUNCTION_ARGS )
 Datum pldbg_abort_target( PG_FUNCTION_ARGS )
 {
 	debugSession * session = defaultSession( PG_GETARG_SESSION( 0 ));
-	
-	sendString( session, PLDBG_ABORT );
+	bool res;
 
-	PG_RETURN_BOOL( getBool( session ));
+	sendString( session, PLDBGAPI_ABORT );
+	res = getBool(session) ? true : getBool(session);  /* the first is breakpoint str, except the first command. */
+
+	PG_RETURN_BOOL(res);
 
 }
 
@@ -581,8 +594,10 @@ Datum pldbg_select_frame( PG_FUNCTION_ARGS )
 		char		   frameString[12];		/* sign, 10 digits, '\0' */
 		char         * resultString;
 		Datum		   result;
+        errno_t       rc;
 
-		sprintf( frameString, "%s %d", PLDBG_SELECT_FRAME, frameNumber );
+        rc = sprintf_s(frameString, 12, "%s %d", PLDBGAPI_SELECT_FRAME, frameNumber); // sizeof frameString.
+        securec_check_ss(rc, "\0", "\0");
 
 		sendString( session, frameString );
 
@@ -608,6 +623,11 @@ Datum pldbg_select_frame( PG_FUNCTION_ARGS )
  *  ensures that the source code that you get is the source code that the 
  *  target is executing.
  *
+ * OpenGauss Modifications:
+ *     This function is no longer used in openGauss, because it will cause some unexpected results, like 
+ *     if we pass in an OID that does not exist, server will throw an ERROR and then abort, so we
+ *     just do a 'get-source' action in client by a sql function 'select pg_proc' rewrited in pldbgapi--1.0.sql.
+ *
  */
 
 Datum pldbg_get_source( PG_FUNCTION_ARGS )
@@ -617,7 +637,8 @@ Datum pldbg_get_source( PG_FUNCTION_ARGS )
 	char		   sourceString[13];		/* 10 digits(oid) + space + 1 command + null terminator */
 	char		 * source;
 
-	sprintf( sourceString, "%s %d", PLDBG_GET_SOURCE, funcOID );
+    errno_t rc = sprintf_s(sourceString, 13, "%s %d", PLDBGAPI_GET_SOURCE, funcOID); // sizeof sourceString
+    securec_check_ss(rc, "\0", "\0");
 
 	sendString( session, sourceString );
 
@@ -654,7 +675,7 @@ Datum pldbg_get_breakpoints( PG_FUNCTION_ARGS )
 		srf->attinmeta = TupleDescGetAttInMetadata( RelationNameGetTupleDesc( TYPE_NAME_BREAKPOINT ));
 		MemoryContextSwitchTo( oldContext );
 
-		sendString( session, PLDBG_GET_BREAKPOINTS );
+		sendString( session, PLDBGAPI_GET_BREAKPOINTS );
 	}
 	else
 	{
@@ -706,7 +727,7 @@ Datum pldbg_get_variables( PG_FUNCTION_ARGS )
 		srf->attinmeta = TupleDescGetAttInMetadata( RelationNameGetTupleDesc( TYPE_NAME_VAR ));
 		MemoryContextSwitchTo( oldContext );
 
-		sendString( session, PLDBG_GET_VARIABLES );
+		sendString( session, PLDBGAPI_GET_VARIABLES );
 	}
 	else
 	{
@@ -769,7 +790,7 @@ Datum pldbg_get_stack( PG_FUNCTION_ARGS )
 		srf->attinmeta = TupleDescGetAttInMetadata( RelationNameGetTupleDesc( TYPE_NAME_FRAME ));
 		MemoryContextSwitchTo( oldContext );
 
-		sendString( session, PLDBG_GET_STACK );
+		sendString( session, PLDBGAPI_GET_STACK );
 	}
 	else
 	{
@@ -787,7 +808,8 @@ Datum pldbg_get_stack( PG_FUNCTION_ARGS )
 		 * frameString points to a string like:
 		 *	targetName:funcOID:lineNumber:arguments
 		 */
-		sprintf( callCount, "%d", srf->call_cntr );
+        errno_t rc = sprintf_s(callCount, 11, "%d", srf->call_cntr); /* size of callcount */
+        securec_check_ss(rc, "\0", "\0");
 
 		values[0] = callCount;
 		values[1] = tokenize( frameString, ":", &ctx );	/* targetName					*/
@@ -827,7 +849,7 @@ Datum pldbg_get_proxy_info( PG_FUNCTION_ARGS )
 	values[0] = DirectFunctionCall1( textin, PointerGetDatum( PG_VERSION_STR ));
 	values[1] = Int32GetDatum( PG_VERSION_NUM );
 	values[2] = Int32GetDatum( PROXY_API_VERSION );
-	values[3] = Int32GetDatum( MyProcPid );
+    values[3] = UInt64GetDatum(MY_SESS_ID);
 
 	result = heap_form_tuple( tupleDesc, values, nulls );
 
@@ -847,9 +869,11 @@ Datum pldbg_set_breakpoint( PG_FUNCTION_ARGS )
 	Oid			   funcOID    = PG_GETARG_OID( 1 );
 	int			   lineNumber = PG_GETARG_INT32( 2 );
 	char		   breakpointString[24];	/* 20 digits + 2 delimiters + 1 command + null terminator */
+    errno_t       rc;
 
-	sprintf( breakpointString, "%s %d:%d", PLDBG_SET_BREAKPOINT, funcOID, lineNumber );
-
+    rc = sprintf_s(breakpointString, 24, "%s %d:%d",  // sizeof breakpointString
+                   PLDBGAPI_SET_BREAKPOINT, funcOID, lineNumber);
+    securec_check_ss(rc, "\0", "\0");
 	sendString( session, breakpointString );
 		
 	PG_RETURN_BOOL( getBool( session ));
@@ -866,9 +890,11 @@ Datum pldbg_drop_breakpoint( PG_FUNCTION_ARGS )
 	Oid			   funcOID    = PG_GETARG_OID( 1 );
 	int			   lineNumber = PG_GETARG_INT32( 2 );
 	char		   breakpointString[13];	/* 10 digits + 1 delimiters + 1 command + null terminator */
+    errno_t       rc;
 
-	sprintf( breakpointString, "%s %d:%d", PLDBG_CLEAR_BREAKPOINT, funcOID, lineNumber );
-
+    rc = sprintf_s(breakpointString, 13, "%s %d:%d",  // sizeof breakpointString
+                   PLDBGAPI_CLEAR_BREAKPOINT, funcOID, lineNumber);
+    securec_check_ss(rc, "\0", "\0");
 	sendString( session, breakpointString );
 		
 	PG_RETURN_BOOL( getBool( session ));
@@ -894,7 +920,7 @@ Datum pldbg_deposit_value( PG_FUNCTION_ARGS )
 
 	initStringInfo( &buf );
 
-	appendStringInfo( &buf, "%s %s.%d=%s", PLDBG_DEPOSIT, varName, lineNumber, value );
+	appendStringInfo( &buf, "%s %s.%d=%s", PLDBGAPI_DEPOSIT, varName, lineNumber, value );
 
 	sendString( session, buf.data );
 
@@ -909,9 +935,9 @@ Datum pldbg_deposit_value( PG_FUNCTION_ARGS )
  *******************************************************************************/
 
 /*******************************************************************************
- * initializeModule()
+ * registCallbackInSessExit()
  *
- *	Initializes the debugger proxy module.  For now, we just register a callback
+ *	For now, we just register a callback
  *	(cleanupAtExit()) that this backend will invoke on exit - we use that 
  *	callback to gracefully close any outstanding connections.
  *
@@ -919,16 +945,13 @@ Datum pldbg_deposit_value( PG_FUNCTION_ARGS )
  *		  each of the complex datatypes that we use (breakpoint, var, frame).
  */
 
-static void initializeModule( void )
+void registCallbackInSessExit( void )
 {
-	static bool	initialized = FALSE;
-
-	if( !initialized )
-	{
-		initialized = TRUE;
-
-		on_shmem_exit( cleanupAtExit, 0 );
-	}
+    if (!g_instance.attr.attr_common.enable_thread_pool) {
+        on_proc_exit(cleanupAtExit, 0);
+    } else {
+        u_sess->ext_fdw_ctx[PLDEBUG_TYPE].fdwExitFunc = cleanupAtExit;
+    }
 }
 
 /*******************************************************************************
@@ -944,18 +967,21 @@ static void initializeModule( void )
  *
  *	NOTE: If you give this function an invalid sessionHandle it will throw an
  *		  error. A sessionHandle is valid if returned by addSession().
+ *
+ * openGauss Modification:
+ *     session state will be check here, before server close, it will send close
+ *     message to client, then client mark this session DBG_SESS_NOTCONNECT.
  */
 
 static debugSession * defaultSession( sessionHandle handle )
 {
-	debugSession * session;
+    MAKESURE_CLIENT_IS_ON;
+	debugSession * session = mostRecentSession;
 
 	if( handle == 0 )
 	{
 		if( mostRecentSession == NULL )
 			ereport( ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg( "invalid session handle" )));
-		else
-			return( mostRecentSession );
 	}
 	else
 	{
@@ -966,11 +992,13 @@ static debugSession * defaultSession( sessionHandle handle )
 		else
 		{
 			mostRecentSession = session;
-			return( session );
 		}
 	}
+    if (session->state == DBG_SESS_NOTCONNECT) {
+        ereport(ERROR, (errcode(ERRCODE_CONNECTION_FAILURE), errmsg("Session connect failed, server is not on")));
+    }
 
-	return( NULL );	  /* keep the compiler happy */
+	return(session);	  /* keep the compiler happy */
 }
 
 /*******************************************************************************
@@ -979,12 +1007,15 @@ static debugSession * defaultSession( sessionHandle handle )
  *	Initialize a hash table that we use to map session handles (simple integer
  *	values) into debugSession pointers.
  *
- *  You should call this function before you use the hash - you can call it 
- *  as many times as you like, it will only initialize the hash table on the
- *  first invocation.
+ * You should call this function before you use the hash - you can call it 
+ * as many times as you like, it will only initialize the hash table on the
+ * first invocation.
+ *
+ * OpenGauss Modifications:
+ *     session hash will be inited when client is starting up;
  */
 
-static void initSessionHash()
+void initSessionHash()
 {
 	if( sessionHash )
 		return;
@@ -995,8 +1026,9 @@ static void initSessionHash()
 		ctl.keysize   = sizeof( sessionHandle );
 		ctl.entrysize = sizeof( sessionHashEntry );
 		ctl.hash      = tag_hash;
+		ctl.hcxt	  = PldbgMemoryContext;
 
-		sessionHash = hash_create( "Debugger sessions", 5, &ctl, HASH_ELEM | HASH_FUNCTION );
+		sessionHash = hash_create( "Debugger sessions", 5, &ctl, HASH_CONTEXT | HASH_ELEM | HASH_FUNCTION );
 	}
 }
 
@@ -1014,14 +1046,13 @@ static void initSessionHash()
 
 static sessionHandle addSession( debugSession * session )
 {
-	static sessionHandle nextHandle;
 	sessionHashEntry   * entry;
 	bool			   	 found;
 	sessionHandle		 handle;
 
 	initSessionHash();
 
-	handle = ++nextHandle;
+	handle = nextHandle ++;
 
 	entry = (sessionHashEntry *)hash_search( sessionHash, &handle, HASH_ENTER, &found );
 
@@ -1045,7 +1076,7 @@ static debugSession * findSession( sessionHandle handle )
 
 	initSessionHash();
 
-	if(( entry = hash_search( sessionHash, &handle, HASH_FIND, NULL )) != NULL )
+	if(( entry = (sessionHashEntry*)hash_search( sessionHash, &handle, HASH_FIND, NULL )) != NULL )
 	{
 		return( entry->m_session );
 	}
@@ -1131,7 +1162,7 @@ static void * readn( int serverHandle, void * dst, size_t len )
 	char  * buffer         = (char *)dst;
 
 	if( serverHandle == -1 )
-		ereport( ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg( "given session is not connected" )));
+        ereport(ERROR, (errcode(ERRCODE_CONNECTION_DOES_NOT_EXIST), errmsg("given session is not connected")));
 
 	while( bytesRemaining > 0 )
 	{
@@ -1152,9 +1183,9 @@ static void * readn( int serverHandle, void * dst, size_t len )
 
 		FD_ZERO( &rmask );
 		FD_SET( serverHandle, &rmask );
-		FD_SET( MyProcPort->sock, &rmask );
+		FD_SET( u_sess->proc_cxt.MyProcPort->sock, &rmask );
 
-		switch( select(( serverHandle > MyProcPort->sock ? serverHandle : MyProcPort->sock ) + 1, &rmask, NULL, NULL, NULL ))
+		switch( select(( serverHandle > u_sess->proc_cxt.MyProcPort->sock ? serverHandle : u_sess->proc_cxt.MyProcPort->sock ) + 1, &rmask, NULL, NULL, NULL ))
 		{
 			case -1:
 			{
@@ -1179,7 +1210,7 @@ static void * readn( int serverHandle, void * dst, size_t len )
 				 * is when the client process has killed itself...
 				 */
 
-				if( FD_ISSET( MyProcPort->sock, &rmask ))
+				if( FD_ISSET( u_sess->proc_cxt.MyProcPort->sock, &rmask ))
 					ereport( ERROR, ( ERRCODE_CONNECTION_FAILURE, errmsg( "debugger connection(client side) terminated" )));
 				break;
 			}
@@ -1266,7 +1297,7 @@ static void sendUInt32( debugSession * session, uint32 val )
  *	don't send the null-terminator.
  */
 
-static void sendString( debugSession * session, char * src )
+void sendString( debugSession * session, char * src )
 {
 	size_t	len = strlen( src );
 
@@ -1328,6 +1359,10 @@ static uint32 getUInt32( debugSession * session )
  *	enough space to hold the entire string (including the null-terminator) and
  *	return a pointer to that space (after, of course, reading the string from
  *	the server and tacking on the null-terminator).
+ *
+ * OpenGauss Modifications:
+ *     " : : " means that server is closed, it will be sent to client before server's shutdown,
+ *     so that client can mark this session state as DBG_SESS_NOTCONNECT;
  */
 
 static char * getNString( debugSession * session )
@@ -1336,16 +1371,18 @@ static char * getNString( debugSession * session )
 
 	if( len == 0 )
 		return( NULL );
-	else
-	{
-		char * result = palloc( len + 1 );
-
-		readn( session->serverSocket, result, len );
 
-		result[len] = '\0';
+	char * result = (char*)palloc( len + 1 );
+	readn( session->serverSocket, result, len );
+	result[len] = '\0';
 
-		return( result );
+	if (strcmp(result, " : : ") == 0) {
+		session->state = DBG_SESS_NOTCONNECT;
+		pfree(result);
+		ereport(ERROR, 
+		    (errcode(ERRCODE_CONNECTION_DOES_NOT_EXIST), errmsg("The pldebugger server has been shutdown.")));
 	}
+	return( result );
 }
 
 /*******************************************************************************
@@ -1355,18 +1392,12 @@ static char * getNString( debugSession * session )
  *	server.
  */
 
-static void closeSession( debugSession * session )
+void closeSession( debugSession * session )
 {
-	if( session->serverSocket )
-	        closesocket( session->serverSocket );
+    if( session->serverSocket )
+        closesocket( session->serverSocket );
 
-	if( session->listener )
-		BreakpointCleanupProc( MyProcPid );
-
-	if( session->breakpointString )
-		pfree( session->breakpointString );
-
-	pfree( session );
+    session->state = DBG_SESS_NOTCONNECT;
 }
 
 /******************************************************************************
@@ -1375,19 +1406,14 @@ static void closeSession( debugSession * session )
  *	This is a callback function that the backend invokes when exiting.  At exit,
  *	we close any connections that we may still have (connections to debugger
  *	servers, that is).
+ *
+ * OpenGauss Modifications:
+ *     We call the new function pldbg_off() instead to clean up everything.
  */
 
 static void cleanupAtExit( int code, Datum arg )
 {
-	/*
-	 * FIXME: we should clean up all of the sessions stored in the
-	 *		  sessionHash.
-	 */
-
-	if( mostRecentSession )
-		closeSession( mostRecentSession );
-
-	mostRecentSession = NULL;
+    pldbg_off(NULL);
 }
 
 /*******************************************************************************
@@ -1417,3 +1443,26 @@ static TupleDesc getResultTupleDesc( FunctionCallInfo fcinfo )
 	}
 	return( rsinfo->expectedDesc );
 }
+
+/******************************************************************************
+ * clearSocketContent
+ * clear socket content
+ */
+void clearSocketContent(debugSession* session)
+{
+    fd_set fds;
+    struct timeval timeout={0,1};
+    FD_ZERO(&fds);
+    FD_SET(session->serverSocket, &fds);
+    for (;;) {
+        switch (select(session->serverSocket + 1, &fds, NULL, NULL, &timeout)) {
+            case -1:
+                ereport(ERROR, (errmsg("select() failed while waiting for target")));
+            case 0:
+                return;
+            default:
+                pfree(getNString(session));
+                break;
+        }
+    }
+}
\ No newline at end of file
diff --git a/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/pldebugger.h b/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/pldebugger.h
index 223ac81..8d15040 100644
--- a/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/pldebugger.h
+++ b/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/pldebugger.h
@@ -1,8 +1,22 @@
+/*
+ * OpenGauss Modification:
+ *    We have made the following modifications on the source code to adapt to openGauss:
+ *    1. 'LWLockId' is redefined to 'LWLock' by typedef method.
+ *    2. Some structs in other .cpp files have been moved to here.
+ *    3. 'debugSessionState' var is added to mark session status in client.
+ *    4. Add a message command 'PLDBG_DISCONNECT', which means the client is closed, and the server will
+ *       re-send a message to proxy and keep waiting for a new client to connect.
+ *
+ *    5. Most importantly, we split the contents of pldebugger into server and client, and each role will keep their
+ *       own vars within the struct scope. All of these vars are inited in 'init_pldebugger_role()'.
+ */
 #ifndef PLDEBUGGER_H
 #define PLDEBUGGER_H
 
 #include "globalbp.h"
-#include "storage/lwlock.h"
+#include "storage/lock/lwlock.h"
+
+typedef LWLock *LWLockId;
 
 /* 
  * We keep one per_session_ctx structure per backend. This structure holds all
@@ -15,8 +29,65 @@ typedef struct
 	int		 client_w;				/* Write stream connected to client						 */
 } per_session_ctx_t;
 
-extern per_session_ctx_t per_session_ctx;
+/*******************************************************************************
+ * Structure debugSession
+ *
+ *	A debugger client may attach to many target sessions at the same time. We
+ *	keep track of each connection in a debugSession structure. When the client
+ *	makes a connection, we allocate a new debugSession structure and return 
+ *	a handle to that structure to the caller.  He gives us back the handle 
+ *	whenever he calls another proxy function. A handle is just a smallish 
+ *  integer value that we use to track each session - we use a hash to map
+ *  handles into debugSession pointers.
+ */
+typedef enum debugSessionState {
+    DBG_SESS_UNINIT,         // session not init
+    DBG_SESS_ACTIVE,         // session server active.
+    DBG_SESS_NOTCONNECT      // session server has been shutdown.
+} debugSessionState;
+
+typedef struct
+{
+	int			serverSocket;	/* Socket connected to the debugger server */
+	int			serverPort;		/* Port number where debugger server is listening */
+	int			listener;		/* Socket where we wait for global breakpoints */
+	char	   *breakpointString;
+        debugSessionState       state;
+} debugSession;
+
+/*******************************************************************************
+ * Stucture sessionHashEntry
+ *
+ *	As mentioned above (see debugSession), a debugger proxy can manage many
+ *	debug sessions at once.  To keep track of each session, we create a
+ *	debugSession object and return a handle to that object to the caller.  The
+ *	handle is an opaque value - it's just an integer value.  To convert a
+ *	handle into an actual debugSession pointer, we create a hash that maps
+ *	handles into debugSession pointers.
+ *
+ *  Each member of the hash is shaped like a sessionHashEntry object.
+ */
+typedef int32  sessionHandle;
+
+typedef struct
+{
+	sessionHandle	m_handle;
+	debugSession   *m_session;
+} sessionHashEntry;
 
+typedef struct
+{
+	void	(* initialize)(void);
+	bool	(* frame_belongs_to_me)(ErrorContextCallback *frame);
+	void	(* send_stack_frame)(ErrorContextCallback *frame);
+	void	(* send_vars)(ErrorContextCallback *frame);
+	void	(* select_frame)(ErrorContextCallback *frame);
+	void	(* print_var)(ErrorContextCallback *frame, const char *var_name, int lineno);
+	bool	(* do_deposit)(ErrorContextCallback *frame, const char *var_name,
+						   int line_number, const char *value);
+	Oid		(* get_func_oid)(ErrorContextCallback *frame);
+	void	(* send_cur_line)(ErrorContextCallback *frame);
+} debugger_language_t;
 
 /*
  * errorHandlerCtx
@@ -26,7 +97,6 @@ extern per_session_ctx_t per_session_ctx;
  *  wrap sigjmp_buf's - we have to do that because sigjmp_buf is defined as an 
  *  array on some platforms (like Win32).
  */
-
 typedef struct
 {
 	sigjmp_buf	m_savepoint;
@@ -49,22 +119,66 @@ extern errorHandlerCtx client_lost;
 #define PLDBG_DEPOSIT				'd'
 #define PLDBG_RESTART				'r'
 #define PLDBG_STOP				'x'
+#define PLDBG_DISCONNECT        'C'
 
-typedef struct
-{
-	void	(* initialize)(void);
-	bool	(* frame_belongs_to_me)(ErrorContextCallback *frame);
-	void	(* send_stack_frame)(ErrorContextCallback *frame);
-	void	(* send_vars)(ErrorContextCallback *frame);
-	void	(* select_frame)(ErrorContextCallback *frame);
-	void	(* print_var)(ErrorContextCallback *frame, const char *var_name, int lineno);
-	bool	(* do_deposit)(ErrorContextCallback *frame, const char *var_name,
-						   int line_number, const char *value);
-	Oid		(* get_func_oid)(ErrorContextCallback *frame);
-	void	(* send_cur_line)(ErrorContextCallback *frame);
-} debugger_language_t;
+/*****************************************************************************
+ * for thread pool of openGauss, we use knl_u_pldbg_context to store global var of
+ * of session-level.
+ */
+typedef enum Pldbg_Role {
+    PLDBG_NONE,         // not a pldebugger session.
+    PLDBG_SERVER,       // pldebugger server, be debugged.
+    PLDBG_CLIENT        // pldebugger client, be used to debug server.
+} Pldbg_Role;
+
+typedef struct knl_u_pldbg_client_context {
+    debugSession*     theMostRecentSession;  // the most recent session we used
+    HTAB*             my_attached_sessions;  // sessions we attached
+    sessionHandle     nextHandleNum;         // session id of next handle
+} knl_u_pldbg_client_context;
+
+typedef struct knl_u_pldbg_server_context {
+    HTAB*             breakpoints;           // local breakpoints
+    HTAB*             breakCounts;           // key and count of local breakpoints
+    per_session_ctx_t session_debug_info;    // session-level debug info
+} knl_u_pldbg_server_context;
+
+typedef struct knl_u_pldbg_context {
+    Pldbg_Role role;
+    knl_u_pldbg_client_context* client;
+    knl_u_pldbg_server_context* server;
+    void (*shutdown)();
+	MemoryContext pldbg_sess_cxt;
+} knl_u_pldbg_context;
+
+
+#define localBreakpoints ((knl_u_pldbg_context*)(u_sess->ext_fdw_ctx[PLDEBUG_TYPE].pldbg_ctx))->server->breakpoints
+#define localBreakCounts ((knl_u_pldbg_context*)(u_sess->ext_fdw_ctx[PLDEBUG_TYPE].pldbg_ctx))->server->breakCounts
+#define per_session_ctx ((knl_u_pldbg_context*)(u_sess->ext_fdw_ctx[PLDEBUG_TYPE].pldbg_ctx))->server->session_debug_info
+#define mostRecentSession ((knl_u_pldbg_context*)(u_sess->ext_fdw_ctx[PLDEBUG_TYPE].pldbg_ctx))->client->theMostRecentSession
+#define sessionHash ((knl_u_pldbg_context*)(u_sess->ext_fdw_ctx[PLDEBUG_TYPE].pldbg_ctx))->client->my_attached_sessions
+#define nextHandle ((knl_u_pldbg_context*)(u_sess->ext_fdw_ctx[PLDEBUG_TYPE].pldbg_ctx))->client->nextHandleNum
+#define PldbgMemoryContext ((knl_u_pldbg_context*)(u_sess->ext_fdw_ctx[PLDEBUG_TYPE].pldbg_ctx))->pldbg_sess_cxt
+#define IS_PLDEBUGGER_ON (u_sess->ext_fdw_ctx[PLDEBUG_TYPE].pldbg_ctx != NULL)
+#define IS_PLDEBUGGER_CLIENT (IS_PLDEBUGGER_ON && ((knl_u_pldbg_context*)(u_sess->ext_fdw_ctx[PLDEBUG_TYPE].pldbg_ctx))->client != NULL)
+#define IS_PLDEBUGGER_SERVER (IS_PLDEBUGGER_ON && ((knl_u_pldbg_context*)(u_sess->ext_fdw_ctx[PLDEBUG_TYPE].pldbg_ctx))->server != NULL)
+#define MAKESURE_CLIENT_IS_ON  \
+    do { \
+        if (!IS_PLDEBUGGER_CLIENT) {  \
+            ereport(ERROR, (errcode(ERRCODE_INITIALIZE_FAILED), errmsg("Pldebugger is not active or you are not client now.")));  \
+        }   \
+    } while (0);
+#define InvalidSessId uint64(-1)
+#define MY_SESS_ID (IS_THREAD_POOL_WORKER ? u_sess->session_id : t_thrd.proc_cxt.MyProcPid)
+
+int LWLockNewTrancheId();
+void init_pldebugger_role(Pldbg_Role role);
+void destroy_pldebugger_context();
+void pldbg_client_shutdown();
+void pldbg_server_shutdown();
 
 /* in plugin_debugger.c */
+extern void initLocalBreakpoints(void);
 extern void initGlobalBreakpoints(void);
 extern bool plugin_debugger_main_loop(void);
 
@@ -73,6 +187,7 @@ extern bool attach_to_proxy( Breakpoint * breakpoint );
 extern void setBreakpoint( char * command );
 extern void clearBreakpoint( char * command );
 extern bool breakpointsForFunction( Oid funcOid );
+extern void initSessionHash(void);
 
 extern void	dbg_send( const char *fmt, ... )
 #ifdef PG_PRINTF_ATTRIBUTE
@@ -82,8 +197,10 @@ __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)))
 #endif
 ;
 extern char 	   * dbg_read_str(void);
-
-extern LWLockId  getPLDebuggerLock(void);
+void sendString( debugSession * session, char * src );
+void closeSession( debugSession * session );
+void registCallbackInSessExit(void);
+extern LWLock*  getPLDebuggerLock(void);
 
 /* in plpgsql_debugger.c */
 extern void plpgsql_debugger_fini(void);
diff --git a/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/plpgsql_debugger.cpp b/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/plpgsql_debugger.cpp
index df52f01..f753d40 100644
--- a/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/plpgsql_debugger.cpp
+++ b/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/plpgsql_debugger.cpp
@@ -24,6 +24,7 @@
 #include "globalbp.h"
 #include "utils/array.h"
 #include "utils/builtins.h"
+#include "utils/memutils.h"
 #include "utils/syscache.h"
 #include "miscadmin.h"
 
@@ -46,8 +47,7 @@
  * each variable. 
  */
 
-typedef struct
-{
+typedef struct var_value {
     bool	    isnull;			/* TRUE -> this variable IS NULL */
 	bool		visible;		/* hidden or visible? see is_visible_datum() */
 	bool		duplicate_name;	/* Is this one of many vars with same name? */
@@ -63,8 +63,7 @@ typedef struct
  * code and display variable values
  */
 
-typedef struct
-{
+typedef struct dbg_ctx {
     PLpgSQL_function *	func;		/* Function definition */
     bool				stepping;	/* If TRUE, stop at next statement */
     var_value	     *  symbols;	/* Extra debugger-private info about variables */
@@ -128,22 +127,153 @@ debugger_language_t plpgsql_debugger_lang =
 	plpgsql_send_cur_line
 };
 
-/* Install this module as an PL/pgSQL instrumentation plugin */
-static void
-plpgsql_debugger_init(void)
+/*
+
+ * Install this module as an PL/pgSQL instrumentation plugin when database start up;
+ * Called by: _PG_init
+ */
+static void plpgsql_debugger_init(void)
 {
-	PLpgSQL_plugin ** var_ptr = (PLpgSQL_plugin **) find_rendezvous_variable( plugin_name );
+	PLpgSQL_plugin ** var_ptr = (PLpgSQL_plugin **) find_rendezvous_variable(plugin_name);
 
 	*var_ptr = &plugin_funcs;
 }
 
 
+/*
+ * Initialize the contents of 'u_sess->ext_fdw_ctx[PLDEBUG_TYPE].pldbg_ctx'
+ * during the debugger starting process.
+ */
+void init_pldebugger_role(Pldbg_Role role)
+{
+    if (u_sess->ext_fdw_ctx[PLDEBUG_TYPE].pldbg_ctx != NULL) {
+        ereport(ERROR, 
+            (errcode(ERRCODE_INVALID_ROLE_SPECIFICATION), errmsg("You already have an identity. ")));
+    }
+
+    if (t_thrd.role == THREADPOOL_WORKER &&
+        (u_sess->plsql_cxt.plugin_ptr == NULL || *u_sess->plsql_cxt.plugin_ptr == NULL)) {
+        process_shared_preload_libraries();
+    }
+
+    MemoryContext pldbg_sess_cxt = AllocSetContextCreate(u_sess->top_mem_cxt, "PldbgSessCxt",
+        ALLOCSET_SMALL_MINSIZE, ALLOCSET_SMALL_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE);
+
+    MemoryContext oldcontext = MemoryContextSwitchTo(pldbg_sess_cxt);
+	knl_u_pldbg_context* pldbg_cxt = (knl_u_pldbg_context*)palloc(sizeof(knl_u_pldbg_context));
+	
+    switch (role) {
+        case PLDBG_CLIENT: {
+            knl_u_pldbg_client_context* client = 
+                (knl_u_pldbg_client_context*)palloc(sizeof(knl_u_pldbg_client_context));
+            client->theMostRecentSession = NULL;
+            client->my_attached_sessions = NULL;
+            client->nextHandleNum = 1;
+
+            pldbg_cxt->server = NULL;
+            pldbg_cxt->client = client;
+            pldbg_cxt->role = PLDBG_CLIENT;
+            pldbg_cxt->pldbg_sess_cxt = pldbg_sess_cxt;
+            u_sess->ext_fdw_ctx[PLDEBUG_TYPE].pldbg_ctx = (void*)pldbg_cxt;
+            initSessionHash();
+            ereport(NOTICE, (errmsg("Pldebugger is started successfully, you are CLIENT now.")));
+        } break;
+        case PLDBG_SERVER: {
+            knl_u_pldbg_server_context* server = 
+                (knl_u_pldbg_server_context*)palloc(sizeof(knl_u_pldbg_server_context));
+            server->breakpoints = NULL;
+            server->breakCounts = NULL;
+            server->session_debug_info.step_into_next_func = false;
+            server->session_debug_info.client_w = 0;
+            server->session_debug_info.client_r = 0;
+
+            pldbg_cxt->server = server;
+            pldbg_cxt->client = NULL;
+            pldbg_cxt->role = PLDBG_SERVER;
+            pldbg_cxt->pldbg_sess_cxt = pldbg_sess_cxt;
+            u_sess->ext_fdw_ctx[PLDEBUG_TYPE].pldbg_ctx = (void*)pldbg_cxt;
+			
+            /* now we can init some pointers */
+            initLocalBreakpoints();
+            ereport(NOTICE, (errmsg("Pldebugger is started successfully, you are SERVER now.")));
+        } break;
+        default: {
+            MemoryContextSwitchTo(oldcontext);
+            ereport(ERROR, 
+                (errcode(ERRCODE_INVALID_ROLE_SPECIFICATION), errmsg("invalid pldebugger role.")));
+        }
+    }
+    MemoryContextSwitchTo(oldcontext);
+
+    // when session exits, call 'pldbg_off()'.
+    registCallbackInSessExit();
+}
+
+/*
+ * Destroy pldebugger context when the current session exits
+ */
+void destroy_pldebugger_context()
+{
+    MemoryContextDelete(PldbgMemoryContext);
+    PldbgMemoryContext = NULL;
+    u_sess->ext_fdw_ctx[PLDEBUG_TYPE].pldbg_ctx = NULL;
+    u_sess->ext_fdw_ctx[PLDEBUG_TYPE].fdwExitFunc = NULL;
+}
+void pldbg_client_shutdown()
+{
+#define PLDBGAPI_DISCONNECT "C\n"
+    // free all sessions
+    HASH_SEQ_STATUS	  scan;
+    sessionHashEntry* session = NULL;
+    if (sessionHash != NULL) {
+    hash_seq_init(&scan, sessionHash);
+    while((session = (sessionHashEntry*)hash_seq_search(&scan)) != NULL){
+        sendString(session->m_session, PLDBGAPI_DISCONNECT);
+        closeSession(session->m_session);
+    }
+    }
+}
+/*
+ * shut down the server when do pldbg_off()
+ */
+void pldbg_server_shutdown()
+{
+    /* server just on before and do not have a client. */
+    if (per_session_ctx.client_r == 0)
+        return;
+
+    /* client mabey down before, we must test it first. */
+    bool client_is_off = false;
+    fd_set fds;
+    struct timeval timeout={1,0};
+
+    FD_ZERO(&fds);
+    FD_SET(per_session_ctx.client_r, &fds);
+    switch (select(per_session_ctx.client_r + 1, &fds, NULL, NULL, &timeout)) {
+        case -1:
+            ereport(ERROR, (errmsg("select() failed while waiting for target")));
+        case 0:
+            client_is_off = false;
+            break;
+        default: /* there is something in socket, mabey shutdown message of client or other command. */
+            if (FD_ISSET(per_session_ctx.client_r, &fds)) {
+                char* cmd = dbg_read_str();
+                if (cmd[0] == PLDBG_DISCONNECT)
+                    client_is_off = true;
+            }
+            break;
+    }
+    if (!client_is_off)
+        dbg_send(" :%s: ", " ");
+    per_session_ctx.client_r = 0;
+    per_session_ctx.client_w = 0;
+}
+
 /**********************************************************************
  * Functions implemeting the pldebugger_language_t interface
  **********************************************************************/
 
-static bool
-plpgsql_frame_belongs_to_me(ErrorContextCallback *frame)
+static bool plpgsql_frame_belongs_to_me(ErrorContextCallback* frame)
 {
 	return (frame->callback == plugin_funcs.error_callback);
 }
@@ -156,8 +286,7 @@ plpgsql_frame_belongs_to_me(ErrorContextCallback *frame)
  * finds a PL/pgSQL call in the stack (remember, the call stack may contain
  * stack frames for functions written in other languages like PL/Tcl).
  */
-static void
-plpgsql_send_stack_frame(ErrorContextCallback *frame)
+static void plpgsql_send_stack_frame(ErrorContextCallback* frame)
 {
 	PLpgSQL_execstate *estate = (PLpgSQL_execstate *) frame->arg;
 #if (PG_VERSION_NUM >= 80500)
@@ -189,8 +318,7 @@ plpgsql_send_stack_frame(ErrorContextCallback *frame)
 	 * Now assemble a string that shows the argument names and value for this frame
 	 */
 
-	for( arg = 0; arg < func->fn_nargs; ++arg )
-	{
+    for (arg = 0; arg < func->fn_nargs; ++arg) {
 		int					index   = func->fn_argvarnos[arg];
 		PLpgSQL_datum		*argDatum = (PLpgSQL_datum *)estate->datums[index];
 		char 				*value;
@@ -273,35 +401,9 @@ plpgsql_send_vars(ErrorContextCallback *frame)
 							  var->notnull ? 't':'f', 
 							  var->datatype ? var->datatype->typoid : InvalidOid,
 							  val );
-				  
-					break;
-				}
-#if 0
-			FIXME: implement other types
-
-				case PLPGSQL_DTYPE_REC:
-				{
-					PLpgSQL_rec * rec = (PLpgSQL_rec *) estate->datums[i];
-					int		      att;
-					char        * typeName;
 
-					if (rec->tupdesc != NULL)
-					{
-						for( att = 0; att < rec->tupdesc->natts; ++att )
-						{
-							typeName = SPI_gettype( rec->tupdesc, att + 1 );
-	
-							dbg_send( "o:%s.%s:%d:%d:%d:%d:%s\n",
-									  rec->refname, NameStr( rec->tupdesc->attrs[att]->attname ), 
-									  0, rec->lineno, 0, rec->tupdesc->attrs[att]->attnotnull, typeName ? typeName : "" );
-	
-							if( typeName )
-								pfree( typeName );
-						}
-					}
 					break;
 				}
-#endif
 			}
 		}
 	}
@@ -549,7 +651,9 @@ static void print_var( const PLpgSQL_execstate * frame, const char * var_name, i
 
     fmgr_info( typeStruct->typoutput, &finfo_output );
 
-    extval = DatumGetCString( FunctionCall3( &finfo_output, tgt->value, ObjectIdGetDatum(typeStruct->typelem), Int32GetDatum(-1)));
+    extval = DatumGetCString(FunctionCall3(&finfo_output, tgt->value, 
+                                           ObjectIdGetDatum(typeStruct->typelem),
+                                           Int32GetDatum(-1)));
 
 	/* Send the name:value to the debugger client */
 
@@ -586,10 +690,10 @@ static void print_rec( const PLpgSQL_execstate * frame, const char * var_name, i
 	}
 }
 
-static void print_recfield( const PLpgSQL_execstate * frame, const char * var_name, int lineno, const PLpgSQL_recfield * tgt )
+static void print_recfield(const PLpgSQL_execstate* frame, const char* var_name,
+                           int lineno, const PLpgSQL_recfield* tgt)
 {
-
-
+    return;
 }
 
 static void
@@ -837,7 +941,7 @@ plpgsql_get_func_oid(ErrorContextCallback *frame)
 
 static void dbg_startup( PLpgSQL_execstate * estate, PLpgSQL_function * func )
 {
-	if( func == NULL )
+	if( func == NULL || !IS_PLDEBUGGER_SERVER)
 	{
 		/* 
 		 * In general, this should never happen, but it seems to in the 
@@ -943,13 +1047,14 @@ static void initialize_plugin_info( PLpgSQL_execstate * estate,
 static bool plpgsql_do_deposit(ErrorContextCallback *frame, const char *var_name, int lineno, const char *value)
 {
 	PLpgSQL_execstate *estate = (PLpgSQL_execstate *) frame->arg;
-	dbg_ctx       *dbg_info   = estate->plugin_info;
+	dbg_ctx       *dbg_info   = (dbg_ctx*)estate->plugin_info;
 	PLpgSQL_datum *target;
 	char      	  *select;
 	PLpgSQL_expr  *expr;
 	MemoryContext  curContext = CurrentMemoryContext;
-	ResourceOwner  curOwner   = CurrentResourceOwner;
+	ResourceOwner  curOwner   = t_thrd.utils_cxt.CurrentResourceOwner;
 	bool		retval = false;
+    errno_t rc = 0;
 
 	target = find_datum_by_name(estate, var_name, lineno, NULL);
     if (!target)
@@ -962,9 +1067,10 @@ static bool plpgsql_do_deposit(ErrorContextCallback *frame, const char *var_name
 	 *       need to later (see the retry logic below)
 	 */
 
-	select = palloc( strlen( "SELECT " ) + strlen( value ) + 2 + 1 );
+	select = (char*)palloc( strlen( "SELECT " ) + strlen( value ) + 2 + 1 );
 
-	sprintf( select, "SELECT %s", value );
+    rc = sprintf_s(select, strlen("SELECT ") + strlen(value) + 2 + 1, "SELECT %s", value);
+    securec_check_ss_c(rc, "\0", "\0");
 
     /*
 	 * Note: we must create a dynamically allocated PLpgSQL_expr here - we 
@@ -998,7 +1104,7 @@ static bool plpgsql_do_deposit(ErrorContextCallback *frame, const char *var_name
 		/* Commit the inner transaction, return to outer xact context */
 		ReleaseCurrentSubTransaction();
 		MemoryContextSwitchTo( curContext );
-		CurrentResourceOwner = curOwner;
+		t_thrd.utils_cxt.CurrentResourceOwner = curOwner;
 
 		SPI_restore_connection();		
 
@@ -1014,7 +1120,7 @@ static bool plpgsql_do_deposit(ErrorContextCallback *frame, const char *var_name
 		/* Abort the inner transaction */
 		RollbackAndReleaseCurrentSubTransaction();
 		MemoryContextSwitchTo( curContext );
-		CurrentResourceOwner = curOwner;
+		t_thrd.utils_cxt.CurrentResourceOwner = curOwner;
 
 		SPI_restore_connection();
 
@@ -1030,7 +1136,8 @@ static bool plpgsql_do_deposit(ErrorContextCallback *frame, const char *var_name
 
 	if (!retval)
 	{
-		sprintf( select, "SELECT '%s'", value );
+        rc = sprintf_s(select, strlen("SELECT ") + strlen(value) + 2 + 1, "SELECT '%s'", value);
+        securec_check_ss_c(rc, "\0", "\0");
 
 		expr->dtype       	  = PLPGSQL_DTYPE_EXPR;
 		expr->dno              = -1;
@@ -1054,7 +1161,7 @@ static bool plpgsql_do_deposit(ErrorContextCallback *frame, const char *var_name
 			/* Commit the inner transaction, return to outer xact context */
 			ReleaseCurrentSubTransaction();
 			MemoryContextSwitchTo( curContext );
-			CurrentResourceOwner = curOwner;
+			t_thrd.utils_cxt.CurrentResourceOwner = curOwner;
 
 			SPI_restore_connection();		
 
@@ -1069,7 +1176,7 @@ static bool plpgsql_do_deposit(ErrorContextCallback *frame, const char *var_name
 			/* Abort the inner transaction */
 			RollbackAndReleaseCurrentSubTransaction();
 			MemoryContextSwitchTo( curContext );
-			CurrentResourceOwner = curOwner;
+			t_thrd.utils_cxt.CurrentResourceOwner = curOwner;
 
 			SPI_restore_connection();
 
@@ -1119,7 +1226,7 @@ static bool is_datum_visible( PLpgSQL_datum * datum )
 		PLpgSQL_var * var = (PLpgSQL_var *)datum;
 		int			  i;
 
-		for( i = 0; i < sizeof( hidden_variables ) / sizeof( hidden_variables[0] ); ++i )
+		for( i = 0; i < (int)(sizeof( hidden_variables ) / sizeof( hidden_variables[0] )); ++i )
 		{
 			if( strcmp( var->refname, hidden_variables[i] ) == 0 )
 			{
@@ -1200,7 +1307,7 @@ plpgsql_send_cur_line(ErrorContextCallback *frame)
 
 	dbg_send( "%d:%d:%s",
 			  func->fn_oid,
-			  stmt->lineno+1,
+			  stmt->lineno,
 #if (PG_VERSION_NUM >= 90200)
 			  func->fn_signature
 #else
@@ -1244,132 +1351,126 @@ static bool isFirstStmt( PLpgSQL_stmt * stmt, PLpgSQL_function * func )
 
 static void dbg_newstmt( PLpgSQL_execstate * estate, PLpgSQL_stmt * stmt )
 {
-	PLpgSQL_execstate * frame = estate;
-
     /*
-	 * If there's no debugger attached, go home as quickly as possible.
+	 * If there's no debugger attached or pldebugger is off, go home as quickly as possible.
 	 */
-	if( frame->plugin_info == NULL )
+	if( !IS_PLDEBUGGER_SERVER || estate->plugin_info == NULL)
 		return;
-	else
-	{
-		dbg_ctx 		  * dbg_info = (dbg_ctx *)frame->plugin_info;
-		Breakpoint		  * breakpoint = NULL;
-		eBreakpointScope	breakpointScope = 0;
+	
+	PLpgSQL_execstate * frame = estate;
+    dbg_ctx 		  * dbg_info = (dbg_ctx *)frame->plugin_info;
+	Breakpoint		  * breakpoint = NULL;
+	eBreakpointScope	breakpointScope = (BP_LOCAL);
 
-		/*
-		 * The PL compiler marks certain statements as 'invisible' to the
-		 * debugger. In particular, the compiler may generate statements
-		 * that do not appear in the source code. Such a statement is
-		 * marked with a line number of -1: if we're looking at an invisible
-		 * statement, just return to the caller.
-		 */
+	/*
+	 * The PL compiler marks certain statements as 'invisible' to the
+	 * debugger. In particular, the compiler may generate statements
+	 * that do not appear in the source code. Such a statement is
+	 * marked with a line number of -1: if we're looking at an invisible
+	 * statement, just return to the caller.
+	 */
 
-		if( stmt->lineno == -1 )
-			return;
+	if( stmt->lineno == -1 )
+		return;
 
+	/*
+	 * Now set up an error handler context so we can intercept any
+	 * networking errors (errors communicating with the proxy).
+	 */
+	if( sigsetjmp( client_lost.m_savepoint, 1 ) != 0 )
+	{
 		/*
-		 * Now set up an error handler context so we can intercept any
-		 * networking errors (errors communicating with the proxy).
+		 *  The connection to the debugger client has slammed shut - 
+		 *	just pretend like there's no debugger attached and return
+		 *
+		 *	NOTE: we no longer have a connection to the debugger proxy -
+		 *		  that means that we cannot interact with the proxy, we
+		 *		  can't wait for another command, nothing.  We let the
+		 *		  executor continue execution - anything else will hang
+		 *		  this backend, waiting for a debugger command that will
+		 *		  never arrive.
+		 *
+		 *		  If, however, we hit a breakpoint again, we'll stop and
+		 *		  wait for another debugger proxy to connect to us.  If
+		 *		  that's not the behavior you're looking for, you can 
+		 *		  drop the breakpoint, or call free_function_breakpoints()
+		 *		  here to get rid of all breakpoints in this backend.
 		 */
+		per_session_ctx.client_w = 0; 		/* No client connection */
+		dbg_info->stepping 		 = FALSE; 	/* No longer stepping   */
+	}
 
-		if( sigsetjmp( client_lost.m_savepoint, 1 ) != 0 )
-		{
-			/*
-			 *  The connection to the debugger client has slammed shut - 
-			 *	just pretend like there's no debugger attached and return
-			 *
-			 *	NOTE: we no longer have a connection to the debugger proxy -
-			 *		  that means that we cannot interact with the proxy, we
-			 *		  can't wait for another command, nothing.  We let the
-			 *		  executor continue execution - anything else will hang
-			 *		  this backend, waiting for a debugger command that will
-			 *		  never arrive.
-			 *
-			 *		  If, however, we hit a breakpoint again, we'll stop and
-			 *		  wait for another debugger proxy to connect to us.  If
-			 *		  that's not the behavior you're looking for, you can 
-			 *		  drop the breakpoint, or call free_function_breakpoints()
-			 *		  here to get rid of all breakpoints in this backend.
-			 */
-			per_session_ctx.client_w = 0; 		/* No client connection */
-			dbg_info->stepping 		 = FALSE; 	/* No longer stepping   */
-		}
-
-		if(( dbg_info->stepping ) || breakAtThisLine( &breakpoint, &breakpointScope, dbg_info->func->fn_oid, isFirstStmt( stmt, dbg_info->func ) ? -1 : stmt->lineno ))
-			dbg_info->stepping = TRUE;
-		else
-			return;
-
-		per_session_ctx.step_into_next_func = FALSE;
+    if ((dbg_info->stepping) ||
+        breakAtThisLine(&breakpoint, &breakpointScope, dbg_info->func->fn_oid,
+                        isFirstStmt(stmt, dbg_info->func) ? -1 : stmt->lineno))
+		dbg_info->stepping = TRUE;
+	else
+		return;
 
-		/* We found a breakpoint for this function (or we're stepping into) */
-		/* Make contact with the debugger client */
+	per_session_ctx.step_into_next_func = FALSE;
+	/* We found a breakpoint for this function (or we're stepping into) */
+	/* Make contact with the debugger client */
+	if( !attach_to_proxy( breakpoint ))
+	{
+		/* 
+		 * Can't attach to the proxy, maybe we found a stale breakpoint?
+		 * That can happen if you set a global breakpoint on a function,
+		 * invoke that function from a client application, debug the target
+		 * kill the debugger client, and then re-invoke the function from
+		 * the same client application - we will find the stale global
+		 * breakpoint on the second invocation.
+		 *
+		 * We want to remove that breakpoint so that we don't keep trying
+		 * to attach to a phantom proxy process.
+		 */
+		if( breakpoint )
+			BreakpointDelete( breakpointScope, &(breakpoint->key));
 
-		if( !attach_to_proxy( breakpoint ))
-		{
-			/* 
-			 * Can't attach to the proxy, maybe we found a stale breakpoint?
-			 * That can happen if you set a global breakpoint on a function,
-			 * invoke that function from a client application, debug the target
-			 * kill the debugger client, and then re-invoke the function from
-			 * the same client application - we will find the stale global
-			 * breakpoint on the second invocation.
-			 *
-			 * We want to remove that breakpoint so that we don't keep trying
-			 * to attach to a phantom proxy process.
-			 */
-			if( breakpoint )
-				BreakpointDelete( breakpointScope, &(breakpoint->key));
+		/*
+		 * In any case, if we don't have a proxy to work with, we can't 
+		 * do any debugging so give up.
+		 */
+		pfree( frame->plugin_info );
+		frame->plugin_info       = NULL; /* No debugger context  */
+		per_session_ctx.client_w = 0; /* No client connection */
 
-			/*
-			 * In any case, if we don't have a proxy to work with, we can't 
-			 * do any debugging so give up.
-			 */
-			pfree( frame->plugin_info );
-			frame->plugin_info       = NULL; /* No debugger context  */
-			per_session_ctx.client_w = 0; /* No client connection */
+		return;
+	}
 
-			return;
-		}
+	if( stmt->cmd_type == PLPGSQL_STMT_BLOCK )
+		return;
 
-		if( stmt->cmd_type == PLPGSQL_STMT_BLOCK )
-			return;
+	/*
+	 * The PL/pgSQL compiler inserts an automatic RETURN statement at the
+	 * end of each function (unless the last statement in the function is
+	 * already a RETURN). If we run into that statement, we don't really
+	 * want to wait for the user to STEP across it. Remember, the user won't
+	 * see the RETURN statement in the source-code listing for his function.
+	 *
+	 * Fortunately, the automatic RETURN statement has a line-number of 0 
+	 * so it's easy to spot.
+	 */
+	if( stmt->lineno == 0 )
+		return;
 
+	/*
+	 * If we're in step mode, tell the debugger client, read a command from the client and 
+	 * execute the command
+	 */
+	if( dbg_info->stepping )
+	{
 		/*
-		 * The PL/pgSQL compiler inserts an automatic RETURN statement at the
-		 * end of each function (unless the last statement in the function is
-		 * already a RETURN). If we run into that statement, we don't really
-		 * want to wait for the user to STEP across it. Remember, the user won't
-		 * see the RETURN statement in the source-code listing for his function.
-		 *
-		 * Fortunately, the automatic RETURN statement has a line-number of 0 
-		 * so it's easy to spot.
+		 * Make sure that we have all of the debug info that we need in this stack frame
 		 */
-		if( stmt->lineno == 0 )
-			return;
-
-		/*
-		 * If we're in step mode, tell the debugger client, read a command from the client and 
-		 * execute the command
+		completeFrame( frame );
+		/* 
+		 * We're in single-step mode (or at a breakpoint) 
+		 * send the current line number to the debugger client and report any
+		 * variable modifications
 		 */
 
-		if( dbg_info->stepping )
-		{
-			/*
-			 * Make sure that we have all of the debug info that we need in this stack frame
-			 */
-			completeFrame( frame );
-
-			/* 
-			 * We're in single-step mode (or at a breakpoint) 
-			 * send the current line number to the debugger client and report any
-			 * variable modifications
-			 */
-
-			if (!plugin_debugger_main_loop())
-				dbg_info->stepping = FALSE;
-		}
+		if (!plugin_debugger_main_loop())
+			dbg_info->stepping = FALSE;
 	}
 	
 	return;
diff --git a/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/plugin_debugger.cpp b/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/plugin_debugger.cpp
index 4f5f9b0..1aa33f7 100644
--- a/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/plugin_debugger.cpp
+++ b/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/plugin_debugger.cpp
@@ -33,7 +33,7 @@
 #include "parser/parser.h"
 #include "parser/parse_func.h"
 #include "globalbp.h"
-#include "storage/proc.h"							/* For MyProc		   */
+#include "storage/proc.h"         /* For MyProc            */
 #include "storage/procarray.h"						/* For BackendPidGetProc */
 #include "utils/array.h"
 #include "utils/builtins.h"
@@ -86,11 +86,11 @@ typedef enum
 /* Global breakpoint data. */
 typedef struct
 {
-#if (PG_VERSION_NUM >= 90600)
-	int		tranche_id;
+#if (PG_VERSION_NUM >= 90204)
+	int	tranche_id;
 	LWLock	lock;
 #else
-	LWLockId	lockid;
+	LWLockId     lockid;
 #endif
 } GlobalBreakpointData;
 
@@ -98,9 +98,6 @@ typedef struct
  * Local (static) variables
  **********************************************************************/
 
-
-per_session_ctx_t per_session_ctx;
-
 errorHandlerCtx client_lost;
 
 static debugger_language_t *debugger_languages[] = {
@@ -115,13 +112,11 @@ static debugger_language_t *debugger_languages[] = {
  * Function declarations
  **********************************************************************/
 
-void _PG_init( void );				/* initialize this module when we are dynamically loaded	*/
+extern "C" void _PG_init( void );				/* initialize this module when we are dynamically loaded	*/
 
 /**********************************************************************
  * Local (hidden) function prototypes
  **********************************************************************/
-
-//static char       ** fetchArgNames( PLpgSQL_function * func, int * nameCount );
 static void        * writen( int peer, void * src, size_t len );
 static bool 		 connectAsServer( void );
 static bool 		 connectAsClient( Breakpoint * breakpoint );
@@ -159,11 +154,14 @@ void _PG_init( void )
  * CREATE OR REPLACE FUNCTION pldbg_oid_debug( functionOID OID ) RETURNS INTEGER AS 'pldbg_oid_debug' LANGUAGE C;
  */
 
-Datum pldbg_oid_debug(PG_FUNCTION_ARGS);
+extern "C" Datum pldbg_oid_debug(PG_FUNCTION_ARGS);
 PG_FUNCTION_INFO_V1(pldbg_oid_debug);
 
 Datum pldbg_oid_debug(PG_FUNCTION_ARGS)
 {
+	if (!IS_PLDEBUGGER_SERVER) {
+        init_pldebugger_role(PLDBG_SERVER);
+	}
 	Oid			funcOid;
 	HeapTuple	tuple;
 	Oid			userid;
@@ -256,7 +254,7 @@ char *dbg_read_str( void )
 
 	len = readUInt32( sock );
 
-	dst = palloc(len + 1);
+	dst = (char*)palloc(len + 1);
 	readn( sock, dst, len );
 	
 	dst[len] = '\0';
@@ -625,11 +623,13 @@ static bool parseBreakpoint( Oid * funcOID, int * lineNumber, char * breakpointS
 static bool addLocalBreakpoint( Oid funcOID, int lineNo )
 {
 	Breakpoint breakpoint;
+	errno_t rc = memset_s(&breakpoint.key, sizeof(BreakpointKey), 0, sizeof(BreakpointKey));
+	securec_check(rc, "", "");
 	
-	breakpoint.key.databaseId = MyProc->databaseId;
+	breakpoint.key.databaseId = t_thrd.proc->databaseId;
 	breakpoint.key.functionId = funcOID;
 	breakpoint.key.lineNumber = lineNo;
-	breakpoint.key.targetPid  = MyProc->pid;
+    breakpoint.key.targetSessId  = MY_SESS_ID;
 	breakpoint.data.isTmp     = FALSE;
 	breakpoint.data.proxyPort = -1;
 	breakpoint.data.proxyPid  = -1;
@@ -691,11 +691,13 @@ void clearBreakpoint( char * command )
 	if( parseBreakpoint( &funcOID, &lineNo, command + 2 ))
 	{
 		Breakpoint breakpoint;
+		errno_t rc = memset_s(&breakpoint.key, sizeof(BreakpointKey), 0, sizeof(BreakpointKey));
+		securec_check(rc, "", "");
 	
-		breakpoint.key.databaseId = MyProc->databaseId;
+		breakpoint.key.databaseId = t_thrd.proc->databaseId;
 		breakpoint.key.functionId = funcOID;
 		breakpoint.key.lineNumber = lineNo;
-		breakpoint.key.targetPid  = MyProc->pid;
+        breakpoint.key.targetSessId  = MY_SESS_ID;
 
 		if( BreakpointDelete( BP_LOCAL, &breakpoint.key ))
 			dbg_send( "t" );
@@ -711,8 +713,10 @@ void clearBreakpoint( char * command )
 bool breakAtThisLine( Breakpoint ** dst, eBreakpointScope * scope, Oid funcOid, int lineNumber )
 {
 	BreakpointKey		key;
+	errno_t rc = memset_s(&key, sizeof(BreakpointKey), 0, sizeof(BreakpointKey));
+	securec_check(rc, "", "");
 
-	key.databaseId = MyProc->databaseId;
+	key.databaseId = t_thrd.proc->databaseId;
 	key.functionId = funcOid;
     key.lineNumber = lineNumber;
 
@@ -723,48 +727,7 @@ bool breakAtThisLine( Breakpoint ** dst, eBreakpointScope * scope, Oid funcOid,
 		return( TRUE );
 	}
 
-	/*
-	 *  We conduct 3 searches here.  
-	 *	
-	 *	First, we look for a global breakpoint at this line, targeting our
-	 *  specific backend process.
-	 *
-	 *  Next, we look for a global breakpoint (at this line) that does
-	 *  not target a specific backend process.
-	 *
-	 *	Finally, we look for a local breakpoint at this line (implicitly 
-	 *  targeting our specific backend process).
-	 *
-	 *	NOTE:  We must do the local-breakpoint search last because, when the
-	 *		   proxy attaches to our process, it marks all of its global
-	 *		   breakpoints as busy (so other potential targets will ignore
-	 *		   those breakpoints) and we copy all of those global breakpoints
-	 *		   into our local breakpoint hash.  If the debugger client exits
-	 *		   and the user starts another debugger session, we want to see the
-	 *		   new breakpoints instead of our obsolete local breakpoints (we
-	 *		   don't have a good way to detect that the proxy has disconnected
-	 *		   until it's inconvenient - we have to read-from or write-to the
-	 *		   proxy before we can tell that it's died).
-	 */
-
-	key.targetPid = MyProc->pid;		/* Search for a global breakpoint targeted at our process ID */
-  
-	if((( *dst = BreakpointLookup( BP_GLOBAL, &key )) != NULL ) && ((*dst)->data.busy == FALSE ))
-	{
-		*scope = BP_GLOBAL;
-		return( TRUE );
-	}
-
-	key.targetPid = -1;					/* Search for a global breakpoint targeted at any process ID */
-
-	if((( *dst = BreakpointLookup( BP_GLOBAL, &key )) != NULL ) && ((*dst)->data.busy == FALSE ))
-	{
-		*scope = BP_GLOBAL;
-		return( TRUE );
-	}
-
-	key.targetPid = MyProc->pid;	 	/* Search for a local breakpoint (targeted at our process ID) */
-
+    key.targetSessId = MY_SESS_ID;     /* Search for a local breakpoint (targeted at our process ID) */
 	if(( *dst = BreakpointLookup( BP_LOCAL, &key )) != NULL )
 	{
 		*scope = BP_LOCAL;
@@ -776,7 +739,7 @@ bool breakAtThisLine( Breakpoint ** dst, eBreakpointScope * scope, Oid funcOid,
 
 bool breakpointsForFunction( Oid funcOid )
 {
-	if( BreakpointOnId( BP_LOCAL, funcOid ) || BreakpointOnId( BP_GLOBAL, funcOid ))
+	if(BreakpointOnId( BP_LOCAL, funcOid ))
 		return( TRUE );
 	else
 		return( FALSE );
@@ -939,7 +902,7 @@ plugin_debugger_main_loop(void)
 
 	/* Initially, set focus on the topmost frame in the stack */
 
-	for( frame = error_context_stack; frame; frame = frame->previous )
+	for( frame = t_thrd.log_cxt.error_context_stack; frame; frame = frame->previous )
 	{
 		/*
 		 * ignore unrecognized stack frames.
@@ -1076,7 +1039,14 @@ plugin_debugger_main_loop(void)
 				lang->send_vars( frame );
 				break;
 			}
-					
+			case PLDBG_DISCONNECT:
+			{
+				closesocket(per_session_ctx.client_r);
+				per_session_ctx.client_r = per_session_ctx.client_w = 0;
+				connectAsServer();
+				lang->send_cur_line(frame);
+				break;
+			}
 			case PLDBG_RESTART:
 			case PLDBG_STOP:
 			{
@@ -1157,24 +1127,12 @@ send_breakpoints(Oid funcOid)
 	Breakpoint      * breakpoint;
 	HASH_SEQ_STATUS	  scan;
 
-	BreakpointGetList( BP_GLOBAL, &scan );
-
-	while(( breakpoint = (Breakpoint *) hash_seq_search( &scan )) != NULL )
-	{
-		if(( breakpoint->key.targetPid == -1 ) || ( breakpoint->key.targetPid == MyProc->pid ))
-			if( breakpoint->key.databaseId == MyProc->databaseId )
-				if( breakpoint->key.functionId == funcOid )
-					dbg_send( "%d:%d:%s", funcOid, breakpoint->key.lineNumber, "" );
-	}
-
-	BreakpointReleaseList( BP_GLOBAL );
-
 	BreakpointGetList( BP_LOCAL, &scan );
 
 	while(( breakpoint = (Breakpoint *) hash_seq_search( &scan )) != NULL )
 	{
-		if(( breakpoint->key.targetPid == -1 ) || ( breakpoint->key.targetPid == MyProc->pid ))
-			if( breakpoint->key.databaseId == MyProc->databaseId )
+        if ((breakpoint->key.targetSessId == InvalidSessId) || (breakpoint->key.targetSessId == MY_SESS_ID))
+			if( breakpoint->key.databaseId == t_thrd.proc->databaseId )
 				if( breakpoint->key.functionId == funcOid )
 					dbg_send( "%d:%d:%s", funcOid, breakpoint->key.lineNumber, "" );
 	}
@@ -1206,7 +1164,7 @@ select_frame(int frameNo, ErrorContextCallback **frame_p, debugger_language_t **
 {
 	ErrorContextCallback *frame;
 
-	for( frame = error_context_stack; frame; frame = frame->previous )
+	for( frame = t_thrd.log_cxt.error_context_stack; frame; frame = frame->previous )
 	{
 		debugger_language_t *lang = language_of_frame(frame);
 		if (!lang)
@@ -1256,7 +1214,7 @@ send_stack( void )
 {
 	ErrorContextCallback * entry;
 
-	for( entry = error_context_stack; entry; entry = entry->previous )
+	for( entry = t_thrd.log_cxt.error_context_stack; entry; entry = entry->previous )
 	{
 		/*
 		 * ignore frames we don't recognize
@@ -1273,32 +1231,22 @@ send_stack( void )
 
 
 /*-------------------------------------------------------------------------------------
- * The shared hash table for global breakpoints. It is protected by 
- * breakpointLock
- *-------------------------------------------------------------------------------------
- */
-static LWLockId  breakpointLock;
-static HTAB    * globalBreakpoints = NULL;
-static HTAB    * localBreakpoints  = NULL;
-
-/*-------------------------------------------------------------------------------------
- * The size of Breakpoints is determined by globalBreakpointCount (should be a GUC)
- *-------------------------------------------------------------------------------------
- */
-static int		globalBreakpointCount = 20;
-static Size		breakpoint_hash_size;
-static Size		breakcount_hash_size;
-
-/*-------------------------------------------------------------------------------------
+ * The shared hash table for global breakpoints. It is protected by breakpointLock
+ *
  * Another shared hash table which tracks number of breakpoints created
  * against each entity.
- *
  * It is also protected by breakpointLock, thus making operations on Breakpoints
  * BreakCounts atomic.
+ *
+ * The size of Breakpoints is determined by globalBreakpointCount (should be a GUC)
  *-------------------------------------------------------------------------------------
  */
-static HTAB *globalBreakCounts;
-static HTAB *localBreakCounts;
+static LWLockId  breakpointLock;
+static HTAB*     globalBreakpoints = NULL;
+static HTAB*     globalBreakCounts = NULL;
+static int		 globalBreakpointCount = 20;
+static Size		 breakpoint_hash_size;
+static Size		 breakcount_hash_size;
 
 typedef struct BreakCountKey
 {
@@ -1312,13 +1260,6 @@ typedef struct BreakCount
 	int				count;
 } BreakCount;
 
-/*-------------------------------------------------------------------------------------
- * Prototypes for functions which operate on GlobalBreakCounts.
- *-------------------------------------------------------------------------------------
- */
-static void initLocalBreakpoints(void);
-static void initLocalBreakCounts(void);
-
 static void   breakCountInsert(eBreakpointScope scope, BreakCountKey *key);
 static void   breakCountDelete(eBreakpointScope scope, BreakCountKey *key);
 static int    breakCountLookup(eBreakpointScope scope, BreakCountKey *key, bool *found);
@@ -1337,33 +1278,42 @@ static void reserveBreakpoints( void )
 #endif
 }
 
-static void
-initializeHashTables(void)
-{
-	LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE);
-
-	initGlobalBreakpoints();
-
-	LWLockRelease(AddinShmemInitLock);
-
-	initLocalBreakpoints();
-	initLocalBreakCounts();
-}
-
-static void
-initLocalBreakpoints(void)
+/*
+ * here we init:
+ * 1) local Breakpoint hatb
+ * 2) local breakpoint count hatb
+ */
+void initLocalBreakpoints(void)
 {
 	HASHCTL	ctl = {0};
-
 	ctl.keysize   = sizeof(BreakpointKey);
 	ctl.entrysize = sizeof(Breakpoint);
 	ctl.hash      = tag_hash;
+	ctl.hcxt      = PldbgMemoryContext;
 
-	localBreakpoints = hash_create("Local Breakpoints", 128, &ctl, HASH_ELEM | HASH_FUNCTION);
+	localBreakpoints = hash_create("Local Breakpoints", 128, &ctl, HASH_CONTEXT | HASH_ELEM | HASH_FUNCTION);
+	if (!localBreakpoints)
+        elog(ERROR, "could not initialize local breakpoints hash table");
+
+   	HASHCTL ctlc = {0};
+	ctlc.keysize   = sizeof(BreakCountKey);
+	ctlc.entrysize = sizeof(BreakCount);
+	ctlc.hash 	  = tag_hash;
+	ctlc.hcxt         = PldbgMemoryContext;
+
+	localBreakCounts = hash_create("Local Breakpoint Count Table", 32, &ctlc, HASH_CONTEXT | HASH_ELEM | HASH_FUNCTION );
+	if (!localBreakCounts)
+        elog(ERROR, "could not initialize local breakpoints count hash table");
 }
 
-void
-initGlobalBreakpoints(void)
+/*
+ * here we init:
+ *    1) Global breakpoint Lock
+ *    2) Global Breakpoint list
+ *    3) Global BreakCounts Table
+ * in share memory.
+ */
+void initGlobalBreakpoints(void)
 {
 	bool   	  		found;
 	int				tableEntries = globalBreakpointCount;
@@ -1371,24 +1321,17 @@ initGlobalBreakpoints(void)
 	HASHCTL breakpointCtl = {0};
 	HASHCTL breakcountCtl = {0};
 
-	gbpd = ShmemInitStruct("Global Breakpoint Data",
-						   sizeof(GlobalBreakpointData), &found);
+        LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE);
+	gbpd = (GlobalBreakpointData*)ShmemInitStruct("Global Breakpoint Data", sizeof(GlobalBreakpointData), &found);
+
 	if (gbpd == NULL)
 		elog(ERROR, "out of shared memory");
 
-#if (PG_VERSION_NUM >= 90600)
-	if (!found)
-	{
-		gbpd->tranche_id = LWLockNewTrancheId();
-		LWLockInitialize(&gbpd->lock, gbpd->tranche_id);
-	}
-	{
-		static LWLockTranche tranche;
-
-		tranche.name = "pldebugger";
-		tranche.array_base = &gbpd->lock;
-		tranche.array_stride = sizeof(LWLock);
-		LWLockRegisterTranche(gbpd->tranche_id, &tranche);
+#if (PG_VERSION_NUM >= 90204)
+    if (!found) {
+			/* Convert to array index. */
+		LWLockRegisterTranche((int)LWTRANCHE_PLDEBUG, "pldebugger");
+		LWLockInitialize(&gbpd->lock, (int)LWTRANCHE_PLDEBUG);
 
 		breakpointLock = &gbpd->lock;
 	}
@@ -1419,6 +1362,8 @@ initGlobalBreakpoints(void)
 
 	globalBreakCounts = ShmemInitHash("Global BreakCounts Table", tableEntries, tableEntries, &breakcountCtl, HASH_ELEM | HASH_FUNCTION);
 
+    LWLockRelease(AddinShmemInitLock);
+
 	if (!globalBreakCounts)
 		elog(FATAL, "could not initialize global breakpoints count hash table");
 }
@@ -1427,7 +1372,7 @@ initGlobalBreakpoints(void)
 /* ---------------------------------------------------------
  * getPLDebuggerLock()
  *
- *	Returns the lockid of the lock used to protect pldebugger shared memory
+ *	Returns the lock used to protect pldebugger shared memory
  *  structures. The lock is called breakpointLock in this file, but it's
  *  also shared by dbgcommm.c.
  */
@@ -1435,8 +1380,8 @@ initGlobalBreakpoints(void)
 LWLockId
 getPLDebuggerLock(void)
 {
-	if( localBreakpoints == NULL )
-		initializeHashTables();
+	if( breakpointLock == NULL )
+		initGlobalBreakpoints();
 
 	return breakpointLock;
 }
@@ -1455,8 +1400,8 @@ getPLDebuggerLock(void)
 static void
 acquireLock(eBreakpointScope scope, LWLockMode mode)
 {
-	if( localBreakpoints == NULL )
-		initializeHashTables();
+	if( breakpointLock == NULL )
+		initGlobalBreakpoints();
 
 	if (scope == BP_GLOBAL)
 		LWLockAcquire(breakpointLock, mode);
@@ -1517,7 +1462,7 @@ BreakpointOnId(eBreakpointScope scope, Oid funcOid)
 	bool			found = false;
 	BreakCountKey	key;
 
-	key.databaseId = MyProc->databaseId;
+	key.databaseId = t_thrd.proc->databaseId;
 	key.functionId = funcOid;
 
 	acquireLock(scope, LW_SHARED);
@@ -1648,7 +1593,7 @@ BreakpointBusySession(int pid)
 			 * will ignore it)
 			 */
 
-			localCopy.key.targetPid = MyProc->pid;
+            localCopy.key.targetSessId = t_thrd.proc->pid;
 
 			BreakpointInsertOrUpdate(BP_LOCAL, &localCopy.key, &localCopy.data );
 		}
@@ -1763,11 +1708,11 @@ BreakpointShowAll(eBreakpointScope scope)
 
 	while((entry = (Breakpoint *) hash_seq_search(&status)))
 	{
-		elog(INFO, "Database(%d) function(%d) lineNumber(%d) targetPid(%d) proxyPort(%d) proxyPid(%d) busy(%c) tmp(%c)",
+        elog(INFO, "Database(%d) function(%d) lineNumber(%d) targetSessId(%ld) proxyPort(%d) proxyPid(%d) busy(%c) tmp(%c)",
 			 entry->key.databaseId,
 			 entry->key.functionId,
 			 entry->key.lineNumber,
-			 entry->key.targetPid,
+             entry->key.targetSessId,
 			 entry->data.proxyPort,
 			 entry->data.proxyPid,
 			 entry->data.busy ? 'T' : 'F',
@@ -1823,32 +1768,6 @@ void BreakpointCleanupProc(int pid)
 	releaseLock(BP_GLOBAL);
 }
 
-/* ==========================================================================
- * Function definitions for BreakCounts hash table
- *
- * Note: All the underneath functions assume that the caller has taken care
- * of all concurrency issues and thus does not do any locking
- * ==========================================================================
- */
-
-static void
-initLocalBreakCounts(void)
-{
-	HASHCTL ctl = {0};
-
-	ctl.keysize   = sizeof(BreakCountKey);
-	ctl.entrysize = sizeof(BreakCount);
-	ctl.hash 	  = tag_hash;
-
-	localBreakCounts = hash_create("Local Breakpoint Count Table",
-								   32,
-								  &ctl,
-								  HASH_ELEM | HASH_FUNCTION );
-
-	if (!globalBreakCounts)
-		elog(FATAL, "could not initialize global breakpoints count hash table");
-}
-
 /* ---------------------------------------------------------
  * breakCountInsert()
  *
@@ -1860,7 +1779,7 @@ breakCountInsert(eBreakpointScope scope, BreakCountKey *key)
 	BreakCount *entry;
 	bool		found;
 	
-	entry = hash_search(getBreakCountHash(scope), key, HASH_ENTER, &found);
+	entry = (BreakCount*)hash_search(getBreakCountHash(scope), key, HASH_ENTER, &found);
 	
 	if (found)
 		entry->count++;
@@ -1878,7 +1797,7 @@ breakCountDelete(eBreakpointScope scope, BreakCountKey *key)
 {
 	BreakCount		*entry;
 	
-	entry = hash_search(getBreakCountHash(scope), key, HASH_FIND, NULL);
+	entry = (BreakCount*)hash_search(getBreakCountHash(scope), key, HASH_FIND, NULL);
 	
 	if (entry)
 	{
@@ -1900,7 +1819,7 @@ breakCountLookup(eBreakpointScope scope, BreakCountKey *key, bool *found)
 {
 	BreakCount		*entry;
 	
-	entry = hash_search(getBreakCountHash(scope), key, HASH_FIND, found);
+	entry = (BreakCount*)hash_search(getBreakCountHash(scope), key, HASH_FIND, found);
 	
 	if (entry)
 		return entry->count;
@@ -1914,12 +1833,11 @@ breakCountLookup(eBreakpointScope scope, BreakCountKey *key, bool *found)
  *	Returns a pointer to the global or local breakpoint hash,
  *	depending on the given scope.
  */
-
 static HTAB *
 getBreakpointHash(eBreakpointScope scope )
 {
-	if( localBreakpoints == NULL )
-		initializeHashTables();
+	if( globalBreakpoints == NULL )
+		initGlobalBreakpoints();
 
 	if (scope == BP_GLOBAL)
 		return globalBreakpoints;
@@ -1933,12 +1851,11 @@ getBreakpointHash(eBreakpointScope scope )
  *	Returns a pointer to the global or local breakcount hash,
  *	depending on the given scope.
  */
-
 static HTAB *
 getBreakCountHash(eBreakpointScope scope)
 {
-	if( localBreakCounts == NULL )
-		initializeHashTables();
+	if( globalBreakCounts == NULL )
+		initGlobalBreakpoints();
 
 	if (scope == BP_GLOBAL)
 		return globalBreakCounts;
diff --git a/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/uninstall_pldbgapi.sql b/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/uninstall_pldbgapi.sql
index 568d053..fa8ab8c 100644
--- a/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/uninstall_pldbgapi.sql
+++ b/gpl_dependency/pldebugger/gplsrc/pldebugger_3_0/uninstall_pldbgapi.sql
@@ -7,27 +7,22 @@
 -- versions, however.
 --
 
-DROP FUNCTION pldbg_get_target_info(TEXT, "char");
-DROP FUNCTION pldbg_wait_for_target(INTEGER);
-DROP FUNCTION pldbg_wait_for_breakpoint(INTEGER);
 DROP FUNCTION pldbg_step_over(INTEGER);
 DROP FUNCTION pldbg_step_into(INTEGER);
-DROP FUNCTION pldbg_set_global_breakpoint(INTEGER, OID, INTEGER, INTEGER);
 DROP FUNCTION pldbg_set_breakpoint(INTEGER, OID, INTEGER);
-DROP FUNCTION pldbg_select_frame(INTEGER, INTEGER);
 DROP FUNCTION pldbg_get_variables(INTEGER);
 DROP FUNCTION pldbg_get_proxy_info();
 DROP FUNCTION pldbg_get_stack(INTEGER);
 DROP FUNCTION pldbg_get_source(INTEGER, OID);
 DROP FUNCTION pldbg_get_breakpoints(INTEGER);
 DROP FUNCTION pldbg_drop_breakpoint(INTEGER, OID, INTEGER);
-DROP FUNCTION pldbg_deposit_value(INTEGER, TEXT, INTEGER, TEXT);
-DROP FUNCTION pldbg_create_listener();
 DROP FUNCTION pldbg_continue(INTEGER);
 DROP FUNCTION pldbg_attach_to_port(INTEGER);
 DROP FUNCTION pldbg_abort_target(INTEGER);
 DROP FUNCTION pldbg_oid_debug(OID);
 DROP FUNCTION plpgsql_oid_debug(OID);
+DROP FUNCTION plpgsql_off();
+DROP FUNCTION plpgsql_on();
 
 DROP TYPE proxyInfo;
 DROP TYPE var;