2017-06-03 2 views
1

Ich habe libcurl für einen C++ - Daemon eingepackt, den ich auf Google Container Engine bereitgestellt habe. Alles funktioniert prächtig bis auf ein kleines Problem. Es segfaults immer wenn ich curl_slist_free_all() rufe. Es passiert nicht auf den Ubuntu 14s oder 16s noch macOS. Es kommt nur in der GKE Docker-Umgebung mit Debian 8.7 vor. Das ist buchstäblich mein einziger Fehler und es hat mich wochenlang belästigt.curl_slist_free_all() verursacht segfault auf GKE mit Debian 8.7

Ich habe Ressourcen-Handles mit RAII-Stil-Container für Ausnahmesicherheit (ja, ja ... ich benutze Ausnahmen) und Leckschutz gewickelt. Die easy_init und easy_cleanup sind in den CurlSession Konstruktoren und Destruktoren. Die global_init & Bereinigung sind in den HTTP-Konstruktoren und Destruktoren.

Ich habe bestätigt, dass es keine doppelt freien Situationen gibt, spule den libcurl-Code und kann immer noch nicht ergründen, warum dies nur auf diesem Betriebssystem env geschieht. Ich habe es geschafft, einen Debugger anzuhängen und isoliert den einzelnen Slist Cleanup Aufruf.

Der einzige Weg, wie ich meinen Code zum Arbeiten bekommen kann, ist in alle anderen env, was kein Deal Breaker ist, würde ich nur eher mein Speicher Profiler gab mir eine saubere Rechnung der Gesundheit.

Jede Einsicht oder gemeinsamer Schmerz geschätzt.

Mein Kopf slist Wrapper:

HTTP::Headers::Headers() : slist{nullptr} {} 

HTTP::Headers::Headers(const HeaderKeyValues &headers) 
    : slist{nullptr} 
{ 
    for (const auto& header : headers) add(header.first, header.second); 
} 

HTTP::Headers::~Headers() { 
    curl_slist_free_all(slist); // <- seems to crash on Google's Debian image 
    slist = nullptr; 
}; 

void HTTP::Headers::add(const std::string& key, const std::string& value) 
{ 
    std::ostringstream os; 
    os << key << ": " << value; 

    slist = curl_slist_append(slist, os.str().c_str()); 
    if (!slist) { 
     LOG(fatal) << "Failed appending to header list"; 
     throw std::runtime_error{"Failed appending to header list"}; 
    } 
} 

Subset des Versenders:

HTTP::Response HTTP::dispatch(const Request& req) const { 
    CurlSession session; 
    const auto handle = session.handle; 

    Headers headerList{req.headers}; 
    if (req.chunked) 
     headerList.add("Transfer-Encoding", "chunked"); 

    // more ... // 

    if (headerList.notEmpty()) 
     curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headerList.slist); 

    // perform the actual request 
    CURLcode result = curl_easy_perform(handle); 
+2

Ich vermute, dass etwas anderes den Speicher durcheinander bringt, so dass diese Funktion zum Absturz bringt. 'curl_slist_free_all()' ist einfach, funktioniert für ein Universum von Benutzern bereits und wurde in vielen Jahren nicht geändert ... –

+0

Ja, dieser Teil ist definitiv gut geschrieben. Ich glaube nicht, dass es ein Teil von libcurl ist. Scheiße ist solide, warum ich es benutze. Ich spiele eine Woche oder zwei in meinem Cluster und poste meine Ergebnisse zurück. OMG, danke für deine Antwort! Der Name wurde nicht verbunden. :) – pestilence669

Antwort

0

Ich vermute, das eine Art subtiler Inkompatibilität zwischen dem Docker Bild aufzubauen war und die Docker bereitstellen Bild, das sich nur beim Laufen auf GKE manifestiert.