This is the mail archive of the cygwin-developers@sourceware.cygnus.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[updated] Re: (patch) winsup noncygwin mess cleanup


Chris Faylor <cgf@cygnus.com> writes:
> 
> Hmm.  The stdin/out fds should be opened in hinfo_init since parent_alive
> should be NULL.  Is parent_alive non-NULL for some reason?

The trouble was in pinfo_init. We have to pretend not have a parent
process to take stuff from when dynamically loaded. I also force
parent_alive to NULL in that case just to be safe.

> I don't think it's really important.  But, of course, if we don't do
> it, the first question on the cygwin mailing list after your patch is
> applied will be something like "I'm trying to get my GLIP application
> running using the snapshot from 12/7 and now I can't send any signals.
> What gives?"

I'm running into bizarre segfaults *after* the DLL is initialized when
signals are enabled. Since I can't use gdb in this case, it's rather
hard to debug. There's also the issue of threading here (I'm testing
this with Java JNI), so I'm going to punt on this issue for now.

Here's an updated patch that fixes the stylistic issue as well as
the missing stdout/err issue when exec'd from a Cygwin app. The two
new and small changes are in dcrt0.cc:dll_crt0_1.

After this is in, I'll give it another shot ... hopefully problems will
magically fix themselves ;-)

Sun Dec  5 00:20:55 1999  Mumit Khan  <khan@xraylith.wisc.edu>

	* init.cc (dynamically_loaded): New global variable.
	(dll_entry): Use.
	* winsup.h (dynamically_loaded): Declare.
	* dcrt0.cc (do_global_ctors): Likewise.
	(set_os_type): Make static again.
	(dll_crt0_1): Handle dynamically_loaded case.
	* dll_init.cc (dll_dllcrt0_1): Delete.
	(dll_dllcrt0): Handle dynamically_loaded case. 
	(dll_noncygwin_dllcrt0): Mark obsolescent.
	* libccrt0.cc (cygwin_attach_noncygwin_dll): Delete.
	* pinfo.cc (pinfo_init): Don't inherit parent fds if dynamically
	loaded.
	* include/cygwin/cygwin_dll.h (cygwin_attach_noncygwin_dll): Delete
	prototype.
	(_cygwin_noncygwin_dll_entry): Mark obsolescent.

Index: init.cc
===================================================================
RCS file: /home/khan/CVSROOT/cygwin/winsup/init.cc,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 init.cc
--- init.cc	1999/12/04 02:01:43	1.1.1.1
+++ init.cc	1999/12/05 06:14:19
@@ -24,12 +24,15 @@ extern "C" void export_free (void *);
 
 extern void do_global_ctors (void (**in_pfunc)(), int force);
 
+int NO_COPY dynamically_loaded;
+
 int
 WINAPI dll_entry (HANDLE hdll, DWORD reason, void *static_load)
 {
   switch (reason)
     {
     case DLL_PROCESS_ATTACH:
+      dynamically_loaded = (static_load == NULL);
       break;
     case DLL_THREAD_ATTACH:
       break;
Index: winsup.h
===================================================================
RCS file: /home/khan/CVSROOT/cygwin/winsup/winsup.h,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 winsup.h
--- winsup.h	1999/12/04 02:01:45	1.1.1.1
+++ winsup.h	1999/12/05 06:19:50
@@ -30,6 +30,9 @@ details. */
 enum os_type {winNT = 1, win95, win98, win32s, unknown};
 extern os_type os_being_run;
 
+/* Used to check if Cygwin DLL is dynamically loaded. */
+extern int dynamically_loaded;
+
 #include <cygwin/version.h>
 
 #define TITLESIZE 1024
Index: dcrt0.cc
===================================================================
RCS file: /home/khan/CVSROOT/cygwin/winsup/dcrt0.cc,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 dcrt0.cc
--- dcrt0.cc	1999/12/04 02:01:42	1.1.1.1
+++ dcrt0.cc	1999/12/05 06:13:56
@@ -72,7 +72,7 @@ do_global_dtors (void)
     }
 }
 
-void
+static void
 do_global_ctors (void (**in_pfunc)(), int force)
 {
   if (!force)
@@ -103,7 +103,7 @@ os_type NO_COPY os_being_run;
    operating system being run.  This information is used internally
    to manage the inconsistency in Win32 API calls between Win32 OSes. */
 /* Cygwin internal */
-void
+static void
 set_os_type ()
 {
   OSVERSIONINFO os_version_info;
@@ -561,7 +561,10 @@ ResourceLocks _reslock NO_COPY;
 MTinterface _mtinterf NO_COPY;
 #endif
 
-/* Take over from libc's crt0.o and start the application.  */
+/* Take over from libc's crt0.o and start the application. Note the
+   various special cases when Cygwin DLL is being runtime loaded (as
+   opposed to being link-time loaded by Cygwin apps) from a non
+   cygwin app via LoadLibrary.  */
 static void
 dll_crt0_1 ()
 {
@@ -660,7 +663,9 @@ dll_crt0_1 ()
       longjmp (ciresrv->jmp, ciresrv->cygpid);
     }
 
-  pinfo_init (info);		/* Initialize our process table entry. */
+  /* Initialize our process table entry. Don't use the parent info for
+     dynamically loaded case. */
+  pinfo_init ((dynamically_loaded) ? NULL : info);		
 
   if (!old_title && GetConsoleTitle (title_buf, TITLESIZE))
       old_title = title_buf;
@@ -689,7 +694,7 @@ dll_crt0_1 ()
 
   /* Set new console title if appropriate. */
 
-  if (display_title)
+  if (display_title && !dynamically_loaded)
     {
       char *cp = line;
       if (strip_title_path)
@@ -702,8 +707,13 @@ dll_crt0_1 ()
   /* Allocate dtable */
   dtable_init ();
 
-  /* Initialize signal/subprocess handling. */
-  sigproc_init ();
+  /* Can't use signals in non-cygwin apps since it depends on synchronizing 
+     with a a helper thread.  */
+  if (!dynamically_loaded)
+    {
+      /* Initialize signal/subprocess handling. */
+      sigproc_init ();
+    }
 
   /* Connect to tty. */
   tty_init ();
@@ -723,9 +733,10 @@ dll_crt0_1 ()
 		  cygwin_version.dll_major, cygwin_version.dll_minor,
 		  cygwin_version.api_major, cygwin_version.api_minor);
 
-  /* Scan the command line and build argv.  Expand wildcards if not called from
-     another cygwin process. */
-  build_argv (line, argv, argc, NOTSTATE (myself, PID_CYGPARENT) && allow_glob);
+  /* Scan the command line and build argv.  Expand wildcards if not 
+     called from another cygwin process. */
+  build_argv (line, argv, argc, 
+	      NOTSTATE (myself, PID_CYGPARENT) && allow_glob);
 
   /* Convert argv[0] to posix rules if it's currently blatantly
      win32 style. */
@@ -746,13 +757,16 @@ dll_crt0_1 ()
   set_errno (0);
   debug_printf ("user_data->main %p", user_data->main);
 
-  /* Flush signals and ensure that signal thread is up and running. */
-  sig_send (NULL, __SIGFLUSH);
+  /* Flush signals and ensure that signal thread is up and running. Can't
+     do this for noncygwin case since the signal thread is blocked due to
+     LoadLibrary serialization. */
+  if (!dynamically_loaded)
+    sig_send (NULL, __SIGFLUSH);
 
   /* Initialize uid, gid. */
   uinfo_init ();
 
-  if (user_data->main)
+  if (user_data->main && !dynamically_loaded)
     exit (user_data->main (argc, argv, *user_data->envptr));
 }
 
@@ -797,9 +811,16 @@ dll_crt0 (per_process *uptr)
 	      console_shared_h = child_proc_info->console_h;
 
 	      /* We don't want subprocesses to inherit this */
-	      if (!DuplicateHandle (me, child_proc_info->parent_alive, me, &parent_alive,
-					 0, 0, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
-		system_printf ("parent_alive DuplicateHandle failed, %E");
+	      if (!dynamically_loaded)
+	        {
+		  if (!DuplicateHandle (me, child_proc_info->parent_alive, 
+	                                me, &parent_alive, 0, 0, 
+				        DUPLICATE_SAME_ACCESS 
+				        | DUPLICATE_CLOSE_SOURCE))
+		    system_printf ("parent_alive DuplicateHandle failed, %E");
+		}
+	      else if (parent_alive)
+		parent_alive = NULL;
 
 	      switch (child_proc_info->type)
 		{
Index: dll_init.cc
===================================================================
RCS file: /home/khan/CVSROOT/cygwin/winsup/dll_init.cc,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 dll_init.cc
--- dll_init.cc	1999/12/04 02:01:43	1.1.1.1
+++ dll_init.cc	1999/12/05 06:14:03
@@ -457,244 +457,26 @@ extern "C"
   extern struct _reent reent_data;
 };
 
-/* Initialize Cygwin DLL. This is only done if this is the first cygwin
-   DLL to be loaded and the main app is not Cygwin. */
-/* FIXME: This function duplicates too much code from dll_crt0_1 in
-   dcrt0.cc.  Need to consolidate this and remove the duplication. */
-
-static NO_COPY STARTUPINFO si;
-static NO_COPY LPBYTE info = NULL;
-# define ciresrv ((struct child_info_fork *)(si.lpReserved2))
-
-extern void alloc_stack (child_info_fork *ci);
-extern void do_global_ctors (void (**)(), int);
-extern void set_os_type ();
-
-static void
-dll_dllcrt0_1 (per_process *uptr)
-{
-  /* 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. */
-  exception_list cygwin_except_entry;
-
-  int mypid = 0;
-
-  set_console_handler ();
-  if (!DuplicateHandle (GetCurrentProcess (), GetCurrentProcess (),
-		       GetCurrentProcess (), &hMainProc, 0, FALSE,
-			DUPLICATE_SAME_ACCESS))
-    hMainProc = GetCurrentProcess ();
-  else
-    ProtectHandle (hMainProc);
-
-  DuplicateHandle (hMainProc, GetCurrentThread (), hMainProc,
-		   &hMainThread, 0, FALSE, DUPLICATE_SAME_ACCESS);
-  ProtectHandle (hMainThread);
-
-  char zeros[sizeof (ciresrv->zero)] = {0};
-  /* Set the local copy of the pointer into the user space. */
-  user_data = uptr;
-  user_data->heapbase = user_data->heapptr = user_data->heaptop = NULL;
-
-  GetStartupInfo (&si);
-  if (si.cbReserved2 >= EXEC_MAGIC_SIZE &&
-      memcmp (ciresrv->zero, zeros, sizeof (zeros)) == 0)
-    switch (ciresrv->type)
-      {
-	case PROC_EXEC:
-	case PROC_SPAWN:
-	case PROC_FORK:
-	case PROC_FORK1:
-	  {
-	    child_proc_info = ciresrv;
-	    mypid = child_proc_info->cygpid;
-	    cygwin_shared_h = child_proc_info->shared_h;
-	    console_shared_h = child_proc_info->console_h;
-
-	    /* We don't want subprocesses to inherit this */
-	    if (!DuplicateHandle (hMainProc, child_proc_info->parent_alive, hMainProc,
-				  &parent_alive,
-				  0, 0, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
-	      system_printf ("parent_alive DuplicateHandle failed, %E");
-
-	    switch (child_proc_info->type)
-	      {
-		case PROC_EXEC:
-		case PROC_SPAWN:
-		  info = si.lpReserved2 + ciresrv->cb;
-		  break;
-		case PROC_FORK:
-		case PROC_FORK1:
-		  user_data->forkee = child_proc_info->cygpid;
-		  user_data->heaptop = child_proc_info->heaptop;
-		  user_data->heapbase = child_proc_info->heapbase;
-		  user_data->heapptr = child_proc_info->heapptr;
-		  alloc_stack (ciresrv);		// may never return
-	      }
-	    break;
-	  }
-	default:
-	  if ((ciresrv->type & PROC_MAGIC_MASK) == PROC_MAGIC_GENERIC)
-	    api_fatal ("conflicting versions of cygwin1.dll detected.  Use only the most recent version.\n");
-      }
-
-  do_global_ctors (&__CTOR_LIST__, 1);
-
-#ifdef DEBUGGING
-  if (child_proc_info)
-    switch (child_proc_info->type)
-      {
-	case PROC_FORK:
-	case PROC_FORK1:
-	  ProtectHandle (child_proc_info->forker_finished);
-	case PROC_EXEC:
-	  ProtectHandle (child_proc_info->subproc_ready);
-      }
-#endif
-
-  regthread ("main", GetCurrentThreadId ());
-
-  check_sanity_and_sync (user_data);
-
-  /* Nasty static stuff needed by newlib -- point to a local copy of
-     the reent stuff.
-     Note: 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). */
-
-  *(user_data->impure_ptr_ptr) = &reent_data;
-  _impure_ptr = &reent_data;
-
-#ifdef _MT_SAFE
-  user_data->resourcelocks = &_reslock;
-  user_data->resourcelocks->Init();
-
-  user_data->threadinterface = &_mtinterf;
-  user_data->threadinterface->Init0();
-#endif
-
-  /* Set the os_being_run global. */
-  set_os_type ();
-
-  /* If we didn't call SetFileApisToOEM, console I/O calls would use a
-     different codepage than other Win32 API calls.  In some languages
-     (not English), this would result in "cat > filename" creating a file
-     by a different name than if CreateFile was used to create filename.
-     SetFileApisToOEM prevents this problem by making all calls use the
-     OEM codepage. */
-
-  SetFileApisToOEM ();
-
-  /* Initialize the host dependent constants object. */
-  host_dependent.init ();
-
-  /* Initialize the cygwin subsystem if this is the first process,
-     or attach to the shared data structure if it's already running. */
-  shared_init ();
-
-  if (mypid)
-    set_myself (cygwin_shared->p[mypid]);
-
-  /* Initialize events. */
-  events_init ();
-
-  (void) SetErrorMode (SEM_FAILCRITICALERRORS);
-
-  /* Call this once before heap initializing, to avoid heap fragmentation */
-  extern PSID get_admin_sid (), get_system_sid (), get_world_sid ();
-  get_admin_sid ();
-  get_system_sid ();
-  get_world_sid ();
-
-  /* Initialize the heap. */
-  heap_init ();
-
-  /* Initialize SIGSEGV handling, etc...  Because the exception handler
-     references data in the shared area, this must be done after
-     shared_init. */
-  init_exceptions (&cygwin_except_entry);
-
-  if (user_data->forkee)
-    {
-      /* If we've played with the stack, stacksize != 0.  That means that
-	 fork() was invoked from other than the main thread.  Make sure that
-	 frame pointer is referencing the new stack so that the OS knows what
-	 to do when it needs to increase the size of the stack.
-
-	 NOTE: Don't do anything that involves the stack until you've completed
-	 this step. */
-      if (ciresrv->stacksize)
-	{
-	  asm ("movl %0,%%fs:4" : : "r" (ciresrv->stackbottom));
-	  asm ("movl %0,%%fs:8" : : "r" (ciresrv->stacktop));
-	}
-
-      longjmp (ciresrv->jmp, ciresrv->cygpid);
-    }
-
-  pinfo_init (NULL);		/* Initialize our process table entry. */
-
-  /* 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. */
-
-#ifdef _MT_SAFE
-  user_data->threadinterface->ClearReent();
-  user_data->threadinterface->Init1();
-#else
-  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;
-#endif
-
-  /* Allocate dtable */
-  dtable_init ();
-
-  /* NOTE: No call to sigproc_init() nor to tty_init(). These create
-     threads and uses synchronization, and that's a NO-NO from a
-     DLL entry point thanks to the Windows serialization when loading
-     DLLs dynamically. See MSDN docs for more info.  */
-
-  /* Set up standard fds in file descriptor table. */
-  hinfo_init ();
-
-  /* Initialize uid, gid. */
-  uinfo_init ();
-
-  syscall_printf ("Application CYGWIN version: %d.%d, api: %d.%d",
-		  user_data->dll_major, user_data->dll_minor,
-		  user_data->api_major, user_data->api_minor);
-  syscall_printf ("CYGWIN DLL version: %d.%d, api: %d.%d",
-		  cygwin_version.dll_major, cygwin_version.dll_minor,
-		  cygwin_version.api_major, cygwin_version.api_minor);
-
-  /* Call init of loaded dlls. */
-  DllList::the().initAll();
-
-  set_errno (0);
-}
-
 extern "C"
 int
 dll_dllcrt0 (HMODULE h, per_process *p)
 {
+  /* Partially initialize Cygwin guts for non-cygwin apps. */
+  if (dynamically_loaded && (! user_data || user_data->magic_biscuit == 0))
+    {
+      dll_crt0 (p);
+    }
   return _the.recordDll (h, p);
 }
 
+/* OBSOLETE: This function is obsolescent and will go away in the
+   future.  Cygwin can now handle being loaded from a noncygwin app
+   using the same entry point. */
+
 extern "C"
 int
 dll_noncygwin_dllcrt0 (HMODULE h, per_process *p)
 {
-  /* Partially initialize Cygwin guts for non-cygwin apps. */
-  if (! user_data || user_data->magic_biscuit == 0)
-    {
-      dll_dllcrt0_1 (p);
-    }
   return dll_dllcrt0 (h, p);
 }
 
Index: libccrt0.cc
===================================================================
RCS file: /home/khan/CVSROOT/cygwin/winsup/libccrt0.cc,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 libccrt0.cc
--- libccrt0.cc	1999/12/04 02:01:43	1.1.1.1
+++ libccrt0.cc	1999/12/04 21:47:55
@@ -94,13 +94,3 @@ cygwin_attach_dll (HMODULE h, MainFunc f
   return dll_dllcrt0 (h, &this_proc);
 }
 
-/* for a loaded dll from a non-cygwin app */
-int
-cygwin_attach_noncygwin_dll (HMODULE h, MainFunc f)
-{
-  cygwin_crt0_common (f);
-
-  /* jump into the dll. */
-  return dll_noncygwin_dllcrt0 (h, &this_proc);
-}
-
Index: include/cygwin/cygwin_dll.h
===================================================================
RCS file: /home/khan/CVSROOT/cygwin/winsup/include/cygwin/cygwin_dll.h,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 cygwin_dll.h
--- cygwin_dll.h	1999/12/04 02:01:49	1.1.1.1
+++ cygwin_dll.h	1999/12/04 21:47:48
@@ -29,7 +29,6 @@ CDECL_BEGIN								      \
 									      \
   int WINAPI Entry (HANDLE h, DWORD reason, void *ptr);		              \
   extern int cygwin_attach_dll ();					      \
-  extern int cygwin_attach_noncygwin_dll ();				      \
   extern void cygwin_detach_dll ();	                      		      \
 CDECL_END								      \
 									      \
@@ -88,31 +87,10 @@ int WINAPI _cygwin_dll_entry (HANDLE h, 
   return ret;								      \
 }									      \
 									      \
+/* OBSOLETE: This is only provided for source level compatibility. */         \
 int WINAPI _cygwin_noncygwin_dll_entry (HANDLE h, DWORD reason, void *ptr)    \
 {									      \
-  int ret;								      \
-  ret = 1;								      \
-									      \
-  switch (reason)							      \
-  {									      \
-    case DLL_PROCESS_ATTACH:						      \
-    {									      \
-      storedHandle = h;							      \
-      storedReason = reason;						      \
-      storedPtr = ptr;							      \
-      dll_index = cygwin_attach_noncygwin_dll (h, &__dllMain);   	      \
-      if (dll_index == -1)						      \
-	ret = 0;							      \
-    }									      \
-    break;								      \
-									      \
-    default:						      		      \
-    {									      \
-      ret = _cygwin_dll_entry (h, reason, ptr);				      \
-    }									      \
-    break;								      \
-  }									      \
-  return ret;								      \
+  return _cygwin_dll_entry (h, reason, ptr);				      \
 }									      \
 
 #endif /* __CYGWIN_CYGWIN_DLL_H__ */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]