rochus-keller / Oberon

Oberon parser, code model & browser, compiler and IDE with debugger, and an implementation of the Oberon+ programming language
GNU General Public License v2.0
464 stars 30 forks source link

PCALL / RAISE problem #23

Closed tenko closed 2 years ago

tenko commented 2 years ago

With the same Sqlite wrapper a simple test of pcall/raise seems to fail and return error 127 when run:

module Test

import Sqlite

type DBError = record end

proc tryDB
var e: pointer to DBError
begin
    println("Start")
    if  Sqlite.open("test.db", db) # Sqlite.OK then
        new(e)
        raise(e)
    end
    println("Finish")       
end tryDB

var
    db: carray 1 of *Sqlite.DB
    res: pointer to anyrec

begin
    println("Begin")
    pcall(res, tryDB)
    case res of
    | DBError: println(Sqlite.errmsg(db[0])^)
    end

    if db[0] # nil then
        Sqlite.close(db[0])
    end
    println("End")
end Test

Nothing gets printed, so probably something crashed before entering the main function.

rochus-keller commented 2 years ago

I tried your code both on Mono and C and both versions return

Begin
Start
Finish
End

It seems that Sqlite.open("test.db", db) even then returns OK if the file doesn't exist. Therefore raise() is never called.

tenko commented 2 years ago

Thanks for looking into this.

I believe you need to open a location without access or not existing like Sqlite.open("f:\test.db", db) where f: is not a valid location, otherwise it will create a new file or open an existing.

Got a traceback from GDB

Reading symbols from ./build/Test.exe...
(gdb) run
Starting program: C:\msys64\home\rute\tmp\oberonSqlite\build\Test.exe
[New Thread 9724.0x2f40]
[New Thread 9724.0x27a8]
[New Thread 9724.0x938]
[New Thread 9724.0x267c]
[New Thread 9724.0x2e74]
[New Thread 9724.0x59c]

Thread 1 received signal SIGSEGV, Segmentation fault.
0x00007ff9f4c02cdb in msvcrt!_setjmp () from C:\Windows\System32\msvcrt.dll
rochus-keller commented 2 years ago

I changed the proc tryDB line 11 to if Sqlite.open("f:/test.db", db) # Sqlite.OK then and again run the program in Mono and compiled with gcc -O2 (on my Linux i386 machine); both seem to work; I get this output:

Begin
Start
unable to open database file
End

Since we already saw an issue with your mingw 12.x installation, maybe there are other ones; can you try with the MSVC compiler or with CLANG or with an older mingw? I will try to compile and run the code on some other compilers/platforms too.

EDIT: please note that there is yet another place where an explicit "extern" might be necessary; see in Test.h the line with struct Test2DBError$Class$ Test$DBError$class$; If the compiler has a linkage issue maybe the accessed memory is wrongly initialized, which could explain the segmentation fault.

tenko commented 2 years ago

I tried with extern added to the line struct Test2DBError$Class$ Test$DBError$class$;, but with the same result. I will look into other compilers.

rochus-keller commented 2 years ago

I found the issue: the OBX$PushJump() body in OBX.Runtime.c is missing the return statement; add return j; to the end of the body; amazingly the code worked on Linux even though (and GCC not even put out a warning); just found it because I compiled and run on Windows with the MSVC compiler (which issued a warning). Just pushed some fixes.

tenko commented 2 years ago

Excellent. I can confirm with the latest commit everything works as expected.