Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Le soluzioni FSP per il 2026: potenza e IA al centro
Le soluzioni FSP per il 2026: potenza e IA al centro
In occasione del Tech Tour 2025 della European Hardware Association abbiamo incontrato a Taiwan FSP, azienda impegnata nella produzione di alimentatori, chassis e soluzioni di raffreddamento tanto per clienti OEM come a proprio marchio. Potenze sempre più elevate negli alimentatori per far fronte alle necessità delle elaborazioni di intelligenza artificiale.
AWS annuncia European Sovereign Cloud, il cloud sovrano per convincere l'Europa
AWS annuncia European Sovereign Cloud, il cloud sovrano per convincere l'Europa
AWS è il principale operatore di servizi cloud al mondo e da tempo parla delle misure che mette in atto per garantire una maggiore sovranità alle organizzazioni europee. L'azienda ha ora lanciato AWS European Sovereign Cloud, una soluzione specificamente progettata per essere separata e distinta dal cloud "normale" e offrire maggiori tutele e garanzie di sovranità
Redmi Note 15 Pro+ 5G: autonomia monstre e display luminoso, ma il prezzo è alto
Redmi Note 15 Pro+ 5G: autonomia monstre e display luminoso, ma il prezzo è alto
Xiaomi ha portato sul mercato internazionale la nuova serie Redmi Note, che rappresenta spesso una delle migliori scelte per chi non vuole spendere molto. Il modello 15 Pro+ punta tutto su una batteria capiente e su un ampio display luminoso, sacrificando qualcosa in termini di potenza bruta e velocità di ricarica
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 04-02-2008, 18:16   #1
tomminno
Senior Member
 
Iscritto dal: Oct 2005
Messaggi: 3306
[C++] Linux catch di stack overflow

Come realizzo su Linux qualcosa di equivalente a:

Codice:
void Loop()
{
	static int count = 0;
	cout << count++ << endl;
	Loop();
}

int main(int argc, CHAR* argv[])
{
	__try
	{
		Loop();
	}
	__except(EXCEPTION_EXECUTE_HANDLER)
	{
		cout << "exception caught" << endl;
	}
	return 0;
}
Ho provato in tutti i modi ma con i signal non riesco a catturare uno stack overflow.
tomminno è offline   Rispondi citando il messaggio o parte di esso
Old 04-02-2008, 20:06   #2
71104
Bannato
 
L'Avatar di 71104
 
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7029
non arriva il segnale di segmentation fault in questi casi?
71104 è offline   Rispondi citando il messaggio o parte di esso
Old 05-02-2008, 00:12   #3
ilsensine
Senior Member
 
L'Avatar di ilsensine
 
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
Dubito che un catch su uno stach overflow sia in ogni caso sicuro. Considera questo esempio, e immagina di eseguirlo quando hai solo una manciata di byte di stack disponibili:
Codice:
__try {
  A a; // A e' una classe
  char buf[128]; // stack overflow qui
  ...
} __except (ecc ecc)
Quando accade lo stack overflow, cosa fai? Il distruttore di A viene chiamato?
E se il distruttore è qualcosa tipo
Codice:
A::~A()
{
  char buf[2048]; // stack overflow n.2 versione extralarge
  ...
}
come lo gestisci?

Se rinunci alla mancata chiamata dei distruttori, puoi provare questa tecnica.
Ho aggiunto qualche velato tentativo di supporto multithread e nested, il tutto rigorosamente non testato:
Codice:
static __thread stack_t thread_sigstack;
static __thread stack_t old_thread_sigstack;
void sig_try_init()
{
  thread_sigstack.ss_size = SIGSTKSZ;
  thread_sigstack.ss_flags = 0;
  thread_sigstack.ss_sp = malloc(thread_sigstack.ss_size);
  thread_sigstack.ss_sp = (char *) thread_sigstack.ss_sp + thread_sigstack.ss_size;
  sigaltstack(&thread_sigstack, &old_thread_sigstack);

  struct sigaction sa;
  sigemptyset(&sa.sa_mask);
  sa.sa_flags = SA_ONSTACK;
  sa.sa_sigaction = sighandler;
  sigaction(SIGSEGV, &sa, NULL);
}

void sig_try_exit()
{
  sigaltstack(&old_thread_sigstack, NULL);
  free((char *) thread_sigstack.ss_sp - thread_sigstack.ss_size);
}

void overflow(char *v)
{
  if (v)
    memset(v, 0, 1024);
  char a[1024];
  overflow(a);
}

int main()
{
  sig_try_init();

  __try {
    fprintf(stderr, "Start...\n");
    overflow(NULL);
    fprintf(stderr, "Stop\n");
  } __catch() {
    fprintf(stderr, "Exception caught\n");
  }

  sig_try_exit();
  return 0;
}
Mancano alcuni pezzi, che ti segno qui a parte:
Codice:
__thread sigjmp_buf *env = NULL;
void sighandler(int sig, siginfo_t *si, void *unused)
{
  if (env!=NULL)
    siglongjmp(*env, 1);
  else
    abort();
}

__thread bool __in_catch = false;
#define __try \
{ \
  bool in_catch = false; \
  sigjmp_buf ebuf; \
  sigjmp_buf *old_ebuf = env; \
  env = &ebuf; \
  if (sigsetjmp(*env, 1)==0)

#define __catch() \
  else \
    in_catch = true; \
  env = old_ebuf; \
  __in_catch = in_catch; \
} \
  if (__in_catch)
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al
andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12
ilsensine è offline   Rispondi citando il messaggio o parte di esso
Old 05-02-2008, 00:15   #4
ilsensine
Senior Member
 
L'Avatar di ilsensine
 
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
Il programma di test, compilabile, è questo.
Becca anche i segfault, ovviamente.
Codice:
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <setjmp.h>
#include <string.h>

__thread sigjmp_buf *env = NULL;
static void sighandler(int sig, siginfo_t *si, void *unused)
{
  if (env!=NULL)
    siglongjmp(*env, 1);
  else
    abort();
}

static __thread stack_t thread_sigstack;
static __thread stack_t old_thread_sigstack;
void sig_try_init()
{
  thread_sigstack.ss_size = SIGSTKSZ;
  thread_sigstack.ss_flags = 0;
  thread_sigstack.ss_sp = malloc(thread_sigstack.ss_size);
  thread_sigstack.ss_sp = (char *) thread_sigstack.ss_sp + thread_sigstack.ss_size;
  sigaltstack(&thread_sigstack, &old_thread_sigstack);

  struct sigaction sa;
  sigemptyset(&sa.sa_mask);
  sa.sa_flags = SA_ONSTACK;
  sa.sa_sigaction = sighandler;
  sigaction(SIGSEGV, &sa, NULL);
}

void sig_try_exit()
{
  sigaltstack(&old_thread_sigstack, NULL);
  free((char *) thread_sigstack.ss_sp - thread_sigstack.ss_size);
}

__thread bool __in_catch = false;
#define __try \
{ \
  bool in_catch = false; \
  sigjmp_buf ebuf; \
  sigjmp_buf *old_ebuf = env; \
  env = &ebuf; \
  if (sigsetjmp(*env, 1)==0)

#define __catch() \
  else \
    in_catch = true; \
  env = old_ebuf; \
  __in_catch = in_catch; \
} \
  if (__in_catch)

void overflow(char *v)
{
  if (v)
    memset(v, 0, 1024);
  char a[1024];
  overflow(a);
}

int main()
{
  sig_try_init();

  __try {
    fprintf(stderr, "Start...\n");
    overflow(NULL);
    fprintf(stderr, "Stop\n");
  } __catch() {
    fprintf(stderr, "Exception caught\n");
  }

  sig_try_exit();
  return 0;
}
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al
andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12

Ultima modifica di ilsensine : 05-02-2008 alle 00:22.
ilsensine è offline   Rispondi citando il messaggio o parte di esso
Old 05-02-2008, 07:26   #5
cdimauro
Senior Member
 
L'Avatar di cdimauro
 
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
Quote:
Originariamente inviato da ilsensine Guarda i messaggi
Dubito che un catch su uno stach overflow sia in ogni caso sicuro. Considera questo esempio, e immagina di eseguirlo quando hai solo una manciata di byte di stack disponibili:
Codice:
__try {
  A a; // A e' una classe
  char buf[128]; // stack overflow qui
  ...
} __except (ecc ecc)
Quando accade lo stack overflow, cosa fai? Il distruttore di A viene chiamato?
E se il distruttore è qualcosa tipo
Codice:
A::~A()
{
  char buf[2048]; // stack overflow n.2 versione extralarge
  ...
}
come lo gestisci?
Niente: becchi un mortale double fault e ti metti l'anima in pace.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro
@LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro
Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys
cdimauro è offline   Rispondi citando il messaggio o parte di esso
Old 05-02-2008, 10:04   #6
ilsensine
Senior Member
 
L'Avatar di ilsensine
 
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Niente: becchi un mortale double fault e ti metti l'anima in pace.
No non è un double fault...
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al
andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12
ilsensine è offline   Rispondi citando il messaggio o parte di esso
Old 05-02-2008, 13:54   #7
tomminno
Senior Member
 
Iscritto dal: Oct 2005
Messaggi: 3306
Quote:
Originariamente inviato da ilsensine Guarda i messaggi
Dubito che un catch su uno stach overflow sia in ogni caso sicuro. Considera questo esempio, e immagina di eseguirlo quando hai solo una manciata di byte di stack disponibili:
Codice:
__try {
  A a; // A e' una classe
  char buf[128]; // stack overflow qui
  ...
} __except (ecc ecc)
Quando accade lo stack overflow, cosa fai? Il distruttore di A viene chiamato?
E se il distruttore è qualcosa tipo
Codice:
A::~A()
{
  char buf[2048]; // stack overflow n.2 versione extralarge
  ...
}
come lo gestisci?
Intanto grazie per il codice.
Per quanto riguarda la gestione dello stack overflow, più che altro serve per debug su codice di produzione, per rilevare eventuali problemi ed avere modo di trovare la causa più facilmente.
Si suppone che errori da terminazione immediata non siano così comuni, ma sporadici (e si spera inesistenti...), per cui se il tutto serve per trovare un bug di quelli nascostissimi, l'eventuale memory leak passa in secondo piano.
Inoltre nel caso di una allocazione sullo stack in un distruttore, beh pace.

Il codice che avevo postato è per Windows e in quel modo qualunque porcata commessa nel __try (dereferenziazione di puntatori nulli, doppia delete, stack overflow...) viene catturata da __except e con qualche riga di codice in più è facile avere anche lo stack trace.
Esattamente come accade in C# o Java dove con un try catch sei sicuro che il software continua sempre e comunque a funzionare.

Volevo riuscire a fare la stessa cosa anche su Linux.
tomminno è offline   Rispondi citando il messaggio o parte di esso
Old 06-02-2008, 09:33   #8
cdimauro
Senior Member
 
L'Avatar di cdimauro
 
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
Quote:
Originariamente inviato da ilsensine Guarda i messaggi
No non è un double fault...
Sicuramente sono un po' arrugginito con l'assembly 80x86 , ma se ho uno stack fault, e nell'handler per gestirlo viene generato un altro stack fault, non dovrebbe scatenarsi un double fault?
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro
@LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro
Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys
cdimauro è offline   Rispondi citando il messaggio o parte di esso
Old 06-02-2008, 10:06   #9
ilsensine
Senior Member
 
L'Avatar di ilsensine
 
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
Quote:
Originariamente inviato da cdimauro Guarda i messaggi
Sicuramente sono un po' arrugginito con l'assembly 80x86 , ma se ho uno stack fault, e nell'handler per gestirlo viene generato un altro stack fault, non dovrebbe scatenarsi un double fault?
Secondo te un processo utente ha i privilegi per gestire un page fault?
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al
andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12
ilsensine è offline   Rispondi citando il messaggio o parte di esso
Old 06-02-2008, 10:28   #10
cdimauro
Senior Member
 
L'Avatar di cdimauro
 
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
Ma allora come si fa a "intrappolare" uno stack fault? Dovrebbe esistere un qualche metodo per "ripassare" il controllo in user-space? Giusto per capire.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro
@LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro
Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys
cdimauro è offline   Rispondi citando il messaggio o parte di esso
Old 06-02-2008, 10:43   #11
ilsensine
Senior Member
 
L'Avatar di ilsensine
 
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
Un double fault capita quando per gestire una eccezione capita una seconda eccezione. In pratica, se il gate di eccezione punta a un segmenetno non valido o accade...un segfault nel tentativo di lanciare l'handler. Su linux solo un bug del kernel può provocare un double fault in quanto l'handler è sempre presente e su memoria persistente e valida.

L'eccezione di stack viene gestita correttamente dall'handler del kernel (quindi nessun double fault), che invia un segnale al processo. A seguito del segnale, il processo riparte dall'handler predisposto; se durante l'esecuzione di questo handler si verifica nuovamente la stessa eccezione, si ha un (ancora una volta singolo) fault.
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al
andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12
ilsensine è offline   Rispondi citando il messaggio o parte di esso
Old 06-02-2008, 10:49   #12
cdimauro
Senior Member
 
L'Avatar di cdimauro
 
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
Sì, le condizioni per il double fault me le ricordavo. Non sapevo invece com'era gestito lo stack fault.

Adesso mi è tutto chiaro e concordo con te, ovviamente, visto che l'eccezione di stack fault viene (dal kernel) "reindirizzata" in user-space all'applicazione.

Grazie
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro
@LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro
Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys
cdimauro è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Le soluzioni FSP per il 2026: potenza e IA al centro Le soluzioni FSP per il 2026: potenza e IA al ce...
AWS annuncia European Sovereign Cloud, il cloud sovrano per convincere l'Europa AWS annuncia European Sovereign Cloud, il cloud ...
Redmi Note 15 Pro+ 5G: autonomia monstre e display luminoso, ma il prezzo è alto Redmi Note 15 Pro+ 5G: autonomia monstre e displ...
HONOR Magic 8 Pro: ecco il primo TOP del 2026! La recensione HONOR Magic 8 Pro: ecco il primo TOP del 2026! L...
Insta360 Link 2 Pro e 2C Pro: le webcam 4K che ti seguono, anche con gimbal integrata Insta360 Link 2 Pro e 2C Pro: le webcam 4K che t...
JMEV SC01, la supersportiva cinese da 30...
Tesla Model 3 superata per la prima volt...
AMD ha già risolto la crisi della...
La “batteria di Baghdad” funziona davver...
Pannelli solari al contrario? Non propri...
Google Gemini si espande: arrivano le es...
Mercato TV: la leadership di Samsung reg...
L'AI che lavora 100 volte più vel...
LIDAR, battaglia finale: MicroVision met...
Il 2025 è stato l'anno di BYD: +2...
L'IA enterprise entra nella fase decisiv...
Il tiktoker Khaby Lame cede la sua socie...
Apple Pencil Pro scende a 122€ su Amazon...
Ring in forte sconto su Amazon: videocit...
Blink torna a fare sul serio: Mini 2K+ c...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 20:46.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v