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