Category Archives: C++

Compiling GDB Debugger in Windows

Here are the steps:

  1. Download 7-zip, if you do not have one.
  2. Install MinGW, please read MinGW’s Getting Started wiki. I choose manual installation:

    Download at least the following (or newer) packages from the MinGW download page:

    • binutils
    • gcc-core
    • mingw-runtime
    • w32api
    • expat

    Unpack them directly to D:\mingw

    Expat
    GDB can use the Expat XML parsing library. This library may be included with your operating system distribution; if it is not, you can get the latest version from http://expat.sourceforge.net.
    The `configure' script will search for this library in several standard locations; if it is installed in an unusual path, you can use the `–with-libexpat-prefix’ option to specify its location.

    Expat is used for:

    To download expat for MinGW, please visit here.

    For more about expat, please visit http://sources.redhat.com/gdb/onlinedocs/gdb_31.html.

  3. Install MinGW’s MSYS:
    • Install MSYS DTK 1.0 in D:\mingw\1.0
    • Install MSYS Core 1.0.11. It is an archive. Unpack it in D:\mingw\1.0
  4. Setting PATH and HOME environment, and run D:\mingw\1.0\msys.bat
  5. Download GDB debugger sources. I use the latest repository snapshot. And upack them to D:\mingw\1.0\home
  6. ./configure & make

You should have gdb.exe in D:\mingw\1.0\home\gdb-#.#.#\gdb\ in about 30 minutes.

To port GDB debugger to a new architecture, you should not miss the detailed guide ” Howto: Porting the GNU Debugger — Practical Experience with the OpenRISC 1000 Architecture “.

Update:

To compile GDB Insight 6.8 under MSYS environment, you should make a patch :

Index: gdb/ChangeLog
===================================================================
RCS file: /cvs/src/src/gdb/ChangeLog,v
retrieving revision 1.9174.2.20
diff -u -r1.9174.2.20 ChangeLog
— ChangeLog 31 Mar 2008 03:40:42 -0000 1.9174.2.20
+++ ChangeLog 11 Apr 2008 09:10:13 -0000
@@ -1,3 +1,8 @@
+2008-04-11 Hans Kester
+
+ * configure.ac: Added configdir for MinGW.
+ * configure: Added configdir for MinGW.
+
2008-03-30 Daniel Jacobowitz

* ia64-tdep.c (examine_prologue): Correct array access.

Index: gdb/configure.ac
===================================================================
RCS file: /cvs/src/src/gdb/configure.ac,v
retrieving revision 1.64
diff -u -r1.64 configure.ac
— configure.ac 13 Jan 2008 12:23:05 -0000 1.64
+++ configure.ac 11 Apr 2008 09:02:13 -0000
@@ -1445,7 +1445,7 @@
AC_SUBST(WIN32LDAPP)

case “${host}” in
-*-*-cygwin*)
+*-*-cygwin* | *-*-mingw*)
configdir=”win”
;;
*)

Index: gdb/configure
===================================================================
RCS file: /cvs/src/src/gdb/configure,v
retrieving revision 1.242
diff -u -r1.242 configure
— configure 13 Jan 2008 12:23:04 -0000 1.242
+++ configure 11 Apr 2008 09:05:54 -0000
@@ -23080,7 +23080,7 @@

case “${host}” in
-*-*-cygwin*)
+*-*-cygwin* | *-*-mingw*)
configdir=”win”
;;
*)

Posted in C++, Debug | Tagged , , | 3 Comments

JavaCC

I learned to use JavaCC these days. And I found that JavaCC is a great toolkit.

What is JavaCC?

JavaCC is short for Java Compiler Compiler. It is a parser or scanner generator for Java.

Java Compiler Compiler [tm] (JavaCC [tm]) is the most popular parser generator for use with Java [tm] applications. A parser generator is a tool that reads a grammar specification and converts it to a Java program that can recognize matches to the grammar. In addition to the parser generator itself, JavaCC provides other standard capabilities related to parser generation such as tree building (via a tool called JJTree included with JavaCC), actions, debugging, etc.

You can find a lot of language grammar and AST on its site too. I see that C++ and Java 1.5 grammar are there. JavaScript isn’t there. But I find out that Dojo toolkit’s JSLinker provides an ECMAScript 262 one. That is to say, you can create parser and parse C++, Java or JavaScript sources into your AST for any uses. Lots of great features can be imagined.

I spent about a week learning and using JavaCC. I completed a parser for an IDL language named CAR. I also built an Eclipse editor using the generated AST parser. Bang, all things seems working well: keyword hight-lighting, outline view, error probing, … Great toolkit!

Using JavaCC is quite simple, just download javacc-4.0.zip and unzip it, then following its examples tutorial. I sugguest you to start with JavaGrammars and VTransformer examples, as they are about Java grammar.

I think, later, given opportunity, I will try JavaCC out on other projects. Maybe my Java2Script compiler would be benefited from JavaCC.

P.S. Update:
There is a JavaCC Eclipse Plugin project, you can download the plugin to help you writing your syntax file.

Posted in C++, Java, JavaScript | Tagged , | 2 Comments

Create a Process and Read Its Output

This is a snippet of windows C++ code to create a process and read its output until some specific string is printed. This is useful for programmer to start a server and only to return until the server is started, as sometimes server may take some seconds to initialize.

BOOL CreateProcessAndWait(char* cmdline, int flag,
STARTUPINFO *si, PROCESS_INFORMATION *pi,
const char* keyString)
{
HANDLE hOutputReadTmp,hOutputRead,hOutputWrite;
HANDLE hErrorWrite;
SECURITY_ATTRIBUTES sa;

// Set up the security attributes struct.
sa.nLength= sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;

// Create the child output pipe.
if (!CreatePipe(&hOutputReadTmp, &hOutputWrite, &sa,0)) {
printf("CreatePipe\n");
}
// closes one of its std output handles.
if (!DuplicateHandle(GetCurrentProcess(),hOutputWrite,
GetCurrentProcess(),&hErrorWrite,0,
TRUE,DUPLICATE_SAME_ACCESS))
printf("DuplicateHandle");
// Create new output read handle and the input write handles.
// Set the Properties to FALSE. Otherwise, the child inherits
// the properties and, as a result, non-closeable handles to
// the pipes are created.
if (!DuplicateHandle(GetCurrentProcess(),hOutputReadTmp,
GetCurrentProcess(),
&hOutputRead, // Address of new handle.
0,FALSE, // Make it uninheritable.
DUPLICATE_SAME_ACCESS))
printf("DupliateHandle");

ZeroMemory(si, sizeof(STARTUPINFO));
si->cb = sizeof(STARTUPINFO);
ZeroMemory(pi, sizeof(PROCESS_INFORMATION));
flag = CREATE_NEW_PROCESS_GROUP | flag;
si->dwYCountChars = 5000;
si->dwFlags |= STARTF_USECOUNTCHARS;
si->dwFlags |= STARTF_USESTDHANDLES;
si->hStdOutput = hOutputWrite;
si->hStdError = hErrorWrite;

int ret = CreateProcess(NULL,
cmdline, /* command line */
NULL, /* Security */
NULL, /* thread */
TRUE, /* inherit handles */
flag, /* start flags */
NULL, /* winenv, */
NULL, /* current directory */
si, pi);
if (ret != -1)
{
CHAR lpBuffer[256];
DWORD nBytesRead;
DWORD keyLength = strlen(keyString);
DWORD index = 0;
memset(lpBuffer, 0, sizeof(lpBuffer));

DWORD dwTimeoutThreadId;
HANDLE hTimeoutThread = CreateThread(
NULL, // no security attribute
0, // stack size, BUGBUG:Try to use the limit size!
(LPTHREAD_START_ROUTINE) TimeoutThread,
(LPVOID) pi->hProcess, // thread parameter
0, // not suspended
&dwTimeoutThreadId); // returns thread ID

if (hTimeoutThread == NULL)
{
printf("No time out thread for specific string %s.\n",
keyString);
}
else CloseHandle(hTimeoutThread);

while(TRUE)
{
if (ReadFile(hOutputRead,lpBuffer + index,
sizeof(lpBuffer) - index,
&nBytesRead,NULL) && nBytesRead)
{
if ((index + nBytesRead >= keyLength)
&& strstr(lpBuffer, keyString))
{
break;
}
if (index + nBytesRead > sizeof(lpBuffer)
- keyLength) {
// move
for (DWORD i = 0; i < keyLength; i++) {
lpBuffer[i] = lpBuffer[index + nBytesRead
- keyLength + i];
}
index = keyLength;
memset(lpBuffer + keyLength, 0,
sizeof(lpBuffer) - keyLength);
} else {
index += nBytesRead;
}
}
}
}
return ret;
}

Posted in C++, Snippet, Tricks | Comments Off on Create a Process and Read Its Output