dies geschieht, wenn eine Struktur der Konstruktion, meinen Code: http://wklej.org/hash/c42680a7f9d/txt/ in dieser Zeile: http://wklej.org/hash/5fefcecc371/txt/ Backtrace: http://wklej.org/id/451070/txt/ jede Hilfe Leider apperciated ist, nicht ich den Code kopieren hier, damit ich es posten an einem anderen Ort;.. (std :: string Copykonstruktor seg Fehler
Antwort
einen Debugger verwenden und eine Stack-Trace erhalten
das Problem an Sicherheit grenzender Wahrscheinlichkeit einen schlechten C-String in den std :: string Konstruktor Vielleicht ist der Zeiger ungültig oder der C-String wird nicht beendet und der Konstruktor liest in den geschützten Speicher aus
Aber ohne weitere Informationen kann ich nicht sagen, was der Fehler ist. Der Debugger sollte sofort darauf hinweisen.
Auch Ihre Socket
enthält einen Zeiger, sondern definiert nur einen Konstruktor und Destruktor. Sie benötigen außerdem einen Kopierkonstruktor und einen Zuweisungsoperator. Wenn diese beiden Vorgänge nicht stattfinden sollen, definieren Sie sie als private
ohne Implementierung.
Auch ich sehe von Ihrem Backtrace, dass dies eine alte Version von GCC ist. Es ist möglich, dass diese Version nicht über die Korrekturen verfügt, die die Verwendung von std :: string in Multi-Thread-Programmen ermöglichen. Ich weiß nicht, wann es behoben wurde, aber einige ältere Versionen der libstdC++ - Bibliothek blockierten die Referenzzählungen für die Zeichenfolge nicht und konnten abstürzen, wenn verschiedene Threads den Zeichenfolgenspeicher freigaben und gleichzeitig darauf schreiben würden.
backtrace: http://wklej.org/id/451070/txt/ –
@Fallen: Können Sie mit -O0 -g neu erstellen, so dass wir den Wert der Zeichenfolgen in der Backtrace sehen können? Oder gehen Sie zumindest zu Bild 4 und drucken Sie die Werte jedes Funktionsarguments aus. –
@Zan Lynx: http://wklej.org/hash/73b719ed95a/ –
ich Ihren Code ein, um sich gelegt haben, um es zu bearbeiten:
#ifdef _WIN32
#define _WIN32_WINNT 0x0501
#endif
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <boost/noncopyable.hpp>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <sstream>
#include <string>
#ifdef assert
#undef assert
#endif
#define assert(x)\
if (!x) { \
std::clog << "[Error - __FUNCTION__] Asseration to: " << #x << " failed. line: " << __LINE__ << ", file: " << __FILE__ << "." << std::endl;\
std::exit(100);\
}
template<typename _Tp>
inline std::string toString(_Tp __p)
{
std::stringstream ss;
ss << __p;
std::string ret;
ss >> ret;
return ret;
}
struct Proxy;
typedef std::vector<Proxy*> ProxyVec;
struct Proxy
{
std::string name;
uint32_t port;
};
ProxyVec loadProxies(const std::string& fileName)
{
std::FILE *f = fopen(fileName.c_str(), "r");
if (!f) {
std::clog << "[Error - loadProxies] Cannot open: " << fileName << "." << std::endl;
delete f;
f = NULL;
return ProxyVec();
}
char buffer[1024];
ProxyVec ret;
int32_t __n = 0;
while (fgets(buffer, sizeof(buffer), f)) {
++__n;
std::string str(buffer);
if (str.find("\n") != std::string::npos)
str = str.substr(0, str.length()-1);
if (str.find("\r") != std::string::npos)
str = str.substr(0, str.length()-1);
size_t sep = str.rfind(":");
if (sep == std::string::npos) {
std::clog << "[Error - loadProxies] Cannot load proxy #" << __n << "." << std::endl;
continue;
}
std::string hostname = str.substr(0, sep);
uint32_t port = static_cast<uint32_t>(std::atoi(str.substr(sep+1, str.length()-sep).c_str()));
std::clog << "Loading proxy: " << hostname << ":" << port << "." << std::endl;
Proxy proxy;
proxy.name = hostname;
proxy.port = port;
ret.push_back(&proxy);
}
std::clog << "Loaded: " << __n << " proxies." << std::endl;
return ret;
}
class Socket
{
public:
Socket(boost::asio::io_service& service, const std::string& host,
const std::string& port, const std::string& targetHost, const std::string& targetPort);
~Socket();
void write(const std::string& message);
std::string receivedData() const;
bool connected() const;
void receive();
void handle();
private:
struct SocketData
{
SocketData(boost::asio::io_service& service, const std::string& _host, const std::string& _port,
const std::string& _targetHost, const std::string& _targetPort):
socket(service),
write(service),
read(service),
resolver(service),
buffers(),
host(_host),
port(_port),
targetHost(_targetHost),
targetPort(_targetPort),
connected(false)
{
}
boost::asio::ip::tcp::socket socket;
boost::asio::io_service::strand write, read;
boost::asio::ip::tcp::resolver resolver;
boost::array<char, 1024> buffers;
std::string host, port;
std::string targetHost, targetPort;
bool connected;
};
// FIXME: Use shared_ptr instead.
SocketData* d;
protected:
//handle resolve func
void handle_resolve(const boost::system::error_code&,
boost::asio::ip::tcp::resolver::iterator);
//handle connection func
void handle_connect(const boost::system::error_code&,
boost::asio::ip::tcp::resolver::iterator);
//handle write func
void handle_write(const boost::system::error_code&, size_t);
//handle read func
void handle_read(const boost::system::error_code&, size_t);
private:
void connectionThread();
};
Socket::Socket(boost::asio::io_service& service, const std::string& host, const std::string& port,
const std::string& targetHost, const std::string& targetPort)
: d(new SocketData(service, host, port, targetHost, targetPort))
{
boost::thread thread(boost::bind(&Socket::connectionThread, this));
// FIXME: This function is blocking. The constructur will never exit.
// Use thread_group.join_all() as last line in main() instead.
thread.join();
}
Socket::~Socket()
{
d->socket.close();
delete d;
d = NULL;
}
void Socket::connectionThread()
{
if (!d)
return;
if (d->connected)
return;
boost::asio::ip::tcp::resolver::query query(d->host, d->port);
d->resolver.async_resolve(query,
boost::bind(&Socket::handle_resolve, this,
boost::asio::placeholders::error,
boost::asio::placeholders::iterator));
}
void Socket::handle_resolve(const boost::system::error_code& e,
boost::asio::ip::tcp::resolver::iterator ep_iter)
{
if (!e) {
boost::asio::ip::tcp::endpoint iter = *ep_iter;
d->socket.async_connect(iter,
boost::bind(&Socket::handle_connect, this,
boost::asio::placeholders::error, ++ep_iter));
} else {
std::clog << "[Error - Socket::handle_resolve] " << e.message() << "." << std::endl;
}
}
void Socket::handle_connect(const boost::system::error_code& e,
boost::asio::ip::tcp::resolver::iterator ep_iter)
{
if (!e) {
std::cout << "[Notice - Socket::handle_connect] Connected to host." << std::endl;
d->connected = true;
write("CONNECT " + d->targetHost + ":" + d->targetPort + " HTTP/1.1\r\n\r\n");
receive();
} else if (ep_iter != boost::asio::ip::tcp::resolver::iterator()) {
d->socket.close();
boost::asio::ip::tcp::endpoint ep = *ep_iter;
d->socket.async_connect(ep,
boost::bind(&Socket::handle_connect, this,
boost::asio::placeholders::error, ++ep_iter));
} else {
std::clog << "[Error - Server::handle_connect] " << e.message() << "." << std::endl;
}
}
void Socket::handle_write(const boost::system::error_code& e,
size_t bytes)
{
assert(!e || bytes < 0);
}
void Socket::handle_read(const boost::system::error_code& e,
size_t bytes)
{
assert(!e || bytes < 0);
std::cout << receivedData() << std::endl;
receive();
}
void Socket::write(const std::string& message)
{
boost::asio::async_write(d->socket, boost::asio::buffer(message),
d->write.wrap(
boost::bind(&Socket::handle_write, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred)));
}
std::string Socket::receivedData() const
{
return std::string(d->buffers.data());
}
void Socket::receive()
{
d->socket.async_read_some(boost::asio::buffer(d->buffers),
d->read.wrap(
boost::bind(&Socket::handle_read, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred)));
}
void Socket::handle()
{
assert(!d->targetHost.empty());
assert(!d->targetPort.empty());
std::string str(d->buffers.data());
std::clog << "Received: " << str << "." << std::endl;
if (str.substr(0, 4) == "PING")
write("PO" + str.substr(2) + "\r\n");
else if (str.find("MODE") != std::string::npos)
write("JOIN #OTland\r\n");
else if (str.find("JOIN") != std::string::npos)
write("PRIVMSG #OTland :Hello\r\n");
}
bool Socket::connected() const
{
return d->connected;
}
void handler(const std::string& fileName, const std::string& host, const std::string& port, uint32_t threads);
int main(int argc, char **argv)
{
if (argc < 5) {
std::clog << "[Error - main] Usage: " << argv[0] << " <proxy_file> <host> <port> <threads>" << std::endl;
return 1;
}
std::string file(argv[1]);
std::string host(argv[2]);
std::string port(argv[3]);
uint32_t threads = static_cast<uint32_t>(std::atoi(argv[4]));
if (!threads)
threads = 1;
for (uint32_t __i = 0; __i < threads; ++__i)
// FIXME: Use the thread.join() there.
handler(file, host, port, threads);
}
typedef std::vector<Socket*> SocketVec;
void handler(const std::string& fileName, const std::string& host,
const std::string& port, uint32_t threads)
{
assert(!fileName.empty());
assert(!host.empty());
assert(!port.empty());
ProxyVec proxies = loadProxies(fileName);
assert(proxies.size());
SocketVec sockets;
for (ProxyVec::const_iterator it = proxies.begin(); it != proxies.end(); ++it) {
boost::asio::io_service io;
Socket socket(io, (*it)->name, toString((*it)->port), host, port);
// FIXME: socket is a local variable and it's address is invalid outside
// this loop -> memory leak -> seg-fault.
sockets.push_back(&socket);
}
for (SocketVec::const_iterator it = sockets.begin(); it != sockets.end(); ++it) {
if (!(*it)->connected())
continue;
(*it)->handle();
}
// FIXME: I'm not sure if I understand this architecture. A new thread is
// started with this function as handler ? Who waits until this new created
// thread is finished ? Where is the join() ?
(void) new boost::thread(boost::bind(handler, fileName, host, port, threads));
}
Sie könnten meinen Beitrag bearbeitet haben, aber trotzdem danke –
Ich habe hinzugefügt __ // FIXME: __ Kommentare mit meinen Bemerkungen im Quellcode. Vielleicht kann der __new__ Code hier gepostet werden, nachdem alle Kommentare gemacht wurden, um vergleichen zu können. –
Ich glaube nicht, das einzige Problem ist, aber in diesem Code-Schnipsel in handler
, erstellen Sie Ihre Socket
Objekte auf dem Stapel. Jedes Socket
Objekt, das Sie erstellen, wird am Ende der Schleife for
zerstört. Dies bedeutet, dass die Objekte im Vektor ungültige Objekte sind. Dies kann auch den Speicher-Heap so stark beschädigen, dass der angezeigte Fehler auftritt.
SocketVec sockets;
for (ProxyVec::const_iterator it = proxies.begin(); it != proxies.end(); ++it) {
boost::asio::io_service io;
Socket socket(io, (*it)->name, toString((*it)->port), host, port);
sockets.push_back(&socket);
}
Ändern Sie diese an:
SocketVec sockets;
for (ProxyVec::const_iterator it = proxies.begin(); it != proxies.end(); ++it) {
boost::asio::io_service io;
Socket* socket = new Socket(io, (*it)->name, toString((*it)->port), host, port);
sockets.push_back(socket);
}
<3 Danke, dass du darauf hingewiesen hast –
+1 @Fallen du solltest wirklich die [asio examples] durchgehen (http://www.boost.org/doc/libs/1_45_0/doc/html/boost_asio/examples.html) und modelliere deinen Code ähnlich. Zum Beispiel, wenn asynchrone Methoden verwendet werden, ist es sehr empfehlenswert (http://www.boost.org/doc/libs/1_45_0/doc/html/boost_asio/overview/core/threads.html), einen Pool von Threads, die 'io_service :: run' anstelle eines 'io_service' pro Thread aufrufen. –
Diese Antwort war ursprünglich ein Kommentar zu Dan's Antwort, aber nach an Ihrem Code suchen fühlte ich mich gezwungen, eine vollständige Antwort zu geben. Sie müssen sich die Boost.Asio examples genauer ansehen und verstehen, wie sie funktionieren. Achte besonders auf die asynchronen Beispiele, es sieht nicht so aus, als hättest du die Konzepte der Lebensdauer von Objekten verstanden und wie die Handler arbeiten. Insbesondere sollten Sie Single-Thread-Programme beherrschen, bevor Sie in mehrere Threads springen. Wenn Sie das erreicht haben, sollten Sie einen Thread-Pool verwenden, der io_service::run
statt io_service
pro Thread aufruft. Es wird letztendlich die Logik Ihres Programms leichter verständlich machen.
Sie sollten auch schauen in valgrind, gibt es eine ganze Reihe von Fehlern in Ihrem Code wie folgt ein:
==19853== Invalid read of size 4
==19853== at 0x10000D0E4: handler(std::string const&, std::string const&, std::string const&, unsigned int) (in ./a.out)
==19853== by 0x10000D5E6: main (in ./a.out)
==19853== Address 0x7fff5fbff398 is not stack'd, malloc'd or (recently) free'd
- 1. Seg Fehler machen neue Vektor <string>
- 2. strcpy gibt seg Fehler
- 3. wxWidgets unberechenbar Seg Fehler
- 4. strtok() seg Fehler
- 5. Qt OpenGLFunctions seg Fehler
- 6. Seg Fehler in for-Schleife?
- 7. Implizit Copykonstruktor Aufruf
- 8. Unterschied zwischen Std: String und Std :: String
- 9. C++, Seg Fehler und Speicherverwaltung
- 10. std :: unordered_map :: emplace Problem mit privaten/gelöscht Copykonstruktor
- 11. Warum Copykonstruktor wird in Aufruf aufgerufen std :: vector :: emplace_back()?
- 12. Seg Fault bei der Verwendung von std :: string auf einer Embedded-Linux-Plattform
- 13. Copykonstruktor tut primitive Datentypen
- 14. Seg-Fehler beim Speichern von Daten mit boost :: serialization
- 15. Fehler: Basisklasse 'A1' hat ein eigenes Copykonstruktor
- 16. Copykonstruktor geschweiften Klammern Initialisierung
- 17. Warum "std :: string (blablabla());" kompilieren ohne Fehler?
- 18. Implicit Copykonstruktor
- 19. seg Fehler bei der Verwendung von globalen Objekt statisches Element
- 20. Konstruktor-Referenzparameter führt zu Seg-Fehler
- 21. Get seg Fehler in gdb (Debugging)
- 22. LLVM Codegenerierung, die Seg-Fehler verursacht?
- 23. Seg Fehler erstellen Archiv für Swift App
- 24. Debuggen seg Fehler durch Pufferüberlauf verursacht
- 25. Was bedeutet dieser seg Fehler bedeutet
- 26. Mit sprintf mit std :: string in C++
- 27. Std :: String zu LPCTSTR
- 28. Fehler C2664 von von const std :: string Umwandlung in std :: string &
- 29. Copykonstruktor abgeleiteter QT Klasse
- 30. std :: string und std :: ios :: binary
Warum können Sie Ihren Code hier nicht enthalten? Bitte versuchen Sie, ein kleines Beispiel einzufügen, das Ihr Problem reproduziert. –