Thread: Trouble with the PL/pgSQL debugger and VC++
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
> 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
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