Cosa c'è di sbagliato nel collegamento statico di STL in più librerie condivise?

7

Ecco lo scenario:

  1. libA.so e libB.so si collegano entrambi staticamente allo stesso STL.
  2. libA.so ha un'API pubblica che restituisce uno std :: string.
  3. libB.so chiama questa funzione e riceve una copia della stringa.
  4. Quando la copia di libB.so della stringa esce dall'ambito, viene chiamato il distruttore della stringa.
  5. L'applicazione seg faults tentando di liberare la stringa copiata.

Ho letto altrove che il collegamento statico come questo è brutto, ma mi piacerebbe capire meglio perché è cattivo. Qualcuno può spiegare perché la sequenza sopra potrebbe andare in crash?

    
posta user1509041 09.11.2014 - 09:14
fonte

2 risposte

7

Pensiamo a questo molto attentamente. libA.so è collegato staticamente con l'STL. Tuttavia, l'STL non esiste in modo isolato, richiede il runtime C (CRT). Entrambi risiedono in libstdc ++, una libreria statica. Ciò significa che libA.so e libB.so hanno strutture di dati CRT separate. In particolare, l'heap utilizzato da libA.so è diverso dall'heap utilizzato da libB.so. L'allocazione di una stringa dall'heap di runtime di libA e il tentativo di liberare il runtime di libB semplicemente non funzionano perché il runtime di libB non ha record di allocazione della stringa. L'unico modo per distruggere correttamente la stringa è chiamando il distruttore all'interno di libA.so.

Si potrebbe chiedere: ma libB.so riceve una copia della stringa, giusto? Sì, è giusto, ma chi ha assegnato questa copia? È stato assegnato utilizzando il costruttore di copie nel contesto del runtime di libA.

Detto questo, puoi ancora usare la stringa da libB.so. Non puoi semplicemente distruggerlo da lì.

Puoi anche consentire alla libB di ricevere un puntatore alla stringa e quindi crearne una copia nel contesto del runtime della libB. Quella copia può essere destrutturata da libB.

Ed ecco perché il collegamento statico a volte è cattivo.

    
risposta data 09.11.2014 - 10:40
fonte
2

L'STL è il cosiddetto "full-state" (come opposto allo "stato-meno") che significa che ha alcune cose statiche all'interno. Quando si collega STL staticamente a entrambi libA.so e libB.so si ottengono due istanze della libreria STL in memoria in fase di esecuzione (con due copie di materiale statico). Ognuna di queste due copie gestisce le risorse allocate in modo indipendente e la risorsa allocata in un'istanza della libreria non può essere liberata in un'altra

    
risposta data 09.11.2014 - 09:41
fonte

Leggi altre domande sui tag