[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[Fwd: Debugging execve problems]



Hi,

Looks like this mail did not arrive to the ML. I'm resending and people
interested can contact me for the non-stripped iconx executable (1MB),
or build yourself from the Debian source.

-------- Forwarded Message --------
From: Svante Signell <svante.signell@telia.com>
Reply-to: svante.signell@telia.com
To: Bug hurd mailing list <bug-hurd@gnu.org>
Subject: Debugging execve problems
Date: Wed, 04 Jan 2012 11:10:11 +0100

Hi,

Attached are test programs and a partial gdb session to hunt down the
problems with execv for the icon package:

Without . in PATH:
==================
 ./a.out
error in startup code
/dev/fd/3: can't read interpreter file header

With . in PATH:
===============
PATH=.:$PATH; ./a.out
                                                        Hello, hello.

Test programs: test_execve.c (parts of src/icont/tunix.c)
gcc -g test_execve.c -> a.out
Icon executable: iconx
icon application program (source): hello.icn
icon application program (executable): hello
gdb session (results up to now, not complete!): debugging_execve


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MaxPath 256
//extern char *iconxloc;

/*
 * execute - execute iconx to run the icon program
 */
static void execute(char *ofile, char *efile, char *args[]) {
   int n;
   char **argv, **p;
   char buf[MaxPath+10];
   char *iconxloc = "./iconx";

   /*
    * Build argument vector.
    */
   for (n = 0; args[n] != NULL; n++)    /* count arguments */
      ;
   p = argv = malloc((n + 5) * sizeof(char *));

   *p++ = ofile;                        /* pass icode file name */
   while ((*p++ = *args++) != 0)        /* copy args into argument vector */
      ;
   *p = NULL;

   /*
    * Redirect stderr if requested.
    */
   if (efile != NULL) {
      close(fileno(stderr));
      if (strcmp(efile, "-") == 0)
         dup(fileno(stdout));
      else if (freopen(efile, "w", stderr) == NULL)
	fprintf(stderr,"could not redirect stderr to %s\n", efile);
      }

   /*
    * Export $ICONX to specify the path to iconx.
    */
   sprintf(buf, "ICONX=%s", iconxloc);
   putenv(buf);

   /*
    */
   execv(ofile, argv);
   fprintf(stderr,"could not execute %s\n", ofile);
   }

void main(void)
{
  char *icode = "hello";
  char *args[2] = {"hello", NULL};

  execute(icode, NULL, args);          /* execute the program */
  fprintf(stderr,"could not execute %s\n", icode);
}
#  hello.icn -- used in various ways by the Test-opts script

procedure main(args)
   write("\t\t\t\t\t\t\tHello, ", get(args) | "there", ".")
end

Attachment: hello
Description: application/shellscript

gcc -g test_execve.c

Without . in PATH
=================
gdb ./a.out
break test_execve.c:11
n until
48         execv(ofile, argv);
(gdb) s
execv (path=0x80489dc "hello", argv=0x804a358) at execv.c:26
26      execv.c: No such file or directory.
        in execv.c
dir /usr/src/kernels/eglibc/eglibc-2.13/posix/
22      /* Execute PATH with arguments ARGV and environment from `environ'.  */
23      int
24      execv (const char *path, char *const argv[])
25      {
26        return __execve (path, argv, __environ);
27      }
(gdb) step
__execve (file_name=0x80489dc "hello", argv=0x804a358, envp=0x804a378)
    at ../sysdeps/mach/hurd/execve.c:30
30      {
(gdb) list
25      int
26      __execve (file_name, argv, envp)
27           const char *file_name;
28           char *const argv[];
29           char *const envp[];
30      {
31        error_t err;
32        file_t file = __file_name_lookup (file_name, O_EXEC, 0);
33      
34        if (file == MACH_PORT_NULL)
(gdb) p file
$42 = 125
35          return -1;
36      
37        /* Hopefully this will not return.  */
38        err = _hurd_exec (__mach_task_self (), file, argv, envp);
[New Thread 27529.6]
warning: "gnu_write_inferior vm_read failed": (os/kern) invalid address
warning: "gnu_write_inferior vm_read failed": (os/kern) invalid address
Can't fetch registers from thread bogus thread id 4: No such thread

With . in PATH
===============
export PATH=.:$PATH
gdb ./a.out
dir /usr/src/kernels/eglibc/eglibc-2.13/posix/
break execve.c:30
(gdb)  p envp[10]
$5 = 0x10265c0 "PATH=.:/sbin:/usr/sbin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games"
(gdb) p file
$11 = 125
[New Thread 27565.6]
warning: "gnu_write_inferior vm_read failed": (os/kern) invalid address
warning: "gnu_write_inferior vm_read failed": (os/kern) invalid address
Can't fetch registers from thread bogus thread id 4: No such thread

gdb ./a.out
dir /usr/src/kernels/eglibc/eglibc-2.13/posix/
break execve.c:38
run
Starting program: /home/srs/DEBs/icon/debugging_icon/a.out 
[New Thread 27569.5]
Can't fetch registers from thread bogus thread id 4: No such thread

restarting again:

dir /usr/src/kernels/eglibc/eglibc-2.13/hurd/
list
34         If TASK == mach_task_self (), some ports are dealloc'd by the exec server.
35         ARGV and ENVP are terminated by NULL pointers.  */
36      error_t
37      _hurd_exec (task_t task, file_t file,
38                  char *const argv[], char *const envp[])
39      {
40        error_t err;
41        char *args, *env;
42        size_t argslen, envlen;
43        int ints[INIT_INT_MAX];
44        mach_port_t ports[_hurd_nports];
45        struct hurd_userlink ulink_ports[_hurd_nports];
46        inline void free_port (unsigned int i)
47          {
48            _hurd_port_free (&_hurd_ports[i], &ulink_ports[i], ports[i]);

(gdb) where
#0  _hurd_exec (task=1, file=125, argv=0x804a358, envp=0x804a378)
    at hurdexec.c:39
...
59        if (argv == NULL)
60          args = NULL, argslen = 0;
61        else if (err = __argz_create (argv, &args, &argslen))
62          return err;
err = 0
63        if (envp == NULL)
64          env = NULL, envlen = 0;
65<-        else if (err = __argz_create (envp, &env, &envlen))
66          goto outargs;
69        for (i = 0; i < _hurd_nports; ++i)
70          if (i == INIT_PORT_PROC && task != __mach_task_self ())
71            {
72              /* This is another task, so we need to ask the proc server
73                 for the right proc server port for it.  */
81          else
82            ports[i] = _hurd_port_get (&_hurd_ports[i], &ulink_ports[i]);
gdb hang here

Reply to: