public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
* Strange problem with Sergey's cygwin.dll and remote X
@ 1997-06-06  6:09 Chris Faylor
  1997-06-07 22:39 ` Debugging cygwin.dll with gdb Geoffrey Noer
  0 siblings, 1 reply; 3+ messages in thread
From: Chris Faylor @ 1997-06-06  6:09 UTC (permalink / raw)
  To: gnu-win32

I've recently installed Sergey's cygwin.dll and have been very happy
with the performance improvement.  I've noticed a strange interaction
between it and a product I've been evaluating, however.

The product is Nterprise.  It is an add-on to Windows-NT which allows
one to use Windows-NT applications on any X server.  I've been evaluating
this product for a few months and have been less than thrilled with its
performance, but, for the most part, if you are willing to wait for windows
to appear and if you are willing to try several times to "login", eventually
you may get an almost usable NT window running on an X server.

I had been using bash with no problem prior to updating to Sergey's
cygwin.  Now, whenever I start up a gnuwin remotely application it
'hangs' for an indefinite period.  Reverting to stock B18 "cures" the
problem.

Obviously this is a problem with Nterprise, not cygwin, since the same
software works perfectly when invoked locally.  I'd like to be able to
debug this problem, however, so that I can report back to the Nterprise
folks with a specific function that is failing (I suspect that it has
something to do with the querying of console colors or something like that).

I am at a loss, however, as to how to debug this.  I've built a cygwin.dll
from scratch with Sergey's patches, but then, how do I debug it?  Attempting
to invoke gdb remotely hangs due to the problem I mentioned above.  Attempting
to start gdb with the "good" dll and start a test program with the "bad"
dll just dies with stack failures or whatever -- this is the standard
problem you see when you have two different versions of cygwin.dll in
your path.

So, how do I debug this?  Certainly there must be some method for doing
this or new cygwin.dll development is severely hampered.

Any insight would be appreciated.
-- 
http://www.bbc.com/	cgf@bbc.com			"Strange how unreal
VMS=>UNIX Solutions	Boston Business Computing	 the real can be."
-
For help on using this list (especially unsubscribing), send a message to
"gnu-win32-request@cygnus.com" with one line of text: "help".

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Debugging cygwin.dll with gdb
  1997-06-06  6:09 Strange problem with Sergey's cygwin.dll and remote X Chris Faylor
@ 1997-06-07 22:39 ` Geoffrey Noer
  1997-06-14  9:31   ` Debugging cygwin.dll with gdb & static libcygwin_g.a Mikey
  0 siblings, 1 reply; 3+ messages in thread
From: Geoffrey Noer @ 1997-06-07 22:39 UTC (permalink / raw)
  To: cgf; +Cc: gnu-win32

Chris Faylor wrote:
[...]
> I am at a loss, however, as to how to debug this.  I've built a cygwin.dll
> from scratch with Sergey's patches, but then, how do I debug it?  Attempting
> to invoke gdb remotely hangs due to the problem I mentioned above.
[...]

A future change that needs to be made is to always build cygwin.dll
and libcygwin.a as well as (new) cygwindebug.dll and libcygwindebug.a.
Everything other than gdb would get linked against cygwin.dll whereas
gdb would be linked against cygwindebug.dll.

So if you need to debug a non-functional cygwin.dll, you could use any
previously working gdb since it would depend on a working cygwin.dll.
Alternatively, we could somehow statically link the code inside the
cygwin.dll inside gdb.

-- 
Geoffrey Noer
noer@cygnus.com
-
For help on using this list (especially unsubscribing), send a message to
"gnu-win32-request@cygnus.com" with one line of text: "help".

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Debugging cygwin.dll with gdb & static libcygwin_g.a
  1997-06-07 22:39 ` Debugging cygwin.dll with gdb Geoffrey Noer
@ 1997-06-14  9:31   ` Mikey
  0 siblings, 0 replies; 3+ messages in thread
From: Mikey @ 1997-06-14  9:31 UTC (permalink / raw)
  To: Geoffrey Noer, gnu-win32

[-- Attachment #1: Type: text/plain, Size: 4952 bytes --]

The thing that has bugged me the most about gnu-cygwin32 ever since I 
started using it, is that you couldn't really see what was going on, your 
code gets to the dll, and it disappears, and writing in your own debugging 
messages via debug_printf, is a real pain in the tail, so I finally fixed it.

Attached are the necessary files, to make a static libcygwin_g.a, along 
with a specs file that allows you to link with it.

All you have to do to link with the static lib, is add -g to your link line.

I also added a utility stripdll, so that your production dll will be the usual 
size, ~320K and fixed the Makefile so it will strip the extra debugging 
information from libcygwin.a automatically so you (and I ;^) don't 
have to remember every time. and for those of you who already have 
the Micros*** SDK I included a better version of lib2def.

There are at least two problems with this, the debuggable executables, are 
huge, ~3M at least, so most people won't want to use this for installed stuff ;^)

The libcygwin_g.a is also huge ~11M, so I won't be posting it anywhere, 
if you're into debugging dll code, you're going to have to build the 
dll anyway ;^)

The other thing is that the by now famous win95 lseek() bug will 
catch you once in a while, at least I think that's what's happening
so if the new .exe will run, but gdb segfaults when loading it, just relink, 
and try again.

But I think that being able to debug the .dll code directly is well worth it ;^))))))).

I have built and run /bin/bash.exe linked to /bin/sh "static", 
~3M w/debug code, 520K after strip --strip-all and it seems to work fine,
with one exception, you can reinvoke sh as many times as you want,
but running shell scripts can lockup, I suspect that changes would 
need to be made to the fork() code, to make this a truly workable
alternative for people who want to just send out the executables,
without the dll.

If you need to make changes to dll startup code in either dcrt0.cc, or libccrt0.cc,
like Sergey's patch does, you will want to make those same changes in gcrt0.cc
to debug them.

WARNING compiling with -g on your link line WILL be seriously 
hazardous to your free disk space once you do this, 
YOU HAVE BEEN WARNED!! ;^)

If you haven't mounted your filsystems -b already, you really should.
the attached files are LF only. you may be able to get away with adding
--ignore-whitespace to the patch line below, I don't know.

To create libcygwin_g.a 
BACKUP YOUR SPECS FILE FIRST!!!!
replace your .../H-i386-cygwin32/lib/gcc-lib/i386-cygwin32/$VERSION/specs
with the attached one.
cd into the .../cdk/winsup/ directory, and type patch -p0 < static.dif
find -name \*.rej 		there better not be any.
find -name \*.orig or \*.~1~|xargs rm
#depending on if you have      export VERSION_CONTROL=numbered     in .bashrc
.cd into your .../obj dir, and configure and make as usual.
I didn't have the static lib install by default, because of it's size. so to get the static lib
made and installed you will need to do

make prefix=/your/inst/dir exec_prefix=/your/inst/dir/H-i386-cygwin32 install-static

or just 

make libcygwin_g.a

and copy it wherever you want.

All that being said, have FUN!!!
	Mikey

./*                            DECLARATION

I, Jeffrey DeBeer, grant to the public domain my entire right, title,
and interest (including all rights under copyright) in my changes and
enhancements to the Cygwin32 library. These changes and enhancements are
herein called the "Work". The Work granted to the public domain shall
also include any future revisions of these changes and enhancements
hereafter made by me.

I  represent and warrant that I am the sole author of the Work and that
I have the right and power to make this grant. I make no other express
or implied warranty (including without limitation, in this disclaimer of
warranty, any warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE).

Jeffrey DeBeer
12 June 1997
*/


On Sat, 7 Jun 1997 21:13:14 -0700 (PDT), you wrote:

>Chris Faylor wrote:
>[...]
>> I am at a loss, however, as to how to debug this.  I've built a cygwin.dll
>> from scratch with Sergey's patches, but then, how do I debug it?  Attempting
>> to invoke gdb remotely hangs due to the problem I mentioned above.
>[...]
>
>A future change that needs to be made is to always build cygwin.dll
>and libcygwin.a as well as (new) cygwindebug.dll and libcygwindebug.a.
>Everything other than gdb would get linked against cygwin.dll whereas
>gdb would be linked against cygwindebug.dll.
>
>So if you need to debug a non-functional cygwin.dll, you could use any
>previously working gdb since it would depend on a working cygwin.dll.
>Alternatively, we could somehow statically link the code inside the
>cygwin.dll inside gdb.
>
>-- 
>Geoffrey Noer
>noer@cygnus.com
>-
>For help on using this list (especially unsubscribing), send a message to
>"gnu-win32-request@cygnus.com" with one line of text: "help".
>


[-- Attachment #2: specs --]
[-- Type: text/plain, Size: 1495 bytes --]

*asm:


*asm_final:


*cpp:
%(cpp_cpu) %[cpp_cpu] %{posix:-D_POSIX_SOURCE} %{console:-I/usr/local/include/win32} %{windows:-I/usr/local/include/win32}

*cc1:
%{!mcpu*: %{m386:-mcpu=i386 -march=i386} %{mno-486:-mcpu=i386 -march=i386} %{m486:-mcpu=i486 -march=i486} %{mno-386:-mcpu=i486 -march=i486} %{mno-pentium:-mcpu=i486 -march=i486} %{mpentium:-mcpu=pentium} %{mno-pentiumpro:-mcpu=pentium} %{mpentiumpro:-mcpu=pentiumpro}}

*cc1plus:


*endfile:


*link:
%{mwindows:--subsystem windows} %{windows:--subsystem windows} %{dll:--dll -e _dll_entry@12}

*lib:
%{g:-luser32 -lgdi32 -ladvapi32 -lcomdlg32 -lwsock32 -lnetapi32 -lg -lm} %{!g:-lcygwin} %{windows:-luser32 -lgdi32 -lcomdlg32} %{console:-luser32} %{mwindows:-luser32 -lgdi32 -lcomdlg32} -lkernel32

*libgcc:
%{g:-lcygwin_g} -lgcc

*startfile:
crt0%O%s %{dll:/usr/local/lib/fixup.o}

*switches_need_spaces:


*signed_char:
%{funsigned-char:-D__CHAR_UNSIGNED__}

*predefines:
-Di386 -D_WIN32   -DPOSIX -D__CYGWIN32__ -DWINNT  -D_X86_=1 -D__STDC__=1  -D__stdcall=__attribute__((__stdcall__))   -D__cdecl=__attribute__((__cdecl__))   -Asystem(winnt) -Acpu(i386) -Amachine(i386)

*cross_compile:
1

*version:
cygnus-2.7.2-970404

*multilib:
. ;

*multilib_defaults:


*multilib_extra:


*multilib_matches:


*cpp_cpu:
-Di386  -Asystem(unix) -Acpu(i386) -Amachine(i386) %{mcpu=i486:-Di486} %{m486:-Di486} %{mpentium:-Dpentium -Di586} %{mcpu=pentium:-Dpentium -Di586} %{mpentiumpro:-Dpentiumpro -Di686} %{mcpu=pentiumpro:-Dpentiumpro -Di686}


[-- Attachment #3: static.dif --]
[-- Type: text/x-diff, Size: 29350 bytes --]

diff -urbB ../cdk/winsup/Makefile.in ./Makefile.in
--- ../cdk/winsup/Makefile.in	Thu May 01 10:44:43 1997
+++ ./Makefile.in	Fri Jun 13 09:28:35 1997
@@ -38,12 +38,13 @@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DIRS = @INSTALL@ -d
 
 CC = @CC@
 # FIXME: Which is it, CC or CC_FOR_TARGET?
 CC_FOR_TARGET = $(CC)
-CFLAGS = @CFLAGS@
-CXXFLAGS = @CXXFLAGS@
+CFLAGS = @CFLAGS@ -g
+CXXFLAGS = @CXXFLAGS@ -g
 
 INCLUDES = -I./msinclude -I$(srcdir)/include -I$(srcdir) -I$(srcdir)/../libstdc++/stl -I$(srcdir)/../libio -I../libio -I$(srcdir)/../newlib/libc/include -nostdinc++
 
@@ -74,7 +75,8 @@
 	AR="$(AR)" \
 	RANLIB="$(RANLIB)" \
 	LD="$(LD)" \
-	DLLTOOL="$(DLLTOOL)"
+	DLLTOOL="$(DLLTOOL)" \
+	prefix="$(prefix)"
 
 
 # This is the final name of the cygwin.dll.
@@ -96,6 +98,7 @@
 LIBIBERTYOS=../libiberty/getopt.o ../libiberty/getopt1.o
 
 LIBCOS=libccrt0.o libcctype.o libcerr.o libcmain.o $(LIBIBERTYOS)
+LIBGOS=$(filter-out libccrt0.o,$(LIBCOS))
 
 # Build as many .a files as we have .def files
 
@@ -152,27 +155,39 @@
 readme.info:$(srcdir)/doc/readme.texinfo
 	$(MAKEINFO) -I$(srcdir)/doc  $<
 
-install: $(THEIRLIBS) $(LIBNAME) new-$(DLLNAME) real-headers
+install-static: libcygwin_g.a
+	$(INSTALL_DATA) $< $(tooldir)/lib/$<
+
+install-theirlibs: $(THEIRLIBS) $(LIBNAME)
 	for i in $(THEIRLIBS) $(LIBNAME); do \
 		$(INSTALL_DATA) $$i $(tooldir)/lib/$$i ; \
 	done
+	strip.exe --strip-debug $(tooldir)/lib/$(LIBNAME)
+
+install-dll: new-$(DLLNAME)
 	for i in $(DLLNAME); do \
-	  $(INSTALL_DATA) new-$$i $(tooldir)/lib/$$i ; \
 	  binname=`t='$(program_transform_name)'; echo "$$i" | sed -e $$t` ; \
 	  echo "program_transform_name=$(program_transform_name), i=$$i, binname=$$binname"; \
 	  rm -f $(bindir)/$$binname ; \
-	  ln $(tooldir)/lib/$$i $(bindir)/$$binname >/dev/null 2>&1 || $(INSTALL_DATA) new-$$i $(bindir)/$$binname ; \
+	  $(INSTALL_DATA) new-$$i $(bindir)/$$binname ; \
 	done
+	for i in $(DLLNAME);do utils/stripdll $(bindir)/$$i;done
+
+install-real-headers: real-headers
 	for sub in include include/arpa include/asm include/Windows32 \
 	   include/cygwin32 include/net include/netinet include/sys ; do \
+		$(INSTALL_DIRS) $(tooldir)/$$sub; \
 		for i in $(srcdir)/$$sub/*.h ; do \
 		  $(INSTALL_DATA) $$i $(tooldir)/$$sub/`basename $$i` ; \
 		done ; \
 	done
+
+install-utils:
 	rootme=`pwd` ; export rootme ; \
 	rootsrc=`(cd $(srcdir) ; pwd)` ; export rootsrc ; \
 	cd utils; $(MAKE) install $(FLAGS_TO_PASS)
 
+install: install-theirlibs install-dll install-real-headers install-utils
 	# this will only work if you've maked stmp_ms_include below.
 	#	if [ -e ms_include/windows.h ] ; then  \
 	#		for i in ms_include/*.h ; do \
@@ -254,6 +269,7 @@
 # we build our own import library to get at the winsock functions
 # by different names.
 
+STATICOS=$(filter-out init.o malloc.o dcrt0.o,$(DLL_OFILES))
 #libmywinsock.a:mywinsock.def
 #	$(DLLTOOL) --as=$(AS) -k --dllname wsock32.dll --output-lib libmywinsock.a --def $<
 
@@ -291,8 +307,18 @@
 	$(DLLTOOL) $(DLL_STUFF)
 	$(LD) cygwin.exp $(LD_STUFF)
 
+libcygwin_g.a: gcrt0.o libcygwin.a new-$(DLLNAME)
+	$(AR) crvs libcygwin_g.a $(LIBGOS) gcrt0.o $(STATICOS) glob/glob.o glob/fnmatch.o
+
 clean:
 	-rm -f *.o *.dll *.a *.exp junk *.base
+	$(MAKE) -C glob $@
+	$(MAKE) -C utils $@
+
+distclean: clean
+	-rm -f Makefile config.status config.cache config.log cygwin.def
+	$(MAKE) -C glob $@
+	$(MAKE) -C utils $@
 
 maintainer-clean realclean: clean 
 	@echo "This command is intended for maintainers to use;"
diff -urbB ../cdk/winsup/cygwin.din ./cygwin.din
--- ../cdk/winsup/cygwin.din	Fri May 02 11:57:47 1997
+++ ./cygwin.din	Fri Jun 13 06:32:13 1997
@@ -945,8 +945,6 @@
 _closelog = closelog
 openlog
 _openlog = openlog
-tgetent
-_tgetent = tgetent
 vhangup
 _vhangup = vhangup
 nice
diff -urbB ../cdk/winsup/gcrt0.cc ./gcrt0.cc
--- ../cdk/winsup/gcrt0.cc	Thu Jun 12 08:52:21 1997
+++ ./gcrt0.cc	Fri Jun 13 09:04:41 1997
@@ -0,0 +1,813 @@
+/* gcrt0.cc -- a bit of crt0 that lives in libcygwin_g.a
+
+   Copyright 1996, 1997 Cygnus Solutions
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+/* modified from dcrt0.cc libccrt0.cc and malloc.cc by
+(*jeffdb@netzone.nospam.com) Mikey remove *&nospam to contact
+
+                            DECLARATION
+ 
+I, Jeffrey DeBeer, grant to the public domain my entire right, title,
+and interest (including all rights under copyright) in my changes and
+enhancements to the Cygwin32 library. These changes and enhancements are
+herein called the "Work". The Work granted to the public domain shall
+also include any future revisions of these changes and enhancements
+hereafter made by me. 
+
+I  represent and warrant that I am the sole author of the Work and that
+I have the right and power to make this grant. I make no other express
+or implied warranty (including without limitation, in this disclaimer of
+warranty, any warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE).
+
+Jeffrey DeBeer
+12 June 1997
+*/
+
+
+#include <ctype.h>
+#include <unistd.h>
+#include <reent.h>
+#include <stdlib.h>
+#include "winsup.h"
+#include "glob/glob.h"
+#include "exceptions.h"
+
+per_process *u;
+
+extern "C"
+{
+  /* Used for the libc stuff which uses environ,
+     we copy this into the real crt0.  */
+  char **environ;
+  /* __progname used in getopt error message */
+  char *__progname;
+  struct _reent reent_data;
+};
+
+static const int cygwin_dll_version_major = CYGWIN_DLL_VERSION_MAJOR;
+static const int cygwin_dll_version_minor = CYGWIN_DLL_VERSION_MINOR;
+static char *title;
+
+
+/* this is a horrible hack to avoid changing per_process */
+
+void *
+malloc (size_t size)
+{
+  void *res;
+  res = _malloc_r (_impure_ptr, size);
+  return res;
+}
+
+void
+free (void *p)
+{
+  _free_r (_impure_ptr, p);
+}
+
+void *
+realloc (void *p, size_t size)
+{
+  void *res;
+  res = _realloc_r (_impure_ptr, p, size);
+  return res;
+}
+
+void
+export_free (void *p)
+{
+  _free_r (_impure_ptr, p);
+}
+
+void *
+export_malloc (int size)
+{
+  void *res;
+  res = _malloc_r (_impure_ptr, size);
+  return res;
+}
+
+void *
+export_realloc (void *p, int size)
+{
+  void *res;
+  res = _realloc_r (_impure_ptr, p, size);
+  return res;
+}
+
+/* we need this instead to replace select in cygwin.exp */
+extern "C" {
+
+extern int cygwin32_select(int,fd_set *,fd_set *,fd_set *,struct timeval *);
+
+int select (int n, fd_set *readfds, fd_set *writefds,
+                     fd_set *exceptfds, struct timeval *to)
+{
+return cygwin32_select (n, readfds, writefds, exceptfds, to);
+}
+
+}
+
+/* Return number of elements in a microsoft style env list.  
+   
+   The "environment block" is a null terminated block of strings
+   (two nulls terminate the block).  */
+
+static int
+num_ms_env_vars (const char *rawenv)
+{
+  int i = 0;
+  int count = 0;
+  while (1)
+    {
+      if (rawenv[i] == 0)
+	{
+	  count++;
+	  if (rawenv[i + 1] == 0)
+	    break;
+	}
+      i++;
+    }
+  return count;
+}
+
+/* Build argv from string passed from Windows.  */
+
+static void
+build_argv (char *in, char **out, int len)
+{
+  int count = 0;
+  char *e = in + len;
+  char *s;
+
+  for (s = in; s < e; s++)
+    {
+      debug_printf ("build_argv: fill iteration %s\n", s);
+
+      /* Delete leading spaces.  */
+      while (*s == ' ' || *s == '\t')
+	s++;
+
+      if (!*s)
+	break;
+
+      /* Got to an arg.  */
+
+      char *d;
+      out[count] = d = s;
+      
+      if (*s == '"')
+	{
+	  s++;
+	  while (s[0] && (s[0] != '"' || (s[0] == '"' && s[1] == '"')))
+	    {
+	      if (*s== '"')
+		s++;
+	      *d++ = *s++;
+	    }
+	}
+      else
+	{
+	  while (*s && *s != ' ' && *s != '\t')
+	    {
+	      *d++ = *s++;
+	    }
+	}
+      *d++ = 0;
+      debug_printf ("build_argv: argv[%d]=%s\n", count, out[count]);
+      count++;
+    }
+  out[count] = 0;
+
+  /* FIXME: Verify count == len?  */
+}
+
+/* Compute argc.
+   Windows passes just a string which we need to break up into argc/argv.
+   This pass computes argc.  */
+
+static int
+compute_argc (char *in)
+{
+  char *src;
+  int count=0;
+
+  debug_printf ("compute_argc (%s)\n", in);
+
+  for (src = in; *src; src++)
+    {
+      while (*src == ' ' || *src == '\t' )
+	src++;
+      
+      if (!*src)
+	break;
+      
+      debug_printf ("compute_argc: src is now %s\n", src);
+      if (*src == '"')
+	{
+	  src++;
+	  while (src[0])
+	    {
+	      if (src[0] == '"') 
+		{
+		  src++;
+		  if (src[0] != '"') break;
+		}
+	      
+	      src++;
+	    }
+	}
+      else
+	{
+	  while (*src != ' ' && *src != '\t' && *src != 0)
+	    src++;
+	}
+      count++;
+    }
+  debug_printf ("compute_argc: count is %d\n", count);
+  return count;
+}
+
+/* Perform various start up sanity checks.  */
+
+static void
+checkout ()
+{
+#ifdef __PPC__
+  jmp_buf x;
+
+  if (sizeof (x) != 32*8)
+    {
+      small_printf ("Configuration error with setjmp\n");
+    }
+#endif
+}
+
+static void
+globify (int *acp, char ***avp)
+{
+  /* Yes I know I could use references, but they hide the side effects */
+  int ac = *acp;
+  char **av = *avp;
+  glob_t globs[ac];
+  int rc[ac];
+  int i;
+  int newac = 0;
+  int donesomething = 0;
+
+  for (i = 0; i < ac; i++)
+    {
+      if (strpbrk (av[i], "?*[") != NULL)
+	{
+	  globs[i].gl_offs = 0;
+	  rc[i] = glob (av[i], 
+			GLOB_NOCHECK | GLOB_NOESCAPE,
+			0,
+			&globs[i]);
+	  newac += rc[i] == 0 ? globs[i].gl_pathc : 1;
+	  donesomething = rc[i] == 0;
+	}
+      else
+	{
+	  rc[i] = -1; /* glob not called */
+	  ++newac;
+	}
+    }
+  
+  if (donesomething)
+    {
+      char **newav = (char **)malloc (sizeof (char **) * (newac + 1));
+      int d = 0;
+      for (i = 0; i < ac; i++)
+	{
+	  if (rc[i] == 0)
+	    {
+	      debug_printf ("glob: `%s' converted to:", av[i]);
+	      for (int j = 0; j < globs[i].gl_pathc; j++)
+		{
+		  debug_printf (" %s", globs[i].gl_pathv[j]);
+		  newav[d++] = globs[i].gl_pathv[j];
+		}
+	      debug_printf ("\n");
+	    }
+	  else
+	    {
+	      debug_printf ("glob: `%s' not converted, glob rc = 0x%x\n",
+			    av[i], rc[i]);
+	      newav[d++] = av[i];
+	    }
+	}
+      newav[d] = 0;
+      *acp = newac;
+      *avp = newav;
+    }
+}
+
+/* Utility to probe the stack.  */
+
+static void
+recur (void *p, void *)
+{
+  char b[1000];
+  int x;
+
+  if (&x > p)
+    recur (p, b);
+}
+
+/* List of names which are converted from dos to unix
+   on the way in and back again on the way out.
+
+   PATH needs to be here because CreateProcess uses it and gdb uses
+   CreateProcess.  Having too many more here is dubious.  */
+
+const char *conv_path_names[] =
+{
+  "PATH=",
+  0
+};
+
+void
+__do_global_dtors ()
+{
+  int i;
+  void (**pfunc)() = u->dtors;
+
+  /* Run dtors backwards, so skip the first entry and find how many
+     there are, then run them.  */
+  
+  if (pfunc) 
+    {
+      for (i = 1; pfunc[i]; i++) 
+	;
+      for (i = i - 1; i > 0; i--)
+	{
+	  (pfunc[i])();
+	}
+    }
+}
+
+void
+__do_global_ctors ()
+{
+  int i;
+  void (**pfunc)() = u->ctors;
+  
+  for (i = 1; pfunc[i]; i++)
+    {
+      (pfunc[i])();
+    }
+  atexit (__do_global_dtors);
+}
+
+void
+__main ()
+{
+  if (! u->run_ctors_p)
+    {
+      u->run_ctors_p = 1;
+      __do_global_ctors ();
+    }
+}
+
+void
+_exit (int n)
+{
+  syscall_printf ("_exit (%d)\n", n);
+  syscall_printf ("Terminating.\n");
+  /* restore console title */
+  if (title)
+    SetConsoleTitle (title);
+
+  if(u->self->pid != u->self->ppid)
+  kill(u->self->ppid, SIGCHLD);
+  close_all_files ();
+  u->self->terminate ();
+  shared_terminate ();
+  fork_terminate ();
+
+  /* Must be done last */
+  u->self->record_death();
+
+  destroy_pinfo_lock();
+  ExitProcess (n);
+}
+
+void
+api_fatal (const char *msg)
+{
+  small_printf ("cygwin: %s\n", msg);
+  /* We are going down without mercy - make sure we reset
+     our inuse_p. */
+  if((u != 0) && (u->self != 0))
+    u->self->record_death_nolock();
+
+  ExitProcess (1);
+}
+
+
+/* Wrap the real one, otherwise gdb gets confused about
+   two symbols with the same name, but different addresses.
+
+   UPTR is a pointer to global data that lives on the libc side of the
+   line [if one distinguishes the application from the dll].  */
+
+/* This is needed to terminate the list of import stuff */
+asm (".section .idata$3\n" ".long 0,0,0,0,0");
+
+/* For fork */
+#ifdef _POWER
+extern char __data_start__;
+extern char __data_end__;
+extern char __bss_start__;
+extern char __bss_end__;
+#else
+extern char _data_start__;
+extern char _data_end__;
+extern char _bss_start__;
+extern char _bss_end__;
+#endif
+
+extern "C" 
+{
+/*  char **environ; */
+  void cygwin_crt0();
+  extern void (*__CTOR_LIST__)(void);
+  extern void (*__DTOR_LIST__)(void);
+  int main (int, char **, char **);
+  struct _reent *_impure_ptr;
+  int _fmode;
+};
+
+static per_process cygwin_statu;
+
+/* Set up pointers to various pieces so the dll can then use them,
+   and then jump to the dll.  */
+
+void cygwin_crt0()
+{
+  /* This is used to record what the initial sp was.  The value is needed
+     when copying the parent's stack to the child during a fork.  */
+  int onstack;
+
+  /* The version numbers are the main source of compatibility checking.
+     As a backup to them, we use the size of the per_process struct.  */
+  cygwin_statu.magic_biscuit = sizeof (per_process);
+
+  /* cygwin.dll version number in effect at the time the app was created.  */
+  cygwin_statu.version_major = CYGWIN_DLL_VERSION_MAJOR;
+  cygwin_statu.version_minor = CYGWIN_DLL_VERSION_MINOR;
+
+  cygwin_statu.ctors = &__CTOR_LIST__;
+  cygwin_statu.dtors = &__DTOR_LIST__;
+  cygwin_statu.envptr = &environ;
+  cygwin_statu.impure_ptr_ptr = &_impure_ptr;
+  cygwin_statu.main = &main;
+  cygwin_statu.fmode_ptr = &_fmode;
+  cygwin_statu.initial_sp = (char *) &onstack;
+
+  /* Remember whatever the user linked his application with - or
+     point to entries in the dll.  */
+  cygwin_statu.malloc = &malloc; 
+  cygwin_statu.free = &free;
+  cygwin_statu.realloc = &realloc;
+
+  /* Setup the module handle so fork can get the path name. */
+  cygwin_statu.hmodule = GetModuleHandle(0);
+
+  /* variables for fork */
+#ifdef _POWER
+  cygwin_statu.data_start = &__data_start__;
+  cygwin_statu.data_end = &__data_end__;
+  cygwin_statu.bss_start = &__bss_start__;
+  cygwin_statu.bss_end = &__bss_end__;
+#else
+  cygwin_statu.data_start = &_data_start__;
+  cygwin_statu.data_end = &_data_end__;
+  cygwin_statu.bss_start = &_bss_start__;
+  cygwin_statu.bss_end = &_bss_end__;
+#endif
+
+  /* Jump into the dll.  */
+per_process *uptr = &cygwin_statu;
+
+  int argc;
+  char **argv;
+  int i;
+  /* According to onno@stack.urc.tue.nl, the exception handler record must
+     be on the stack.  */
+  /* FIXME: Verify forked children get their exception handler set up ok.  */
+  struct exception_list cygwin_except_entry;
+
+  /* Sanity check to make sure developers didn't change the per_process
+     struct without updating SIZEOF_PER_PROCESS [it makes them think twice
+     about changing it].  */
+  if (sizeof (per_process) != SIZEOF_PER_PROCESS)
+    {
+      small_printf ("per_process sanity check failed\n");
+      ExitProcess (1);
+    }
+
+  /* Make sure that the app and the dll are in sync.
+     magic_biscuit != 0 if using the old style version numbering scheme.  */
+  if (uptr->magic_biscuit != SIZEOF_PER_PROCESS
+      || uptr->version_major != cygwin_dll_version_major)
+    {
+      small_printf ("CYGWIN DLL and APP out of sync, you'll have to relink, sorry.\n");
+      small_printf ("magic numbers (app %d, dll %d)\n",
+		    uptr->magic_biscuit, 0);
+      if (uptr->magic_biscuit == 0)
+	small_printf ("cygwin version numbers (app %d.%d, dll %d.%d)\n",
+		      uptr->version_major, uptr->version_minor,
+		      cygwin_dll_version_major, cygwin_dll_version_minor);
+      ExitProcess (1);
+    }
+
+  /* Set the local copy of the pointer into the user space.  */
+  u = uptr;
+
+  /* Nasty static stuff needed by newlib  - point to a
+     local copy of the reent stuff. 
+     NB. This MUST be done here (before the forkee code) as the
+     fork copy code doesn't copy the data in libccrt0.cc (that's why we
+     pass in the per_process struct into the .dll from libccrt0).
+  */
+
+  *(u->impure_ptr_ptr) = &reent_data;
+  _impure_ptr = &reent_data;
+
+#if 0
+  small_printf("&reent_data = %x, &_impure_ptr = %x, _impure_ptr = %x\n",
+		&reent_data, &_impure_ptr, _impure_ptr);
+#endif
+
+  /* Enable stracing as soon as possible.  */
+  strace_init ();
+
+  /* Initialize the cygwin32 subsystem if this is the first process,
+     or attach to the shared data structure if it's already running.  */
+  shared_init ();
+
+  /* Initialize SIGSEGV handling, etc.
+     The exception handler references data in the shared area, so this can't
+     be done until after shared_init.  */
+  /* FIXME: For the forkee, our stacked copy of cygwin_except_entry will
+     get overwritten, but presumably with the same data.  Not sure what
+     happens in the forkee if a SIGSEGV happens before now.  */
+  init_exceptions (&cygwin_except_entry);
+
+  /* Initialize the fork mechanism.  */
+  fork_init ();
+
+  /* Initialize the heap.  */
+  heap_init ();
+
+  char *line = GetCommandLineA ();
+  /* Save current console title and set new one */
+  title = (char *) alloca (TITLESIZE);
+  if (!GetConsoleTitle (title, TITLESIZE))
+    title = NULL;
+  SetConsoleTitle (line);
+
+  /* If this is a fork, then do that now.  All the other stuff will
+     have been set up by the task that forked us.  */
+
+  if (u->forkee)
+    {
+      environ = *u->envptr;
+
+      /* When a forked child starts, its stack is quite small.
+	 However, when it longjmp's, the stack becomes that of its parent
+	 which is arbitrarily large.  This can cause the child to crash so
+	 probe the stack out.  */
+      /* FIXME: Fix hardcoding of size after migration.  */
+      recur ((char *)&i - 0x20000, 0);
+
+      debug_printf ("child about to longjmp\n");
+      dump_jmp_buf (u->self->restore);
+
+      /* The corresponding setjmp is in fork.cc.  */
+      longjmp (u->self->restore, u->forkee);
+    }
+
+  /* Nasty static stuff needed by newlib - initialize it. 
+     Note that impure_ptr has already been set up to point to this above
+     NB. This *MUST* be done here, just after the forkee code as some
+     of the calls below (eg. uinfo_init) do stdio calls - this area must
+     be set to zero before then.
+  */
+  memset (&reent_data, 0, sizeof (reent_data));
+  reent_data._errno = 0;
+  reent_data._stdin =  reent_data.__sf + 0;
+  reent_data._stdout = reent_data.__sf + 1;
+  reent_data._stderr = reent_data.__sf + 2;
+
+  /* Perform various startup sanity checks.  */
+  checkout ();
+
+  /* Initialize our process table entry.  */
+  pinfo_init ();
+
+  /* Initialize the file descriptor table.  */
+  hmap_init ();
+
+  /* Initialize uid, gid.  */
+  uinfo_init ();
+
+  /* Initialize winsock */
+  socket_checkinit();
+
+  syscall_printf ("Application CYGWIN version: %d.%d\n",
+		  u->version_major, u->version_minor);
+  syscall_printf ("CYGWIN DLL version        : %d.%d\n",
+		  cygwin_dll_version_major, cygwin_dll_version_minor);
+
+  /* Scan the command line and build argv.  */
+  int len = strlen (line);
+  char *mine = (char *)alloca (len + 2);
+  memcpy (mine, line, len);
+  mine[len] = 0;
+  mine[len+1] = 0;
+  argc = compute_argc (mine);
+  argv =(char **) alloca ((argc + 1) * sizeof (char *));
+  build_argv (mine, argv, len);
+
+  /* Expand *.c, etc.  */
+  if (! u->self->cygwin_parent_p)
+    globify (&argc, &argv);
+
+  /* Deal with environment variables.  */
+  {
+    const char * const rawenv = GetEnvironmentStrings ();
+
+    int envc = num_ms_env_vars (rawenv);
+
+    debug_printf ("Processing %d env vars ...\n", envc);
+
+    /* Allocate space for these (+ the trailing NULL).  */
+    *u->envptr = (char **)alloca ((envc + 1) * sizeof (char *));
+
+    /* Current directory information is recorded as variables of the
+       form "=X:=X:\foo\bar; these must be changed into something legal
+       (we could just ignore them but maybe an application will
+       eventually want to use them).  */
+    int i = 0;
+    int n = 0;
+    while (rawenv[i])
+      {
+	char *c;
+	c = (char *)alloca (strlen (rawenv + i) + 1);
+	strcpy (c, rawenv + i);
+	if (c[0] == '=')
+	  c[0] = '!';
+	
+	(*u->envptr)[n] = c;
+	
+	/* Skip to the next one.  */
+	while (rawenv[i])
+	  ++i;
+	++i;
+	++n;
+      }
+    (*u->envptr)[n] = 0;
+
+    /* Amazingly, NT has a case sensitive environment name list,
+       only sometimes.
+       eg, it's normal to have NT set your "Path" to something.
+       Later, you set "PATH" to something else.  This alters "Path".
+       But if you try and do a naive getenv on "PATH" you'll get nothing. 
+       
+       So we upper case the labels here to prevent confusion later.
+       We do it only for the first process in a session group */
+    
+    if (u->self->pid == u->self->ppid)
+      for (i = 0; i < n; i++)
+        {
+	  char *p;
+	  for (p = (*u->envptr)[i]; *p != '=' && *p; p++)
+	    if (islower (*p))
+	      *p = toupper (*p);
+        }
+
+    /* If we're using posix paths, we do a special thing for the PATH
+       [and potentially others].  They might be in native format so we turn
+       them into their posix equivalent.  */
+
+    if (s->mount.posix_path_p ())
+      {
+	for (i = 0; i < n; i++)
+	  {
+	    for (int j = 0; conv_path_names[j]; j++) 
+	      {
+		char *src = (*u->envptr)[i];
+		int namelen = strlen (conv_path_names[j]);
+
+		if (strncasecmp (src, conv_path_names[j], namelen) != 0)
+		  continue;
+
+		/* Turn all the items in here from c:<foo>;<bar> into their 
+		   mounted equivalents - if they have one.  */
+		char *value = src + namelen;
+		char *envvar = (char *) alloca (win32_to_posix_path_list_buf_size (value));
+		char *outenv = envvar;
+
+		debug_printf ("need to convert %d %s\n", i, src);
+
+		memcpy (outenv, conv_path_names[j], namelen);
+		outenv += namelen;
+
+#if 0 /* Would rather not have this, but may have to.  */
+		/* PATH in win32 always has a virtual ":" at the front
+		   (the current directory is always searched first).  Ensure
+		   PATH has a leading ":".  */
+		if (strcmp (conv_path_names[j], "PATH=") == 0)
+		  {
+		    if (*value != ';'
+			&& !(value[0] == '.' && value[1] == ';'))
+		      *outenv++ = ':';
+		  }
+#endif
+
+		win32_to_posix_path_list (value, outenv);
+
+		debug_printf ("env var converted to %s\n", envvar);
+		(*u->envptr)[i] = envvar;
+	      }
+	  }
+      }
+
+    /* FIXME: Sometimes the dll uses GetEnvironmentVariable,
+       sometimes it uses getenv.  Need to pick *one*.  */
+    environ = *u->envptr;
+    FreeEnvironmentStringsA ((char *) rawenv);
+  }
+
+  /* Save the program name.  It's used in debugging messages and by
+     the fork code (forking spawns a copy of us).  Copy it into a temp and
+     then into the final spot because debugging messages use
+     u->self->progname. Try getting the absolute path from the
+     module handle, if this fails get the name from the path.
+     This call references $PATH so we can't do this until the environment
+     vars are set up.  */
+  /* FIXME: What if argv[0] is relative, $PATH changes, and then the program
+     tries to do a fork?  */
+  {
+    char tmp[MAX_PATH];
+
+    if(u->hmodule != 0)
+      {
+        if(GetModuleFileName(u->hmodule, tmp, MAX_PATH)==0)
+          find_exec (argv[0], tmp);
+      }
+    else
+      find_exec (argv[0], tmp);
+    strcpy (u->self->progname, tmp);
+  }
+
+  /* Convert argv[0] to posix rules if we're using them and it's currently
+     blatantly win32 style.  */
+  if (s->mount.posix_path_p ()
+      && (strchr (argv[0], ':') || strchr (argv[0], '\\')))
+    {
+      char *new_argv0 = (char *) alloca (MAX_PATH);
+      conv_to_posix_path (argv[0], new_argv0);
+      argv[0] = new_argv0;
+    }
+
+  /* Set up __progname for getopt error call */
+  __progname = argv[0];
+
+  if (u->strace_mask & (_STRACE_STARTUP | _STRACE_ALL))
+    {
+      for (i = 0; i < argc; ++i)
+	__sys_printf ("argv[%d] = %s\n", i, argv[i]);
+      for (i = 0; (*u->envptr)[i]; ++i)
+	__sys_printf ("envp[%d] = %x %s\n", i, (*u->envptr)[i], (*u->envptr)[i]);
+    }
+
+  syscall_printf ("CYGWIN Release %d.%d, compiled %s %s\n",
+		  cygwin_dll_version_major, cygwin_dll_version_minor,
+		  __DATE__, __TIME__);
+
+  exit (u->main (argc, argv, environ));
+}
+
+/* This is needed to terminate the list of inport stuff */
+/* FIXME: Doesn't the ppc port handle this differently?  Standardize.  */
+asm (".section .idata$3\n" ".long 0,0,0,0,0,0,0,0");
+
diff -urbB ../cdk/winsup/misc.cc ./misc.cc
--- ../cdk/winsup/misc.cc	Thu Apr 24 16:45:37 1997
+++ ./misc.cc	Fri Jun 13 05:12:47 1997
@@ -103,13 +103,6 @@
 
 extern "C"
 int
-tgetent ()
-{
-  return -1;
-}
-
-extern "C"
-int
 vhangup ()
 {
   set_errno (ENOSYS);
Only in .: static.dif
diff -urbB ../cdk/winsup/utils/Makefile.in ./utils/Makefile.in
--- ../cdk/winsup/utils/Makefile.in	Thu Apr 24 16:46:03 1997
+++ ./utils/Makefile.in	Fri Jun 13 04:22:55 1997
@@ -33,8 +33,8 @@
 
 CC = @CC@
 
-CFLAGS = @CFLAGS@
-CXXFLAGS = @CXXFLAGS@
+override CFLAGS = @CFLAGS@
+override CXXFLAGS = @CXXFLAGS@
 
 # $(srcdir)/../../include is for getopt.h
 INCLUDES = -I$(srcdir)/.. -I$(srcdir)/../include -I$(srcdir)/../../include
@@ -46,10 +46,10 @@
 EXE_LDFLAGS =
 
 PROGS = mount umount ps kill cygwin mkpasswd mkgroup
-
+SCRIPTS = stripdll lib2def
 WINSUP_DEPS = $(srcdir)/../winsup.h
 
-all: $(PROGS)
+all: $(PROGS) $(SCRIPTS)
 
 mount: mount.cc $(WINSUP_DEPS)
 	$(CC) -o $@ $(srcdir)/mount.cc $(ALL_CXXFLAGS) $(EXE_LDFLAGS)
@@ -72,6 +72,12 @@
 mkgroup: mkgroup.c $(WINSUP_DEPS)
 	$(CC) -o $@ $(srcdir)/mkgroup.c $(ALL_CXXFLAGS) $(EXE_LDFLAGS) -lnetapi32 -ladvapi32
 
+stripdll: stripdll.sh
+	cat $(srcdir)/stripdll.sh > $@
+
+lib2def: lib2def.sh
+	cat $(srcdir)/lib2def.sh > $@
+
 clean:
 	rm -f *.o $(PROGS)
 
@@ -79,7 +85,7 @@
 	rm -f  Makefile config.cache 
 
 install:
-	for f in $(PROGS) ; \
+	for f in $(PROGS) $(SCRIPTS); \
 	do \
 	  $(INSTALL_XFORM) $$f $(bindir) ; \
 	done
diff -urbB ../cdk/winsup/utils/lib2def.sh ./utils/lib2def.sh
--- ../cdk/winsup/utils/lib2def.sh	Thu Jun 12 10:34:43 1997
+++ ./utils/lib2def.sh	Fri Jun 13 04:22:55 1997
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+tlow(){
+echo $1|tr A-Z a-z
+}
+
+if [ x"$1" = x"" ];then
+  echo "shell script to generate .def files from .LIB files
+  $0 filename ..."
+  exit 0
+else
+  echo LIBRARY `basename $1 .lib` 
+  echo EXPORTS
+  nm --extern-only $1|egrep '^........ [TR]' \
+  |fgrep -v '$AA'\
+  |fgrep -v 'C@_0'\
+  |fgrep -v '@@' \
+  |sort \
+  |sed -e 's/[^_]*_//' -e 's/[^?]*?//' 
+fi
+
+# T= .text section R= readonly .data section (exported variables)
+# $AA C@_0 @@ exported structure/internal function definitions
diff -urbB ../cdk/winsup/utils/stripdll.sh ./utils/stripdll.sh
--- ../cdk/winsup/utils/stripdll.sh	Thu Jun 12 08:52:31 1997
+++ ./utils/stripdll.sh	Fri Jun 13 04:22:55 1997
@@ -0,0 +1,43 @@
+#!/bin/sh
+#set -xv #debuging
+# this assumes .text .bss .data .edata .idata .stab .stabstr .reloc .rsrc
+# order for sections, which has been true for all the ones I've seen
+# and according to Mr. Noer this will be needed until B18+ comes out
+SECTION=.reloc
+if [ x"$1" = x"" -o x"$2" != x"" ];then
+  echo usage $0 dllname.dll 1>&2 # errors to stderr
+  exit 1;
+elif ! { DUMP=`objdump --headers $1` && echo $DUMP |grep pei-i386 &>/dev/null ;};then
+  echo $0: not an object file 1>&2
+  exit 1; # not an exe dll .a or .o file 
+elif ! echo $DUMP|grep "5 ." &>/dev/null ;then
+  exit 0; # already striped static
+elif echo $DUMP|grep "5 .reloc " &>/dev/null ;then
+  exit 0; # already striped .reloc
+elif echo $DUMP|grep ".rsrc" &>/dev/null ;then
+  if echo $DUMP|grep "7 .reloc " &>/dev/null ;then
+    echo $0: Please adjust .rsrc VMA by hand map is in `dirname $1`/stripmap.$$ 1>&2
+    objdump --headers $1 &>  `dirname $1`/stripmap.$$
+  else
+    SECTION=.rsrc
+  fi
+fi
+if ! echo $DUMP|grep "7 .reloc " &>/dev/null ;then
+  if echo $DUMP|grep "5 .stab " &>/dev/null ;then
+    strip $1 # static .dll
+    exit 0;
+  else
+    echo $0: unknown Error 1>&2
+    exit 1; # no clue
+  fi
+else
+  NEWVMA=`objdump --headers $1|grep "5 .stab "|gawk --traditional '{print $4}'`
+  if [ x"$NEWVMA" != x"" ];then
+    objcopy -S --adjust-section-vma $SECTION=0x$NEWVMA $1;
+    exit 0;
+  else
+    echo $0: unknown Error 1>&2
+    exit 1; # no clue
+  fi
+fi
+[ -f `dirname $1`/stripmap.$$ ] && cat stripmap.$$ && --objdump --headers $1 && echo objcopy -S --adjust-section-vma .rsrc=0xNEWVMA $1

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~1997-06-14  9:31 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1997-06-06  6:09 Strange problem with Sergey's cygwin.dll and remote X Chris Faylor
1997-06-07 22:39 ` Debugging cygwin.dll with gdb Geoffrey Noer
1997-06-14  9:31   ` Debugging cygwin.dll with gdb & static libcygwin_g.a Mikey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).