Date: Fri, 30 Nov 2007 17:28:21 -0500 (EST) From: Daniel Eischen <deischen@freebsd.org> To: "Arno J. Klaassen" <arno@heho.snv.jussieu.fr> Cc: nate@yogotech.com, java@freebsd.org Subject: Re: cvs commit: src/lib/libkse/thread thr_kern.c Message-ID: <Pine.GSO.4.64.0711301659060.5465@sea.ntplx.net> In-Reply-To: <wpprxrto0s.fsf@heho.snv.jussieu.fr> References: <200711301716.lAUHGEV1064334@repoman.freebsd.org> <wpprxrto0s.fsf@heho.snv.jussieu.fr>
index | next in thread | previous in thread | raw e-mail
[-- Attachment #1 --]
On Fri, 30 Nov 2007, Arno J. Klaassen wrote:
>
> Hello,
>
> Daniel Eischen <deischen@freebsd.org> writes:
>
>> deischen 2007-11-30 17:16:14 UTC
>>
>> FreeBSD src repository
>>
>> Modified files:
>> lib/libkse/thread thr_kern.c
>> Log:
>> Initialize the current thread and signal locks so that sigaction()
>> will work after a fork().
>
>
> I spotted this patch wrt my .exec() problems.
>
> Quick recall : I get strange exceptions in java-code doing quite
> a lot of .exec() calls, but only on 2x2way SMP, not on UP or
> single CPU SMP.
>
> I get these problems under releng_6 as well, but 'my' only
> 2x2way SMP box is a production server I cannot test on.
>
> Seeing this patch, I retested on a 2x2 SMP box running releng_7(amd64)
> libmapping libthr.so.3 to libkse.so.3 for /usr/local/jdk1.5.0/bin/java_g.
>
> I use the attached test-program (adapted after gentile remarks of Nate
> Williams; I hope there's not yet another program error in it but it
> does run flawlessly with libthr).
>
> Running it like "/usr/local/jdk1.5.0/bin/java_g Test_cmd /tmp 0 "
> it will produce a java_g.core after a number of iterations
> with exit status 139.
>
> Both with and without the above patch applied (to releng_7) the
> gdb trace shows (I recompiled libkse with -g as well, but no
> line-numbers showing up ) :
>
> gdb -core java_g.core /usr/local/jdk1.5.0/bin/java_g
> GNU gdb 6.1.1 [FreeBSD]
> Copyright 2004 Free Software Foundation, Inc.
> GDB is free software, covered by the GNU General Public License, and you are
> welcome to change it and/or distribute copies of it under certain conditions.
> Type "show copying" to see the conditions.
> There is absolutely no warranty for GDB. Type "show warranty" for details.
> This GDB was configured as "amd64-marcel-freebsd"...
> Core was generated by `java_g'.
[ ... ]
> (gdb) where
> #0 0x000000080075d151 in pthread_sigmask () from /usr/lib/libkse.so.3
> #1 0x000000080075d103 in sigprocmask () from /usr/lib/libkse.so.3
> #2 0x000000080076c423 in pthread_kill () from /usr/lib/libkse.so.3
> #3 0x0000000800758f29 in fork () from /usr/lib/libkse.so.3
> #4 0x0000000801e43158 in jdk_fork_wrapper ()
This isn't really telling me anything because fork() doesn't call
pthread_kill(), and pthread_kill() doesn't call sigprocmask().
--
DE
[-- Attachment #2 --]
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.StringTokenizer;
final class Test_cmd
{
public static void main (String[] args) throws Exception
{
final String path = args[0];
final long max_wait_time_ms = Long.parseLong(args[1]);
final String[] cmd = new String[3];
cmd[0] = "/bin/sh";
cmd[1] = "-c";
cmd[2] = "sync; if [ -e " + path + " ]; then df -k " + path;
cmd[2] += ";else echo; echo \"x -1 -1 0\";fi ";
for (int i= 1; i <= 999; i++)
{
final StringBuffer parsed_std_out = new StringBuffer();
int last_line_start_index = 0;
final String line;
final StringTokenizer st;
final int nr_of_tokens;
long free_bytes = -1;
System.out.println("test <" + i + ">.");
execute_command(cmd, max_wait_time_ms, parsed_std_out);
last_line_start_index = parsed_std_out.lastIndexOf("\n") + 1;
if (last_line_start_index < 0)
{
System.err.println("Failed to find last line start index!");
continue;
}
line = parsed_std_out.substring(last_line_start_index,
parsed_std_out.length());
if (line == null)
{
System.err.println("Failed to find last line in std out!");
continue;
}
st = new StringTokenizer(line);
nr_of_tokens = st.countTokens();
if (nr_of_tokens >= 4)
{
final String free_space_str;
// Filesystem
st.nextToken();
// 1K-blocks
st.nextToken();
// Used
st.nextToken();
// Avail
free_space_str = st.nextToken();
try
{
free_bytes = Long.parseLong(free_space_str);
}
catch (NumberFormatException nfe)
{
free_bytes = -1;
nfe.printStackTrace();
}
free_bytes *= 1024;
}
System.out.println("free bytes <" + free_bytes + ">.");
}
}
/*
* if _max_wait_time_ms != 0, wait _max_wait_time_ms for std out only
* to finish. So std err ain't checked, and neither is the process itselves!!
* For the process we simply call detroy in the finally clause
* else wait "for ever" untill process has finished.
*/
public static boolean execute_command(final String[] _cmd,
final long _max_wait_time_ms, final StringBuffer _parsed_std_out)
{
boolean ok = false;
String full_cmd = "";
Process proc = null;
int exit_value = 0;
Stream_reader std_out = null;
Stream_reader std_err = null;
try
{
for (int i = 0; i < _cmd.length; i++)
{
if (i > 0)
full_cmd += " ";
full_cmd += _cmd[i];
}
proc = Runtime.getRuntime().exec(_cmd);
std_out = new Stream_reader(proc.getInputStream());
std_err = new Stream_reader(proc.getErrorStream());
if (_max_wait_time_ms == 0)
{
proc.waitFor ();
std_out.wait_for();
}
else
std_out.join(_max_wait_time_ms);
if (_parsed_std_out != null)
_parsed_std_out.append(std_out.get_data());
if ( (exit_value = proc.exitValue ()) != 0)
{
System.err.println("Command <" + full_cmd
+ "> finished with exit value <" + exit_value + "> Std error is:\n"
+ std_err.get_data());
}
else
ok = true;
}
catch (InterruptedException int_ex)
{
System.err.println("Command <" + full_cmd
+ "> failed with interrupted exception!");
int_ex.printStackTrace();
exit_value = 1;
ok = false;
}
catch (IOException io_ex)
{
System.err.println("Command <" + full_cmd
+ "> failed with IO exception!");
io_ex.printStackTrace();
io_ex.printStackTrace();
exit_value = 1;
ok = false;
}
catch (Exception ex)
{
System.err.println("Command <" + full_cmd
+ "> failed with exception!");
ex.printStackTrace();
exit_value = 1;
ok = false;
}
finally
{
if (proc != null)
proc.destroy ();
if (std_out != null)
std_out.stop();
if (std_err != null)
std_err.stop();
}
return ok;
} /* execute_command */
private static class Stream_reader implements Runnable
{
private final InputStream input_stream;
private final StringBuffer data;
private final Thread thread;
private boolean stop = false;
private static final String LINE_SEP = "\n";
private Stream_reader(final InputStream _input_stream)
{
this.input_stream = _input_stream;
data = new StringBuffer();
thread = new Thread (this, "Stream_reader");
thread.setPriority (Thread.NORM_PRIORITY);
thread.start ();
}
public void run()
{
try
{
BufferedReader buffered_reader = new BufferedReader(
new InputStreamReader(input_stream));
while (stop == false)
{
final String line;
line = buffered_reader.readLine();
if (line == null)
break;
if (data.length() > 0)
data.append(LINE_SEP);
data.append(line);
}
buffered_reader.close();
}
catch (java.io.IOException io_ex)
{
/* do nothing */
}
} /* run */
private String get_data()
{
return data.toString();
} /* get_data */
private void stop()
{
stop = true;
} /* stop */
private void wait_for()
{
join(0);
} /* wait_for */
private void join(final long _max_time_ms)
{
try
{
thread.join(_max_time_ms);
}
catch (InterruptedException int_ex)
{
int_ex.printStackTrace();
}
} /* join */
} /* class Stream_reader */
}
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.GSO.4.64.0711301659060.5465>
