C/C++

AddressSanitizer:DEADLYSIGNAL végtelen loop

Fórumok

Hátha érdekel valakit, elkerülendő a szívás ....

Ubuntu 22.04.1, gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0. Az Ubuntu egy i5 Macbookon fut Parallels virtualizáció.

curl 7.81.0 (x86_64-pc-linux-gnu) libcurl/7.81.0 OpenSSL/3.0.2 zlib/1.2.11 brotli/1.0.9 zstd/1.4.8 libidn2/2.3.2 libpsl/0.21.0 (+libidn2/2.3.2) libssh/0.9.6/openssl/zlib nghttp2/1.43.0 librtmp/2.3 OpenLDAP/2.5.17
Release-Date: 2022-01-05

Van két rövid C program(ocska), semmi extra, parancssoros fordítás: gcc -Wall -Werror -pedantic -Wextra -fsanitize=address ... -lcurl -lm, weboldal lekérés és feldolgozás. Fordítás során semmit nem ír ki, nincs hiba, nincs megjegyzés.

A két fájl a fő funkciók tekintetében ugyanaz.

Elindítod az egyik fájlt, minden OK, teszi amit tenni kell, lefut, kilép hiba nélkül.

Elindítod a másodikat, kiírja a konzolra: AddressSanitizer:DEADLYSIGNAL végtelen loop-ban, abba sem akarja hagyni.

 

Megoldás:

sudo sysctl -w vm.mmap_rnd_bits=28

Innen szedtem a megoldást, miután feladtam a kód milliomodik átnézését:

https://stackoverflow.com/questions/77672217/gcc-fsanitize-address-resu…

Egészségetekre!

#define trükk

Fórumok

Sziasztok!

Letre kene hoznom par ilyesmi szimbolumot C preprocessz soran:

#define XYZ_WHAT  XYZ_42WHAT
#define XYZ_EVER  XYZ_42EVER
#define XYZ_LOLZ  XYZ_42LOLZ

Ahol a "42" az egy elore adott konstans, amit 1x szeretnek csak definialni az elejen. Ilyesmivel probalkoztam hogy:

#define __xyz_def(a,b)   XYZ_##a##b
#define XYZ_WHAT __xyz_def(42,WHAT)
#define XYZ_EVER __xyz_def(42,EVER)
/* ... */

Ez itten fentebb mar ugye egy fokkal - jobb de a preprocessz alatt nem tudom beleirni azt hogy:

#define NUM  42
#define __xyz_def(a,b)   XYZ_##a##b
#define XYZ_WHAT __xyz_def(NUM,WHAT)
/* ... */

Mi is volt erre a trukk? :) Vagy legalabbis ugy remlik hogy volt erre valami, de sehol sem lelem... 

Thx, A.

gcc: __attribute__ (( ... )) minden fuggvenyre?

Fórumok

Sziasztok!

Lehet hogy tul trivialis a kerdes, de azt hogyan tudom elerni mondjuk leginkabb `gcc` forditasi parameterekkel hogy egy adott *.c => *.o forditas soran minden fuggveny egy bizonyos __attribute_--t (azon belul is most konkretan __attribute__ (( section (".whatever") ))-t) kapjon? Csak a fuggvenyek, szoval a .text(.*) vagy a (.*).text-be meno szimbolumok... Most csak a section-ok szempontjabol erdekes de lehet hogy kesobb mas kapcsan is erdekes lehet.

thx, A.

ld + _start + .text + ordering

Fórumok

Sziasztok!

Szinten RISC-V (32bites, beagyazott) tema: probalok egy sima mezei programot leforditani az xpack-riscv-none-elf toolchain segitsegevel. A forditas kapcsan alapjaraton minden jonak tunik, kiveve az hogy a linkeles utan ezt kapom:

$ nm main.elf  | sort | grep " T "
20000000 T exit
20000026 T main
20000092 T _start
20000116 T main_task
[...]

Ami ugye erosen nem jo, es ezzel egyetertesben a `readelf --file-header main.elf` is ezt mondja:

ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF32
  Data:                              2's complement, little endian
[...]
  Entry point address:               0x20000092
[...]

Merthat a processzor (vagyis annak a bootromja) az olyan hogy 0x20000000-rol szeret(ne) indulni. Ami megfurcsabbba teszi a dolgot, hogy a main() es a main_task() ugyanabbol a forras-modulbol jon, szoval meg egy *.o-bol jovo fuggvenyek koze is teszi be a linker a _start szimbolumnak megfelelo valamit. Ezutobbi papiron lehetne a forditas + linkeles soran kiadott `-ffunction-sections` + `-Wl,--gc-sections` eredmenye is (akar), de ha ezutobbiakat kikapcsolom akkoris ugyanez a helyzet :/ Akkor is ide (egyebkent pont a 0x...92-es cimre) kerul a _start. 

Ez az xPack az a newlib-et hasznalja. Eddig csak picolibc-t hasznaltam RISC-V-s projektekre, szoval lehet hogy ez a newlib kinja ugy altalaban (es pl ARMv6-M vagy ARMv7-M eseten is "ilyen"). 

Mit lehetne itten tenni? Hogyan tudnam eroltetni az linkert (pl a megfelelo -Wl,... kapcsoloval) hogy marpedig a _start az legyen a 0x20000000 cimen es/vagy a .text legelejen? Fuggetlenul attol hogy a .text melyik subsection-jeben mi van? (( Mondjuk ettol fuggetlenul ha atirom a bootrom-ban hogy a 0x20000092-es cimrol induljon a program, akkor sem indul - meg - el, szoval vsz lesz itt mas turpissag is, de ez mas kerdes... ))

Maga a szerkesztes egyebkent olyan hogy a text is a RAM-ba (a 0x20000000-s cimre) van eroltetve, szoval a beagyazott rendszer jelleg ellenere ez most egy teljesen "von Neumann" linkeles: azaz mind a text, mind a data meg a bss (meg a heap) az a 0x20000000 cimtartomanyban van (alul a text, felul a tobbi). Es ez a "von Neumann" linkeles szepen mukodik picolibc eseten, szoval ezzel nem kene hogy gond legyen. Csak a newlib-nek nem tetszik.

thx, A.

[megoldva] beágyazott matek

Fórumok

RISC-V alá próbálom itten beizzítani a klasszikus matek könyvtárakat, egyelőre inkább kevesebb mint több sikerrel. Konkértan az van hogy sima integer architektúra alatt használnám (pl) az sqrtf() függvényt. Ha csak úgy simán linkelem, akkor nem találja:

main.c:(.text+0x116): undefined reference to `sqrtf'

Ha kézzel hozzáadom a megfelelő libm.a file-t a teljes path-tal (/usr/lib/picolibc/riscv64-unknown-elf/lib/rv32imac/ilp32/libm.a, itt konkrétan), akkor sem találja. Ha ebből a libm.a-ból kiveszem a megfelelo *.o-t (ef_sqrt.c.o, ebben van a T: sqrtf szimbolum), azt adom hozzá linkelés során akkor minden fasza. Szoval azért nem rossz a helyzet, de ez így minden csak nem elegáns, pláne nem hordozható.

A megfelelő specs file-ban (picolibc.specs: /usr/lib/picolibc/riscv64-unknown-elf/picolibc.specs) van egy ilyen sor:

--start-group %(libgcc)  -lc %{-oslib=*:--undefined=_exit} %{-oslib=*:-l%*} --end-group

Ezen felbuzdulva a linerknek átadtam a -Wl,-oslib=m opciót, mondván hogy a {-oslib=*:-l%*} direktíva a -lc-hez meg az -lgcc (libgcc)-hez hasonlóan akkor hozzáadja a -lm-et is. De sajnos ez sem elég, ugyanúgy undefined reference to `sqrtf' lesz a vége, pedig ez mig egy vállalhatóan kultúrált/hordozható opció lehetne:

riscv64-unknown-elf-gcc \
        -march=rv32imac -mabi=ilp32 \
        -Wl,-oslib=m -specs=/usr/lib/picolibc/riscv64-unknown-elf/picolibc.specs \
        -Wl,--defsym=__ram=0x20000000 -Wl,--defsym=__ram_size=0x10000 -Wl,--defsym=__stack_size=0 \
        -T./picolibc_ram.ld \
        -o main.elf main.o vector.o rtos/libfreertos.a

Ugyan a newlib-et nem próbáltam ki, de azt látom hogy akár ARM-nél is teljesen hasonlóan megy a minden. Szoval (feltételezem) hogy ARM-nál (arm-none-eabi-gcc) is ezt és/vagy ilyesmit kéne csinálni (ha pl. Cortex-M0 alatt akarnánk floating point math library-t használni).

Bármi ötlet? Thx, A.
 

gcc bug vagy en vagyok a hulye (szokas szerint)?

Fórumok

Van egy kb 25 eve irt kodreszlet, ami akkoriban (2.9x gcc-vel) mukodott jol, most pedig gcc 11.x-el mar nem mindig (nehez reprodukalni, nem mindig szar csak ritkan). Ha belerakok egy printf-et akkor viszont jol mukodik, ezert gondolom h valami optimalizalasi bug lehet. Probaltam volatile-t is irni a deklaraciohoz, bar elvileg nem kene, de az sem segitett rajta. Ha a hibakezelest (if..return 0) is kivettem, akkor se lett jobb.

Mi a hiba? :)

 

INLINE static int afs_fread_dword(dword *ptr,int s1,int s2,afs_FILE *f){
  int s=s1*s2/4;
  while(s>0){
    volatile dword c;
    if(afs_fread(&c,sizeof(c),1,f)!=1) return 0;
    printf("   s=%d c=0x%08X ptr=%p\n",s,c,ptr);
#ifdef REVERSE_BYTEORDER
    c= ((c>>24)&0xFF) | (((c>>16)&0xFF)<<8) | (((c>>8)&0xFF)<<16) | ((c&0xFF)<<24);
#endif
    *ptr=c; ++ptr;
    --s;
  }
  return s2;
}

 

kiirattam a parameteretekt, az s2 mindig 1, az s1 pedig 4/8/12/16/32 tehat nem lehet az a baja, hogy nem oszthato 4-el (dword merete)

ha az egesz fuggveny belsejet kicserelem erre az 1 sorra, akkor is jol mukodik:   return afs_fread(ptr,s1,s2,f);

Segítségkérés: C++ játékprogram fordítása Win11-en

Fórumok

A BrogueCE nevű remek, open source játékkal szeretnék kísérletezni.

A mellékelt instrukciók alapján (BUILD.md) Windows 11-es változatot szeretnék készíteni, és ehhez telepítettem is az ajánlott MSYS2-t, majd annak instrukciói szerint a gcc-t (v13.2.0).

A játék leírásában az szerepel, hogy ekkor a

pacman -S make mingw-w64-x86_64-{gcc,SDL2,SDL2_image}

paranccsal tudom a szükséges dependenciákat telepíteni (abban a könyvtárban, ahol a BUILD.md található), ami látszólag végig is megy, csakhogy az alábbi hibát kapom, amikor a játékot buildelném:

$ make bin/brogue.exe
make: sdl2-config: No such file or directory
make: sdl2-config: No such file or directory
make: *** No rule to make target 'bin/brogue.exe'. Stop.

Itt elakadtam, mert nem értek a C++-hoz, és mielőtt hiányos/elavult dokumentáció miatt GitHub issue-t készítenék, ki szeretném deríteni, hátha csak PEBKAC történt.

[Megoldva] Bármilyen típusú pointer átadása ne mondjon warningot

Fórumok

Írtam egy ilyet:

void nfree(void **p) {

    if (p) {
        free(*p);
        *p = NULL;
    }
    return;
}

Nem akarok típust cast-olni minden híváskor, és nem akarok emiatt warningot látni. Valahogy a realloc(), free() megoldja, hogy a fordító nem nyüszít, bármilyen típusú pointert is adok át. Néztem az stdlib.h-t is, de talán valamilyen attribútum lesz a megoldás, viszont nem tudom mi és miképp.

Mit kell tennem, hogy például ez ne adjon warning: passing argument 1 of ‘nfree’ from incompatible pointer type [-Wincompatible-pointer-types] figyelmeztetést? Már a cast-oláson illetve a warningok globális kikapcsolásán túl.

Megoldás

Az első hozzászólásban apal által adott megoldás nyerte el tetszésemet. Lefordult warning nélkül, ami persze érthető.

Köszönöm a segítséget!
 

2 GB-nál nagyobb fájlok kezelése

Fórumok

Írtam egy programot, ami annyit csinál, hogy egy fájlba ír uint64_t számokat. (pontosabban prímszámokat, egy jó nagy fájlt csinálnék, amiben prímszámok vannak). kb. 2 hét alatt eljutott odáig, hogy a fájl mérete 2GByte lett, és nem íródik bele semmi. Érdekes, mert úgy viselkedik, mintha írna a fájlba, semmi leállás, csak a fájl nem növekszik, megállt 2147483647-nél. (minden 100000. prímnél kiírja a számot, és azt hogy hányadik).
Azt hittem, hogy ez a 2GB mérethatár már a régmult problémája. Ubuntu 18.04 32bit, ext3 fájlrendszer, gcc-7.5.0 a rendszer. Nem hiszem, hogy a rendszer korlátozná a 2GB-nál nagyobb fájlokat, hiszen ennél jóval nagyobb fájlok is vannak használva másegyéb programokkal.
A gcc/glibc cuccnak lenne ilyen határa, vagy esetleg valami fordítási direktíva kéne még?