riscv-software-src / riscv-tools

RISC-V Tools (ISA Simulator and Tests)
1.15k stars 447 forks source link

Writing data into a file not exist getting user load segfault using pk #229

Open suisuiwudi opened 6 years ago

suisuiwudi commented 6 years ago

I just built all the tools today from latest source code.

I compile my program with C++11 nothing else on ubuntu 18.04.

File *file = fopen(filepath, "w")

If this file doesn't exist before running, file ptr is none.

And got this error while writing data.

z  0000000000000000 ra 000000000007a1be sp 000000007f7e97b0 gp 00000000000c1ac8
tp 0000000000000000 t0 0000000000074ac2 t1 000000000000000f t2 ffffffffffffffff
s0 000000007f7e9ab0 s1 0000000000087128 a0 0000000000000001 a1 0000000000000000
a2 0000000000087128 a3 000000007f7e9a40 a4 0000000000000000 a5 0000000000000001
a6 0000000000000800 a7 0000000000000040 s2 0000000000000000 s3 00000000000c0148
s4 0000000000000000 s5 0000000000000000 s6 0000000000000000 s7 000000007f7e9a40
s8 0000000000000000 s9 0000000000000000 sA 0000000000000000 sB 0000000000000000
t3 0000000000000005 t4 00000000000c3270 t5 0000000000000000 t6 0000000000000000
pc 000000000007a1d4 va 0000000000000010 insn       ffffffff sr 8000000200046020
User load segfault @ 0x0000000000000010

fopen with write flag doesn't create a file.

I need to create a file before running so that I didn't get error.

$(SPIKE_TARGET):
    $(CXX) $(CFLAGS) -o $(SPIKE_TARGET) $(MAIN) $(SRCS)

run: $(SPIKE_TARGET)
    $(SPIKE_EXE) $(PK_EXE) $(SPIKE_TARGET) 
g++ version: 6.4.0
gcc version: 6.4.0
aswaterman commented 6 years ago

Looks like this is a problem in the Newlib port: when I compile the same program with riscv64-unknown-linux-gnu-gcc -static, it works as expected.

The Newlib port is for embedded systems and so isn't really expected to support file management operations. In this case, it looks like Newlib doesn't agree with Linux on the definition of the O_CREAT flag to the open syscall - Linux wants 64, and Newlib provides 512.

suisuiwudi commented 6 years ago

@aswaterman I'm using C++11, so I tried to compile my program with riscv64-unknown-linux-gnu-g++ -static, it doesn't work.

jim-wilson commented 6 years ago

Different operating systems may have different APIs. We shouldn't expect to have a single copy of riscv-pk that works with multiple operating systems. Unless maybe we have OS info embedded in ELF headers that you can select the API from. Otherwise, you have to pick one, and target that one. Apparently riscv-pk only supports the linux API.

It looks like the newlib O_CREAT value was originally inherited from BSD Unix, and that BSD Unix uses a different value than Linux. See for instance https://github.com/freebsd/freebsd/blob/master/sys/sys/fcntl.h So it isn't actually wrong. It is just different from what you expected.

But it looks like newlib isn't the issue here. Since you are using a linux compiler, I'd suggest using qemu linux user mode instead of spike. qemu is what we use for toolchain testing, and is well supported. I don't think that riscv-pk is intended to support all linux or POSIX features. If you do think that riscv-pk needs to be fixed, then you should report a bug against riscv-pk instead of riscv-tools.

Oh, and don't use riscv-tools. It is poorly maintained and difficult to build. If you are using riscv-tools, you do not have the latest tools. You have something hopelessly out of date which may never be fixed. If you want a compiler, use (i.e. git clone) riscv/riscv-gnu-toolchain directly. If you want a linux kernel + buildroot, then use sifive/freedom-u-sdk.