Trouble with the PL/pgSQL debugger and VC++

Started by Charlie Savageover 18 years ago3 messages
#1Charlie Savage
cfis@savagexi.com

Hi Korry,

I am having problems with getting the debugger to work. Setup:

OS: Windows XP
Postgresql Version: 8.2.4 compiled with VC++ 2005

Since my version of pg is built with VC++ I thought it wise to also use
VC++ for the debugger plugin. So I converted the Makefile into 3
different VC++ projects - pldbgapi, plugin_debugger and targetinfo.
Note that targetinfo is not mentioned at all in the comments at the top
of Makefile - you may wish to update them.

VC++ did not compile the code as is, I've attached a patch below with
the changes I had to make. I also generated the appropriate DEF files
(using the perl scripts in postgresql-8.2.4\src\tools\msvc). I also had
to define a preprocess define, __WIN32__ (line 1524, pldgbapi.c). Maybe
you could use something more standard, like _WIN32?

I was then able to build the dlls except the profiler (for some reason
the struct timezone wasn't being picked up via the includes - but I left
that for another day).

I then installed the dlls as per the instructions and updated my
postgresql.conf file.

However, I can't set any breakpoints using PgAdmin. I know the dlls are
loaded via Process Explorer, and in fact I can attach to them with the
VC++ debugger.

So then I tried running through your command line example (using the
PgAdmin sql window and then psql) and here are the results:

1. CREATE OR REPLACE FUNCTION testwhere(x int)
RETURNS int AS
$$
DECLARE
result int;
BEGIN
result := x + 1;
RETURN x;
END;
$$
LANGUAGE 'plpgsql' STABLE;

2. SELECT * FROM pldbg_get_target_info( 'testwhere', 'f' );

target;schema;nargs;argtypes;targetname;argmodes;argnames;targetlang;fqname;returnsset;returntype
80655;79041;1;23;testwhere;;{x};77823;core.testwhere;f;23

3. SELECT * FROM pldbg_create_listener();

pldbg_create_listener
1

4. SELECT * from pldbg_set_global_breakpoint(1, 80655, NULL, NULL);

pldbg_set_global_breakpoint
t

5. SELECT * FROM pldbg_wait_for_target(1);

At this point the session hangs, as explained in your email. So what
happens next? I tried:

* Opening a new pgadmin window and doing step 6 (SELECT * FROM
pldbg_wait_for_breakpoint(1);). That didn't work.

* I tried executing the function (select testwhere(7);). That didn't work.

Any tips/help appreciated. Like I said, I can step through the code in
the VC++ debugger so I can pretty much look at anything that might be
helpful.

And I'd be happy to send along the VC++ project files and DEF files if
you'd like them.

Thanks,

Charlie

--------------------

Only in .: msvc
diff -u /c/temp/contrib/pldebugger/pldbgapi.c ./pldbgapi.c
--- /c/temp/contrib/pldebugger/pldbgapi.c	2007-07-29 17:09:46 -0600
+++ ./pldbgapi.c	2007-09-06 00:34:29 -0600
@@ -1560,6 +1560,12 @@
  }
  static int allocateServerListener( int * port )
  {
+#ifdef WIN32
+	WORD 		wVersionRequested;
+	WSADATA 	wsaData;
+	int 		err;
+	u_long blockingMode = 0;
+#endif
  	int	 						sockfd       	= socket( AF_INET, SOCK_STREAM, 0 );
  	struct sockaddr_in 			proxy_addr     	= {0};
  	socklen_t					proxy_addr_len 	= sizeof( proxy_addr );
@@ -1571,9 +1577,6 @@
  	proxy_addr.sin_addr.s_addr = htonl( INADDR_ANY );

#ifdef WIN32
- WORD wVersionRequested;
- WSADATA wsaData;
- int err;

wVersionRequested = MAKEWORD( 2, 2 );

@@ -1617,7 +1620,6 @@
listen( sockfd, 2 );

#ifdef WIN32
- u_long blockingMode = 0;

  	ioctlsocket( sockfd, FIONBIO,  &blockingMode );
  #endif
Only in .: pldebugger
diff -u /c/temp/contrib/pldebugger/plugin_debugger.c ./plugin_debugger.c
--- /c/temp/contrib/pldebugger/plugin_debugger.c	2007-08-07 10:37:14 -0600
+++ ./plugin_debugger.c	2007-09-06 00:34:58 -0600
@@ -1143,16 +1143,18 @@
  	int	 				client_sock;
  	int					reuse_addr_flag = 1;
+#ifdef WIN32
+	WORD wVersionRequested;
+	WSADATA wsaData;
+	int err;
+	u_long blockingMode = 0;
+#endif
  	/* Ask the TCP/IP stack for an unused port */
  	srv_addr.sin_family      = AF_INET;
  	srv_addr.sin_port        = htons( 0 );
  	srv_addr.sin_addr.s_addr = htonl( INADDR_ANY );

#ifdef WIN32
- WORD wVersionRequested;
- WSADATA wsaData;
- int err;
-
wVersionRequested = MAKEWORD( 2, 2 );

err = WSAStartup( wVersionRequested, &wsaData );
@@ -1197,7 +1199,6 @@
listen( sockfd, 2 );

#ifdef WIN32
- u_long blockingMode = 0;

ioctlsocket( sockfd, FIONBIO, &blockingMode );
#endif

#2korry.douglas
korry.douglas@enterprisedb.com
In reply to: Charlie Savage (#1)
Re: Trouble with the PL/pgSQL debugger and VC++

Since my version of pg is built with VC++ I thought it wise to also
use VC++ for the debugger plugin. So I converted the Makefile into 3
different VC++ projects - pldbgapi, plugin_debugger and targetinfo.
Note that targetinfo is not mentioned at all in the comments at the
top of Makefile - you may wish to update them.

Hi Charlie, thanks for the feedback (and thanks for the patches!).

Can you e-mail the VC++ projects that you created? (You can do that
off-list). I have VC++ here but I haven't tried to do a PG build in
that environment yet (guess it's time to learn).

However, I can't set any breakpoints using PgAdmin. I know the dlls
are loaded via Process Explorer, and in fact I can attach to them with
the VC++ debugger.

When you say that you can't set any breakpoints using PgAdmin, does that
mean that the menu choices ("Set Breakpoint" and "Debug") just don't
appear? Or are they there but don't do anything? Or are you getting an
error message?

Can you gather a PgAdmin log file (see Options on the File Menu, then
choose the Logging tab, check "Debug") and send it to me. That will
give me some clues.

5. SELECT * FROM pldbg_wait_for_target(1);

At this point the session hangs, as explained in your email. So what
happens next? I tried:

* Opening a new pgadmin window and doing step 6 (SELECT * FROM
pldbg_wait_for_breakpoint(1);). That didn't work.

That won't work... you want to open another session and SELECT
testwhere(7) from the new session.

The first session is your debugger client, the second session is the
target process (the application that you are debugging).

* I tried executing the function (select testwhere(7);). That didn't
work.

I presume that you mean that the debugger session was still hung in the
call to pldbg_wait_for_target(1), right?

Did you remember to set shared_preload_librarys =
'$libdir/plugins/plugin_debugger' in your postgresql.conf file (and
restart the server aftwards)?.

-- Korry

#3Charlie Savage
cfis@savagexi.com
In reply to: korry.douglas (#2)
Re: Trouble with the PL/pgSQL debugger and VC++

Hi Korry,

Can you e-mail the VC++ projects that you created? (You can do that
off-list). I have VC++ here but I haven't tried to do a PG build in
that environment yet (guess it's time to learn).

Done.

However, I can't set any breakpoints using PgAdmin. I know the dlls
are loaded via Process Explorer, and in fact I can attach to them with
the VC++ debugger.

When you say that you can't set any breakpoints using PgAdmin, does that
mean that the menu choices ("Set Breakpoint" and "Debug") just don't
appear? Or are they there but don't do anything? Or are you getting an
error message?

Let me see if I can clarify. Both choices are available from the
PgAdmin menu.

When I choose Debug a window opens asking me to set the value for the
parameter to the fucntion I do that, hit OK. But then the window just
reappears again.

If instead I do "Set Breakpoint" then I get a window that says "Waiting
to set breakpoint in core.testwhere" with a progress bar (note there is
a debugger window behind it also). That window never goes away. When I
press cancel I get a Debug Assertion Failure:

close.c, line 47
Expression (fh >= 0 && (unsigned)fh < (unsigned)_nhandle)

Can you gather a PgAdmin log file (see Options on the File Menu, then
choose the Logging tab, check "Debug") and send it to me. That will
give me some clues.

Yes, will do.

* Opening a new pgadmin window and doing step 6 (SELECT * FROM
pldbg_wait_for_breakpoint(1);). That didn't work.

That won't work... you want to open another session and SELECT
testwhere(7) from the new session.

I thought each pgadmin sql window was its own session though (they have
different backend pids)? No?

The first session is your debugger client, the second session is the
target process (the application that you are debugging).

* I tried executing the function (select testwhere(7);). That didn't
work.

I presume that you mean that the debugger session was still hung in the
call to pldbg_wait_for_target(1), right?

Did you remember to set shared_preload_librarys =
'$libdir/plugins/plugin_debugger' in your postgresql.conf file (and
restart the server aftwards)?.

Yes. And checked it a few times :)

FYI the readme includes the .so ($libdir/plugins/plugin_debugger.so') if
I remember correctly, might want to remove that.

Charlie