Hallo Andre, On Sun, 28 Dec 2003 at 03:30 (+0100), Andre Heine wrote:
Am Saturday 27 December 2003 19:55 schrieb Bernhard Walle:
On Sat, 27 Dec 2003 at 19:33 (+0100), Andre Heine wrote:
Am Saturday 27 December 2003 14:25 schrieb Bernhard Walle:
On Sat, 27 Dec 2003 at 14:10 (+0100), Andre Heine wrote:
Am Saturday 27 December 2003 13:42 schrieb Bernhard Walle:
[...]
Bei Rattis Problem geht es um einen SIGSEGV. Da wird über Perl auf C-Code zugegriffen und dieser Code produziert einen echten Speicher- zugriffsfehler. Das Betriebssystem schickt an den Prozess ein SIGSEGV Signal mit der Aufforderung, dass das Programm beendet wird.
Ok. Diesen Umstand hab' ich übersehen ;(
Ich dachte an ein Java Programm von der Arbeit, wo ich externe Programme, Skripte, etc starten in der shell starten musste.
Einige Programme haben sich mit Segfault beendet, meins musste aber weiterlaufen...
Funktioniert doch sowieso, hab's gerade mal ausprobiert.
===================================================================
import java.io.IOException;
class Extern
{
public static void main (String[] args)
{
System.out.println("Starte Testprogramm ...");
Process p = null;
try
{
p = Runtime.getRuntime().exec("acroread");
p.waitFor();
}
catch (IOException e)
{
e.printStackTrace();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("Fortgefaren");
}
}
===================================================================
Wenn ich das Programm mit "killall -SEGV acroread" abschieße, und das
dürfte das gleiche wie ein "echter" Speicherzugriffsfehler sein, wird
keine Exception geworfen und mit "Fortgefahren" weitergemacht.
Dann habe ich mal weil's so schön ist nativen Code geschrieben und darin
absichtlich ein Speicherzugriffsfehler produziert:
======= Native.java ================================================
import java.io.*;
class Native
{
static
{
System.loadLibrary("native");
}
public static native double nativeSqrt(double d);
public static void main (String[] args) throws IOException
{
System.out.println("Zahl eingeben: ");
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
double d = Double.parseDouble(reader.readLine());
System.out.println("Java-Wurzel von " + d + " = " + Math.sqrt(d));
try
{
System.out.println("Native Wurzel von " + d + " = " + nativeSqrt(d));
}
catch (Throwable t)
{
System.out.println("t gefangen: " + t.getMessage());
}
}
}
======================================================================
======= Native.cc ====================================================
#include
Ist den ein "Fehlschlag bei der Speicherbeschaffung" kein falscher Zugriff auf den Speicher (oder ist damit nur gemeint, das zuwenig Speicher vorhanden ist, vermutlich ja *g*).
Nein. Der new-Operator kann scheitern, wenn kein Speicher mehr da ist. Dann wirft dieser Operator eine std::bad_alloc-Ausnahme. Wenn Du die Ausnahme abfängst und trotzdem weitermachst und auf den nicht beschafften Speicher zugreifst, bekommst Du wieder einen SIGSEGV, den Du nicht mehr abfangen kannst (außer über Signal handling).
Genau, darum werden ja "Ausnahmen geworfen". Man soll nicht mehr auf diese Variable zugreifen.
Ja, Du kannst mit Ausnahmebehandlung Speicherzugriffsfehler vermeiden (was auch über den Rückgabewert NULL wie bei malloc() möglich wäre, nur halt wesentlich unkomfortabler), aber Du kannst sie nicht abfangen, wenn sie bereits passiert sind. Das ist ein wesentlicher Unterschied. In Java sollte es bis auf nativen Code (s.o.) keine Speicherzugriffs- fehler geben, weil die Sprache und die JVM so designed wurden, dass man keine Low-Level-Speicheroperationen durchführen kann. In reinem Perl kann man auch keine Speicherzugriffsfehler produzieren, Ratti verwendet aber eine Bibliothek, die auf C(/C++)-Code zurückgreift. Gruß, Bernhard -- _________ http://www.bwalle.de _________________________________________________ Es ist ein großer Vorteil im Leben, die Fehler, aus denen man lernen kann, möglichst früh zu begehen. -- Sir Winston Churchil