volumit / tricore_gcc940_linux_bins

GCC 9.4.0. Tricore / AURIX Prebuild Binaries for Ubuntu
GNU General Public License v3.0
15 stars 3 forks source link

tricore gdb crash when fopen is used in source #1

Open Changqing-JING opened 2 years ago

Changqing-JING commented 2 years ago

Environment:

uname -a
Linux ubuntu 5.15.0-25-generic #25-Ubuntu SMP Wed Mar 30 15:54:22 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

Reproduce steps:

  1. Install tricore gcc:

    sudo apt install 7zip
    git clone https://github.com/volumit/tricore_gcc940_linux_bins.git
    cd tricore_gcc940_linux_bins
    7z x tricore_940_linux.zip.001
    chmod -R 777 tricore_940_linux
    echo "export TRICORE_GCC_PATH=$(pwd)/tricore_940_linux/bin" >> ~/.profile
  2. Build tricore qemu from source:

    git clone https://github.com/volumit/qemu.git
    cd qemu
    git submodule update --init --progress
    mkdir build
    cd build
    CC=gcc-9 CFLAGS=-Wno-error ../configure
    make -j $(nproc)
    echo "export TRICORE_QEMU_PATH=$(pwd)/build" >> ~/.profile
  3. Build tricore gdb

    git clone https://github.com/volumit/gdb-tricore.git
    cd gdb-tricore
    CC=gcc-9 CFLAGS=-Wno-error ./configure --target=tricore-unknown-elf x86_64-pc-linux-gnu --host=x86_64-pc-linux-gnu
    make -j $(nproc)
    echo "export TRICORE_GDB_PATH=$(pwd)/gdb" >> ~/.profile
  4. Build follow code with tricore gcc:

    $TRICORE_GCC_PATH/tricore-elf-gcc -g -Wall -o build/c_demo.elf c_demo.c
    
    #include <stdio.h>

int main(){

FILE* f = fopen("", "rb");

return f==NULL;

}


6. Launch tricore qemu:
```shell
$TRICORE_QEMU_PATH/qemu-system-tricore -display none -M tricore_tsim161 -semihosting -S -s -kernel build/c_demo.elf
  1. Connect tricore gdb to qemu:
    $TRICORE_GDB_PATH/gdb -data-directory $TRICORE_GDB_PATH/data-directory ./build/c_demo.elf
  2. Tricore gdb abort when continue debug:
    Reading symbols from ./build/c_demo.elf...
    (gdb) target remote :1234
    Remote debugging using :1234
    0x80000000 in _start ()
    (gdb) run
    The "remote" target does not support "run".  Try "help target" or "continue".
    (gdb) continue
    Continuing.
    Aborted (core dumped)
volumit commented 2 years ago

confirmed, please be aware that qemu semishosting is disabled if a connection to gdb is detected. the semihosting of the gdbclient is then used. Both are nearly identical. I will upload a patch in the corresponding https://github.com/volumit/gdb-tricore. Please feedback if the fix is working, then I will close the issue.

Changqing-JING commented 2 years ago

It doesn't crash in my test after this fix. But another problem: Wrong file content is read by fread. This problems appears both with gdb connection and without gdb connection.

Reproduce steps:

  1. Update tricore gdb and rebuild

    cd gdb-tricore
    git clean -x -f -d && git submodule foreach --recursive git clean -x -f -d
    git pull
    CC=gcc-9 ./configure --host=x86_64-linux-gnu --target=tricore-elf --program-prefix=tricore-elf --disable-nls --disable-itcl --disable-tk --disable-tcl --disable-winsup --disable-gdbtk --disable-libgui --disable-rda --disable-sid --disable-sim --disable-newlib --disable-libgloss --disable-gas --disable-ld --disable-binutils --disable-gprof --disable-source-highlight --with-system-zlib --prefix=$INSTALL_PREFIX --disable-werror --with-python
    make -j $(nproc)
  2. Build following code:

    $TRICORE_GCC_PATH/tricore-elf-gcc -g -Wall -o build/test_read_file.elf $(pwd)/test_read_file.c
    
    /// @file test_read_file.c, utf-8 encoding
    #include <stdio.h>

char buffer[100];

int main() { const char path = FILE; FILE f = fopen(path, "rb");

if (f) { fseek(f, 0, SEEK_END); long length = ftell(f); fseek(f, 0, SEEK_SET);

length = length < ((int)sizeof(buffer)) ? length : sizeof(buffer);

fread(buffer, 1, length, f);

fclose(f);

printf("file content is: \n");
for (int i = 0; i < length; i++) {
  printf("%x", buffer[i]);
}
printf("\n");

} return 0; }

3. Run the test_read_file.elf in qemu without gdb:
```shell

$TRICORE_QEMU_PATH/qemu-system-tricore -display none -M tricore_tsim161 -semihosting -kernel build/test_read_file.elf
file content in byte is: 
2f000ffffffd6ffffff850ffffff806520746573745f72650645f66696c652e63a23696e636c756465203c737464696f2e685890ffffffd00000000065725b3130305d3baa696e74206d61696e2829207ba2020636f6e73742063666666666666363668203d20
  1. Run with GDB connected:
    $TRICORE_QEMU_PATH/qemu-system-tricore -display none -M tricore_tsim161 -S -s -semihosting -kernel build/test_read_file.elf

    run gdb

    $TRICORE_GDB_PATH/gdb -data-directory $TRICORE_GDB_PATH/data-directory ./build_read_file.elf
    (gdb) target remote :1234
    Remote debugging using :1234
    warning: No executable has been specified and target does not support
    determining executable automatically.  Try using the "file" command.
    0x80000000 in ?? ()
    (gdb) c
    Continuing.
    file content in byte is: 
    0000ffffffd6ffffff850ffffff800000000000000000000000000000000000005890ffffffd0000000000000000000000000000000000000000066666666666636360000
    [Inferior 1 (process 1) exited normally]

    The printed content with gdb is different with the content without gdb.

volumit commented 2 years ago

I can not act daily, do you have more items which I should correct. Please can you continue with qemu semihosting without gdb invocation and tell me if further functional errors are happen. The qemu semihosting was used inside the gcc testsuite, which I nailed down to zero fails. It could be that the gdb testsuite has here some gaps. But I have to check. I would to collect all issues from your usage and and fix them in one correction one session. I will also then check if there is a gap in the testsuite of gdb and why it was not covered there. Well prepared easy for me to reproduce. Like to work with you!

Changqing-JING commented 2 years ago

Haha, thank you very much! I also like to work with you: a technical excellent expert. The tricore toolchain is very wonderful. I didn't have find more problems.

Just one more question about C++ part: C99 API related macros, such as _GLIBCXX_USE_C99_STDLIB and _GLIBCXX_USE_C99_STDIO are not defined by default. It lead to some C99 carry over API or some related C++ API can't work. For example:

$TRICORE_GCC_PATH/tricore-elf-g++ -std=gnu++17 -o build/cpp_demo.elf cpp_demo.cpp 
cpp_demo.cpp: In function 'int main()':
cpp_demo.cpp:6:26: error: 'to_string' is not a member of 'std'; did you mean 'u32string'?
    6 |   std::string str = std::to_string(1);
      |                          ^~~~~~~~~
      |                          u32string

#include <string>

int main() {

  std::string str = std::to_string(1);
  return 0;
}

Technically it's not a big problem because this problem can be solved by define _GLIBCXX_USE_C99_STDIO manually.

#define _GLIBCXX_USE_C99_STDIO 1
#include <string>

int main() {

  std::string str = std::to_string(1);
  return 0;
}

But on user experience point of view, when user see error message "'to_string' is not a member of 'std'", it's not straight forward to know he is missing a _GLIBCXX_USE_C99_STDIO. Is this possible to define those marcos by default?

Changqing-JING commented 2 years ago

Update about fread got wrong content: Add a -mcpu=tc39xx in gcc arguments can get correct content by fread. Why this bug related to CPU type?

$TRICORE_GCC_PATH/tricore-elf-gcc -g -Wall  -mcpu=tc39xx -o build/test_read_file.elf $(pwd)/test_read_file.c
$TRICORE_QEMU_PATH/qemu-system-tricore -display none -M tricore_tsim162 -semihosting -kernel build/test_read_file.elf
file content is: 
2f2f2f204066696c6520746573745f726561645f66696c652e632c207574662d3820656e636f64696e67a23696e636c756465203c737464696f2e683eaa63686172206275666665725b3130305d3baa696e74206d61696e2829207ba2020636f6e
volumit commented 2 years ago

thanks for pointing it out, will fix it at the weekend, depending how complex it is. so 2 issues actually. Thanks again for the good preparation, everything what you have shown was reproduceable in 5min.

volumit commented 2 years ago

for _GLIBCXX_USE_C99_STDLIB, I do not know actually, surprising that the libstdc++ testsuite is not failing, but let me check as well. In theory it is not an issue to add a define, but then I will move away from the gcc9.4.0 fork and touching the base, so please let me check.

volumit commented 2 years ago

I can confirm, and opened several tickets for the findings. With slightly modified also vio_read has impacts, which I have to analyze. /home/dummy/qemu_tricore_6250/bin/qemu-system-tricore -display none -M tricore_tsim162 -semihosting -d in_asm,nochain -D ./qemutrace.txt -kernel ./test_read_file.elf vio_read toread 400 read 286 file content is: 2f2f2f204066696c6520746573745f726561645f66696c652e632c207574662d3820656e636f64696e67da23696e636c756465203c737464696f2e683eda23696e636c756465203c737464696e742e683eda63686172206275666665725b313030 gcc test_read_file.c ./a.out file content is: 2f2f2f204066696c6520746573745f726561645f66696c652e632c207574662d3820656e636f64696e67da23696e636c756465203c737464696f2e683eda23696e636c756465203c737464696e742e683eda63686172206275666665725b313030

Actually it looks like that I have to touch gcc, gdb and qemu. Binutils and Newlib are seeming to be unaffected. All the things are taking time, and I will do my best. Please make an high urgent issue, if you are getting blocked by the mal-functions.

Changqing-JING commented 2 years ago

Thank you very much for your help! Since we already have a workaround by using tc39xx, it's not very urgent.

Changqing-JING commented 2 years ago

By the way, another question, --semihosting-cmdline option is not supported now. Is this possible to pass arguments to main function? If yes, how to do this? If no, is this possible to support --semihosting-cmdline?

volumit commented 2 years ago

see here. https://github.com/volumit/tricore_gcc940_linux_bins/issues/10#issue-1287685091 Please comment in https://github.com/volumit/tricore_gcc940_linux_bins/issues/10#issue-1287685091