dlaczego SIGSEGV przed uruchomieniem main()

dlaczego SIGSEGV przed uruchomieniem main()
Marius.Maximus
  • Rejestracja:ponad 14 lat
  • Ostatnio:około 13 godzin
  • Postów:2096
0

Czy mogę prosić o wyjaśnienie dlaczego pojawia sie SIGSEGV na platformie Linux ?
Wyjątek jest zanim uruchomi się main, minimalny kawałek kodu który powoduje wyjątek

Kopiuj
#include <cstdio>

#include <ftd2xx.h>

// /** @{
//  * @name FT_STATUS
//  * @details Return status values for API calls.
//  */
// typedef ULONG	FT_STATUS;

FT_STATUS stat;

int main()
{
    printf("main\n");
    FT_HANDLE m_dev_handle;
    FT_Close(m_dev_handle);
}

Warunki konieczne aby pojawił się wyjątek:

  1. -lftd2xx , nie ma znaczenia czy biblioteka jest statyczna czy dynamiczna
  2. #include <ftd2xx.h>
  3. użycie w kodzie dowolnej funkcji z biblioteki ftd2xx FT_***
  4. zadeklarowanie globalnej zmiennej typu FT_STATUS

Dlaczego zadeklarowana globalna zmienna która nawet nie jest używana powoduje wyjątek szczególnie że jest to typ prosty ULONG ?

screenshot-20240522084922.png

Zastanawia mnie co się zmienia pomiędzy wersjami w kontekście biblioteki że jedna wersja nie działa:

Kopiuj
// ta wersja nie dziala
FT_STATUS stat;
int main()
{

a taka wersja działa

Kopiuj
int main()
{
  FT_STATUS stat;

--
Nie przyjmuję reklamacji za moje rady, używasz na własną odpowiedzialność.
Programowanie bez formatowania to jak chodzenie ze spodniami spuszczonymi na kostki. Owszem da się ale po pierwsze nie wygodne, po drugie nieprzyzwoicie wygląda.
Przed zaczęciem nowego wątku przeczytam problem XY
GO
  • Rejestracja:około rok
  • Ostatnio:5 miesięcy
  • Postów:358
5

Hmm na call stacku masz funkcje o nazwie stat i zadeklarowałeś globalną zmienną stat.
W C++ jest mangling nazw w C nie ma, więc teoretycznie symbole powinny być takie same dla zmiennej i funkcji.

Mógłbyś wejść do tej funkcji stat, bo kodów źródłowych nie ma i zobaczy co ona tam robi, czy strace jakie systemowe wywołanie robi, z jakim adresem.
Co jest pod tym adresem, jakaś analiza tego.

edytowany 2x, ostatnio: .GodOfCode.
Marius.Maximus
producent udostępnia tylko .so i .a
BG
  • Rejestracja:prawie 6 lat
  • Ostatnio:dzień
  • Postów:289
1

Co podaje ldd ?
Biblioteka z pakietu, sam kompilowałeś czy ściągnąłeś z sieci binarke?

Marius.Maximus
binarka ze strony producenta
BG
W tym przypadku problemem była ta zmienna, ale gdyby binarka od producenta była zlinkowana z czymś czego nie masz, to objawy mogłyby być podobne. ldd by Ci o tym najprawdopodobniej powiedziało
elwis
  • Rejestracja:ponad 18 lat
  • Ostatnio:5 dni
1

To co pisze @GodOfCode zdaje się mieć sens. Jeśli nie chcesz deklarować zmiennej stat w mainie to zrób ją jako static, powinno pomóc. Inna nazwa zmiennej też.


edytowany 1x, ostatnio: elwis
Marius.Maximus
  • Rejestracja:ponad 14 lat
  • Ostatnio:około 13 godzin
  • Postów:2096
0

Przyczyna sie wyjasniła !
To co napisał @.GodOfCode. jest przyczyną, typ zmiennej nie ma znaczenia tylko nazwa stat powoduje zamieszanie czyli nawet taka wersja int stat; tez powoduje wyjątek.
Sprawdziłem co importuje biblioteka libftd2xx.a i na liscie jest funkcja stat. https://www.man7.org/linux/man-pages/man2/stat.2.html

Wszystko jasne.

mea culpa, mea culpa,
mea máxima culpa.


--
Nie przyjmuję reklamacji za moje rady, używasz na własną odpowiedzialność.
Programowanie bez formatowania to jak chodzenie ze spodniami spuszczonymi na kostki. Owszem da się ale po pierwsze nie wygodne, po drugie nieprzyzwoicie wygląda.
Przed zaczęciem nowego wątku przeczytam problem XY
edytowany 2x, ostatnio: Marius.Maximus
MarekR22
Moderator C/C++
  • Rejestracja:około 17 lat
  • Ostatnio:4 minuty
7

czemu piszesz "mea culpa, mea culpa,"?
To jest jeden z większych WTF linker-a. Linker powinien podnieść tu alarm, a tego nie robi.
Zauważenie tego problemu jest dość trudne.
To jest powód dla którego dodano namespace do C++.


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 2x, ostatnio: MarekR22
DN
Czy jest szansa, że mógłby 'nakarmić' jakąś flagą kompilator żeby to wykrył? Bo w sumie to wydaje się dość proste do wywalania się co chwilę przy zew. bibliotekach.
Marius.Maximus
  • Rejestracja:ponad 14 lat
  • Ostatnio:około 13 godzin
  • Postów:2096
0

@MarekR22 ja uznałem ze po części przyczyniłem się do błędu, bo zadeklarowałem globalna zmienną i pech chciał że nazwa to akurat funkcja która gdzieś istnieje też w globalnej przestrzeni.
Kompilator nie był w stanie tego wyłapać, bo wyłapie tylko funkcje które są w plikach .h
Ale zgodzę się z tym że linker powinien chociaż warningiem mnie uraczyć.

Czy twórcy gcc wiedzą o tym problemie ?
Czy to nie ma sensu zgłaszać bo i tak nikt z tym nic nie robi bo jest to cześć standardu c++ :D


--
Nie przyjmuję reklamacji za moje rady, używasz na własną odpowiedzialność.
Programowanie bez formatowania to jak chodzenie ze spodniami spuszczonymi na kostki. Owszem da się ale po pierwsze nie wygodne, po drugie nieprzyzwoicie wygląda.
Przed zaczęciem nowego wątku przeczytam problem XY
MarekR22
Moderator C/C++
  • Rejestracja:około 17 lat
  • Ostatnio:4 minuty
1
Marius.Maximus napisał(a):

Czy twórcy gcc wiedzą o tym problemie ?

Tak to jest znany problem, dla którego nie ma prostego rozwiązania.
Na SO widziałem analogiczny problem z inną funkcją o jeszcze bardziej dziwnej nazwie (nie pamiętam teraz co to było).


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
Marius.Maximus
  • Rejestracja:ponad 14 lat
  • Ostatnio:około 13 godzin
  • Postów:2096
0

To była lekcja programowania pod tytułem: "Niebezpieczeństwa używanie zmiennych globalnych" 😀

Wnioski:

  1. Najlepiej nie używać globalnych zmiennych
  2. w ostateczności nazwa misi być "fikuśna" aby zmniejszyć prawdopodobieństwo kolizji

--
Nie przyjmuję reklamacji za moje rady, używasz na własną odpowiedzialność.
Programowanie bez formatowania to jak chodzenie ze spodniami spuszczonymi na kostki. Owszem da się ale po pierwsze nie wygodne, po drugie nieprzyzwoicie wygląda.
Przed zaczęciem nowego wątku przeczytam problem XY
BG
  • Rejestracja:prawie 6 lat
  • Ostatnio:dzień
  • Postów:289
1
MarekR22 napisał(a):
Marius.Maximus napisał(a):

Czy twórcy gcc wiedzą o tym problemie ?

Tak to jest znany problem, dla którego nie ma prostego rozwiązania.
Na SO widziałem analogiczny problem z inną funkcją o jeszcze bardziej dziwnej nazwie (nie pamiętam teraz co to było).

Pewnie coś z tego:

Kopiuj
$ man y0

Y0(3)                      Linux Programmer's Manual                     Y0(3)

NAME
       y0, y0f, y0l, y1, y1f, y1l, yn, ynf, ynl - Bessel functions of the second kind
Satanistyczny Awatar
  • Rejestracja:ponad 6 lat
  • Ostatnio:10 dni
  • Postów:704
1

Nie zapomnij nawrzucać producentowi na adres supportu klienta.

GO
Mówiłeś, że jesteś low level programistą embedded, stat to syscall linuxowy, ale jednocześnie jest taka funkcja w c która wywołuje syscall stat, przypadkiem nadpisał ją, biblioteka była napisana w C to nie miała manglingu ani namespaces zbudowanego na tym, więc zmienna otrzymała taki sam symbol i jednocześnie go nadpisała, a linkier nie zgłosił błędu, że jest kolizja symboli. Wina linkiera, że pozwala overritten każdy symbol bez powiadomienia, że został nadpisany. No chyba, że w warningu było napisane, że jest override symbol, ale nie dodał -Wpedantic -Wextra -Wall.
Satanistyczny Awatar
Mówieś, że pijesz wodę. Wielbłądy też piją wodę, chyba że akurat nie ma jej w pobliżu to korzystają z zasobów zakumulowanych w organiźmie.
MasterBLB
  • Rejestracja:około 19 lat
  • Ostatnio:16 dni
  • Lokalizacja:Warszawa
  • Postów:1454
0
Marius.Maximus napisał(a):

To była lekcja programowania pod tytułem: "Niebezpieczeństwa używanie zmiennych globalnych" 😀

Wnioski:

  1. Najlepiej nie używać globalnych zmiennych
  2. w ostateczności nazwa misi być "fikuśna" aby zmniejszyć prawdopodobieństwo kolizji

Bracie @Marius.Maximus generalnie wnioski słuszne, przy czym 1 to powinien być "jeśli już używać zmiennych globalnych, to z głową".
Ja postępuję w taki sposób, np. dla QStringów definiujących jakieś identyfikatory:

Kopiuj
//mam sobie plik który zowię definitions.h, a w nim
namespace Global
{
  namespace Constants
  {
    namespace Math
    {
      const double pi = 3.14;
    }
    namespace Physics
    {
      const double accelerationEarth = 9.81;
    }
  }

  namespace Database
  {
     const QString databaseName = "some name";
  }
}

//i potem używanie tego jest bardzo proste, intuicyjne i samodokumentujące się dzięki podpowiedziom IDE - o ile się te namespace'y dobrze ponazywa
#include "definitions.h"

double circleArea = Global::Constants::Math::pi * radius * radius;

Poza tym, robię je tylko jako read-only, unikam jak ognia jakiegokolwiek zapisywania do nich poza inicjalizacją.


"Sugeruję wyobrazić sobie Słońce widziane z orbity Merkurego, a następnie dupę tej wielkości. W takiej właśnie dupie specjalista ma teksty o wspaniałej atmosferze, pracy pełnej wyzwań i tworzeniu innowacyjnych rozwiązań. Pracuje się po to, żeby zarabiać, a z resztą specjalista sobie poradzi we własnym zakresie, nawet jeśli firma mieści się w okopie na granicy obu Korei."
-somekind,
konkretny człowiek-konkretny przekaz :]

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.