/*****************************************************************************
*
* This document is licensed under GNU GPL 2.0 (www.gnu.org/copyleft/gpl.html)
*
* Author : singh.gurjeet@{gmail | hotmail | yahoo }.com
*
*****************************************************************************/
Purpose:
========
To be able to debug postgres on Windows using a GUI IDE.
Target Audience:
================
Windows developers who have never compiled/linked/run postgres on Windows.
Developers who have experience of compiling postgres using Cygwin/MSYS/MinGW
but would like to debug using a GUI.
IDE:
====
Eclipse + CDT plug-in.
Pre-requisites:
===============
The Msys toolkit + a few mingw tools.
Advantages:
===========
Using the combination of Eclipse + CDT + msys, from within the IDE you can:
1) Browse the code in a Visual Editor.
2) Search for declarations/definitions of C/C++ symbols within the IDE.
2) Compile the PGSQL binary from within the IDE.
3) Attach to a running postgres.exe and debug it.
4) All this, without having to create projects, or deciding which files
should you include in the IDE's project! It'll automatically create
the project based on your makefiles.
Well, since version 8.0, postgres is being compiled natively on Windows;
before that, Cygwin emulation layer was used to compile and run postgres
on Windows. So, since 8.0, PGSQL is able to do almost everything on
Windows, that it can do on a Nixen1; like creating
tablespaces, for which links are used on Nixen, and junction-points are
used on Windows (supported only by NTFS 5.0 or greater).
So, here it goes:
Download:
=========
Download the following packages from the sites listed before them:
http://www.mingw.org/download.shtml MSYS-1.0.10.exe
http://www.mingw.org/download.shtml msysDTK-1.0.1.exe
http://www.mingw.org/download.shtml mingw32-make-3.80.0-3.exe
http://www.mingw.org/download.shtml gdb-5.2.1-1.exe
http://www.mingw.org/download.shtml mingw-runtime-3.9.tar.gz
http://www.mingw.org/download.shtml mingw-utils-0.3.tar.gz
http://www.mingw.org/download.shtml gcc-core-3.4.2-20040916-1.tar.gz
http://www.mingw.org/download.shtml gcc-g_-3.4.2-20040916-1.tar.gz
http://www.mingw.org/download.shtml w32api-3.6.tar.gz
http://www.mingw.org/download.shtml binutils-2.15.91-20040904-1.tar.gz
http://www.mingw.org/download.shtml bison-2.0-MSYS.tar.gz
http://sourceforge.net/projects/gnuwin32 flex-2.5.4a-1-bin.zip
http://www.eclipse.org/ eclipse-SDK-3.1.2-win32.zip
http://www.eclipse.org/cdt/ org.eclipse.cdt-3.0.2-win32.x86.zip
OR
http://download.eclipse.org/tools/cdt/releases/eclipse3.1/dist/3.0.2/
Install the msys + mingw toolkit:
=================================
Install the packages in the following order to the locations specified.
Remember to read notes under 'My Configuration' section below.
MSYS-1.0.10.exe D:\msys\1.0
msysDTK-1.0.1.exe D:\msys\1.0
mingw32-make-3.80.0-3.exe D:\msys\1.0\mingw
gdb-5.2.1-1.exe D:\msys\1.0\mingw
Now _copy_ all the *.tar.gz files, except for 'bison-2.0-MSYS.tar.gz',
listed above to the folder D:/msys/1.0/mingw/ .
Open the msys console (or the 'shell' if you prefer), from the 'Programs'
menu (or the Desktop, if you creaed a shortcut there). Then execute the
following list of commands, one after the other, looking for any errors
after each one of them:
cd /mingw
for i in `ls *.tar.gz`; do tar xfz $i; done
cp -a /mingw/mingw32/* /mingw
A note of caution from AumAum's page (see 'Acknowledgement' below):
It's crucial to crack the tarballs into /mingw (D:\msys\n.n\mingw),
because if you crack any of them into / (D:\msys\n.n), you'll cause
some subtle conflicts between MSYS and the MinGW tools which will cause
your compilations to fail.
Now, test that your compiler is working fine; execute the following
commands (in msys shell):
cd ~
cat > hello.c << EOF
#include
int main(){printf( "Hello World\n" ); }
EOF
gcc hello.c
./a.exe
If you see the greeting 'Hello World' after executing a.exe, then
congratulations.... you have the msys toolkit working.
Using WinZip or some such utility (use free alternative IZarc.org), extract
'flex-2.5.4a-1-bin.zip' to D:/msys/1.0/mingw/ and 'bison-2.0-MSYS.tar.gz'
to D:\msys\1.0 .
At this point, you can delete the *.tar.gz files that were copied into
D:/msys/1.0/mingw/ .
And delete the hello.c and a.exe using the following commands
(in msys shell):
cd ~
rm hello.c a.exe
Test postgres compilability:
============================
Now its time to test if this setup can actually compile postgres sources...
If you have not done it yet, then get the sources of postgres (using CVS
or the per-release tarball from the site), let's say in the directory
D:/Dev/postgres/pgsql_tip/ .
Note: In the msys shell, the Windows' drives are accessed as /a OR /b OR /c
etc. So, in the following command-set, I am trying to install postgres in
the Windows' F:/pgsql .
In the msys shell, execute the following commnads (first read the
'A few tricks' section below):
cd /d/Dev/postgres/pgsql_tip
make distclean
./configure --without-zlib --enable-debug --prefix=/f/pgsql
make
make install
If everything goes well, you should have a directory tree under F:/pgsql/
that has all the binaries to run postgres. But you won't be able to run
postgres; at least not if you are logged in a an Administrator or a login
with Administrators group. This is because postgres is designed not to
run with Administrator privileges; so that the security of you machine is
not compromised even if somebody is able to break into postgres.
Setup the environment:
======================
Add the following to your PATH environment variable in Windows:
;D:\msys\1.0\mingw\bin;D:\msys\1.0\bin;F:\pgsql\bin;F:\pgsql\lib
(instructions: right-click 'My Computer' > Properties > Advanced >
'Environment Variables' )
This will enable you to run MinGW and postgres cammands from Windows' cmd
prompt. Alternatively, create a file setpgenv.bat with the following
contents and execute it from the cmd.exe everytime you wish to use MinGW
commands:
E:\WINNT\system32\chcp.com 1252
set PATH=%PATH%;D:\msys\1.0\mingw\bin;D:\msys\1.0\bin;F:\pgsql\bin;F:\pgsql\lib
Create a file setpgenv.sh with the following contents:
#!/bin/sh
/e/WINNT/system32/chcp.com 1252
PATH=$PATH:/d/msys/1.0/mingw/bin:/d/msys/1.0/bin:/f/pgsql/bin:/f/pgsql/lib
and include a line like the following in your msys' /etc/profile file:
source /d/Dev/postgres/setpgenv.sh
Remember, all the steps listed above are to be performed as the logged in
user, not for the user you are going to create next.
Create a user by the name postgres on your machine. (Read the docs for your
version of Windows to know how to do it.)
Assign a password to this user, and remember it.
Test postgres:
==============
To run and test postgres, do the following:
Run the following command in cmd.exe or the Start > Run dialog box:
runas /env /user:postgres cmd
when asked for the password, key in the password you assigned to the user
postgres. And... you are logged in as user postgres.
Reminder: the /env switch to the runas command passes on the current
environment to the new process being created. So, you have to either set
the msys/mingw/pgsql variables in your PATH variable, or run the
setpgenv.bat file before running this command.
From within this new console, fire up the msys shell using the following
command:
sh
Now set the environment variables so that the postgres' utilities can be
found on the $PATH variable (no need to do this if you have set these in
the First user's environment varaible).
source /d/Dev/postgres/setpgenv.sh
Now we can run the postgres RDBMS as this user and test if it is working
fine. To do so, run the following commands:
initdb -D /f/pgsql/data
pg_ctl -D /f/pgsql/data/ -l /f/pgsql/pgsql.log start
pg_ctl -D /f/pgsql/data/ status
createdb test
psql test
create table t( a int );
insert into t values ( 1 );
insert into t values ( 2 );
select * from t;
Optionally, to run the regression tests, run the following commands:
cd /d/Dev/postgres/pgsql_tip/src/test/regress
make clean all runtest
Note: there may be a few 'timeout' errors, you can safely ignore them. If
the tablespace testing scripts fail, then make sure that the value of the
--prefix switch of 'configure', i.e. /f/pgsql/, points to a NTFS 5.0
partition; you might have to 'make install' postres again.
Install Eclipse + CDT:
======================
Extract the eclipse-SDK-3.1.2-win32.zip package to a folder of your choice.
Extract org.eclipse.cdt-3.0.2-win32.x86.zip to the same directory. This will
extract all the CDT related files into the 'plugins' directory.
Create the Workspace and the project:
=====================================
Create a directory Eclipse_Workspace at your favourite place except anywhere
under Postgres source's directory.
D:/Dev/postgres/Eclipse_Workspace/
Run the eclipse.exe file from the installation directory.
If shown the dialog-box to choose a workspace, point it to the above created
directory, otherwise, go to File > 'Switch Workspace' and point it to the
above created directory.
go to Window > 'Open Perspective' > Other > C/C++ .
This will switch to the CDT plugin. Now we wre ready to create a C/C++
project.
go to File > New > 'Standard make C project'
Give the project a name 'pgsql_tip'. And uncheck the 'Use Default' box, and
point it to your postgres' source directory.
D:/Dev/postgres/pgsql_tip/
Click Next, and under the 'C/C++ Indexer' tab choose 'No Indexer'. We are
disabling the indexer just so that it doesn't slow down the computer
right now. We can/will switch on the Indexer again later.
The moment you click Finish, Eclipse/CDT runs the following command
'make clean all', which in effect tries to rebuild the whole project
using the GNUMakefile in the root of the project. You can see the
progress in the 'Console' view or the 'Progress' view.
Reminder: You must have the msys/mingw environment variables set for Eclipse
to find the right make/gcc/gdb tools. If not set in the PATH variable,
then you must run the setpgenv.bat in a console and run Eclipse.exe from
within that cmd.exe .
Now, right-click on the project (in the 'C/C++ Projects' view), and click on
'Build Make Target...'. In the resulting dialog box, click on 'Add' and
assign 'Target Name' as 'clean', 'Make Target' as 'clean', leave the
check-box 'Use default' checked, and click on create.
Create another entry named 'all', following the same steps as described
above.
From now on, we'll use these 'make' targets to build or clean the postgres
binaries.
Right-click on the project (in the 'C/C++ Projects' view), click on
properties, and select 'C/C++ Make Project' in the left pane. Select the
'Binary Parser' tab, and check the check-box against 'PE Windows Parser'.
This will allow the CDT to auto-discover the binaries built by a make
command, and allow you to attach to a running process with the same image.
Note: You might not encounter this following problem, but I do always.
During the 'make all' session, the make command fails with the error
'The system cannot find the file specified.' when trying to execute the
following command:
AWK='gawk' /bin/sh.exe Gen_fmgrtab.sh ../../../src/include/catalog/pg_proc.h
So, all that I do is open the msys shell, and execute the following commands:
cd /d/Dev/postgres/pgsql_tip/src/backend/utils/
AWK='gawk' /bin/sh.exe Gen_fmgrtab.sh ../../../src/include/catalog/pg_proc.h
and come back to Eclipse, right-click on pgsql_tip project (in the
'C/C++ Projects' view) and issue the 'Build Make Target...' command.
Note: if you haven't run the 'Test postgres compilability' section above,
then you have to run atleast the 'configure' command listed in that
section for 'make' to be able to compile the project.
Finally, in the 'Console' view of Eclipse, you should see the statement
'All of PostgreSQL successfully made. Ready to install.'. This means,
everything went fine, and we have successfully compiled postgres from
within the IDE.
Debugging postgres:
===================
Open cmd.exe as user postgres. (Follow the instructions under the section
'Test postgres' till 'source setpgenv.sh'.)
Execute the following command in the resulting msys shell to get postmaster
(postgres' master process) running:
pg_ctl -D /f/pgsql/data/ start -l /f/pgsql/pgsql.log
Open another cmd.exe as user postgres, and run eclipse.exe from within that.
Something like:
D:\Dev\eclipse-SDK-3.1.2-win32\eclipse.exe
Eclipse needs to be run as OS user postgres because all the postgres' shadow
processes forked from now on will be running with the OS user postgres'
permissions; and to attach a debugger to that process, you should be
running the debugger as that user.
Reminder: Do not close the cmd.exe window from which you have started
postmaster (using the pg_ctl command). Although that process has been
sent to the background, still the whole database will come down if you
close that window.
Again, msys/mingw need to be a part of the $PATH variable before you start
eclipse.
If not opened by default, open the workspace created earlier (see section
'Create the Workspace and the project'), and switch to C/C++ perspective.
Open a new cmd.exe (not necessarily as user postgres), and launch
psql test postgres
This will connect to database 'test' as user 'postgres'.
Find the process-id of the shadow process of this connection.
(To find this pid, open Task Manager before launching 'psql', and note
down the pids of all the postgres.exes running. Now launch psql as above,
and find the new postmaster.exe which wasn't present before. (the ps
command doesn't seem to be showing processes from other users) )
Back in Eclipse, click on the Debug button on the toolbar(the one with bug
in the icon). If it is the first time, it shows a dialog box 'Debug'.
Click on 'C/C++ Attach to Local Application', and if a configuration
doesn't exist under it, then click on the button 'New' to create a new
configuration under it.
For this configuration, under the 'Main' tab, in 'Project' text-box, write
the name of your project (pgsql_tip) or click on 'Browse' button to see a
list of projects in your workspace.
For the 'C/C++ Application' text-box, click on 'Search Project...' button to
see a list of binaries discovered by the binary parsers associated with
the workspace. Choose 'postgres.exe' and click 'OK'.
Explore the other tabs too, but for now, accept the defaults, and click on
'Apply' and then click on 'Debug' button.
CDT will pop-up a list of processes running on the machine. You would find
quite a few postgres.exes, choose the one with the pid that we noted
earlier, and click 'OK'.
If/When asked to switch Perspective to 'Debug', click 'OK'. This will switch
from C/C++ perspective to Debug perspective, which allows you to do all
the tasks related to debugging; like viewing the stack, viewing local
variables' values, view memory, etc. etc. .
Well, once you are in the Debug perspective, you will be shown a stack in a
view named 'Debug'. Right now, all the threads of the debugger are
'Suspended'. Here, open up the threads, and under each you will see a
stack of each of the threads. Double click on the one that says
'pgwin32_recv() at socket.c:248 ...', and the corresponding code will
pop-up in the editor window. Double-clicking on the grey bar to the left
in the editor will put a breakpoint. Put a breakpoint on the line that
says WSARecv( ... ). Click on the green arrow in the 'Debug' view; this
will allow all the suspended threads to resume execution.
Go back to the psql prompt, and fire up a SQL query, the debugger will stop
at the breakpoint you just created, and you can take control from there.
We have deferred source code indexing till now because it consumes a lot of
CPU and a lot of memory, which would slow down you other processing. To
enable indexer, right-click on the project in the 'C/C++ projects' view,
and select 'Properties'. Select 'C/C++ Indexer' in the left pane, and
from the drop-down list choose 'Full C/C++ Indexer' and click 'OK'.
The moment you finish this task, the indexer will start in the background;
be patient, it might make Eclipse hung at times, but it will come back.
A few tricks:
=============
1) You should use the switch --enable-debug for the configure script; if you
don't, then gdb won't be able to show you the lines, and hence, you won't
see any source code in the Eclipse.
2) Open the 'configure' file from the source root of pgsql
(pgsql_tip/configure), and find the line with the following contents:
elif test "$GCC" = yes; then
CFLAGS="-O2"
And change
CFLAGS="-O2"
to
CFLAGS="-O0"
This change will disable the optimizations done by the compiler. We need to
do this, otherwise, while debugging, the pointer in the editor will not
follow the flow of the code.
After this change to the 'configure' script, make sure you run the configure
script again with --enable-debug switch.
My Configuration:
=================
TODO : finish this section
I used PG 8.0.3
1 Nixen : member of Unix clan. Same word is used for plural too.
Acknowledgement: It wasn't possible for me to get the steps right for installing
msys + mingw, if not for the following document:
http://www.mingw.org/MinGWiki/index.php/RealDumbQuickstart
Yes, I had to help from this page specially written for _dumb_ starters.
Every time I tried my hands on installing both msys and mingw alogside
each other, I made a constant mistake; and the 'get more involved'
section in this page helped me to sort it out. Although, I made a subtle
change in the placing of mingw tools in this document. Thanks again to
'AumAum'.