diff --git a/Telegram/SourceFiles/_other/updater_linux.cpp b/Telegram/SourceFiles/_other/updater_linux.cpp
index 35d67072c..f65ad0944 100644
--- a/Telegram/SourceFiles/_other/updater_linux.cpp
+++ b/Telegram/SourceFiles/_other/updater_linux.cpp
@@ -324,7 +324,7 @@ bool update() {
 int main(int argc, char *argv[]) {
     bool needupdate = true, autostart = false, debug = false, tosettings = false, startintray = false, testmode = false;
 
-    char *key = 0;
+    char *key = 0, *crashreport = 0;
     for (int i = 1; i < argc; ++i) {
         if (equal(argv[i], "-noupdate")) {
             needupdate = false;
@@ -342,7 +342,9 @@ int main(int argc, char *argv[]) {
             key = argv[i];
         } else if (equal(argv[i], "-workpath") && ++i < argc) {
             workDir = argv[i];
-        }
+		} else if (equal(argv[i], "-crashreport") && ++i < argc) {
+			crashreport = argv[i];
+		}
     }
     openLog();
 
@@ -408,17 +410,20 @@ int main(int argc, char *argv[]) {
     char *args[MaxArgsCount] = {0}, p_noupdate[] = "-noupdate", p_autostart[] = "-autostart", p_debug[] = "-debug", p_tosettings[] = "-tosettings", p_key[] = "-key", p_startintray[] = "-startintray", p_testmode[] = "-testmode";
     int argIndex = 0;
     args[argIndex++] = path;
-    args[argIndex++] = p_noupdate;
-    if (autostart) args[argIndex++] = p_autostart;
-    if (debug) args[argIndex++] = p_debug;
-	if (startintray) args[argIndex++] = p_startintray;
-	if (testmode) args[argIndex++] = p_testmode;
-    if (tosettings) args[argIndex++] = p_tosettings;
-    if (key) {
-        args[argIndex++] = p_key;
-        args[argIndex++] = key;
-    }
-
+	if (crashreport) {
+		args[argIndex++] = crashreport;
+	} else {
+		args[argIndex++] = p_noupdate;
+		if (autostart) args[argIndex++] = p_autostart;
+		if (debug) args[argIndex++] = p_debug;
+		if (startintray) args[argIndex++] = p_startintray;
+		if (testmode) args[argIndex++] = p_testmode;
+		if (tosettings) args[argIndex++] = p_tosettings;
+		if (key) {
+			args[argIndex++] = p_key;
+			args[argIndex++] = key;
+		}
+	}
     pid_t pid = fork();
     switch (pid) {
     case -1: writeLog("fork() failed!"); return 1;
diff --git a/Telegram/SourceFiles/pspecific_linux.cpp b/Telegram/SourceFiles/pspecific_linux.cpp
index 569639893..675091fe9 100644
--- a/Telegram/SourceFiles/pspecific_linux.cpp
+++ b/Telegram/SourceFiles/pspecific_linux.cpp
@@ -973,6 +973,112 @@ QAbstractNativeEventFilter *psNativeEventFilter() {
 	return _psEventFilter;
 }
 
+void psWriteDump() {
+}
+
+void psWriteStackTrace(int file) {
+	void *addresses[1024] = { 0 };
+
+	size_t size = backtrace(addresses, 1024);
+
+	backtrace_symbols_fd(addresses, size, file);
+}
+
+QString demanglestr(const QString &mangled) {
+	QByteArray cmd = ("c++filt -n " + mangled).toUtf8();
+	FILE *f = popen(cmd.constData(), "r");
+	if (!f) return "BAD_SYMBOL_" + mangled;
+
+	QString result;
+	char buffer[4096] = { 0 };
+	while (!feof(f)) {
+		if (fgets(buffer, 4096, f) != NULL) {
+			result += buffer;
+		}
+	}
+	pclose(f);
+	return result.trimmed();
+}
+
+QString _showCrashDump(const QByteArray &crashdump, QString dumpfile) {
+	QString initial = QString::fromUtf8(crashdump), result;
+	QStringList lines = initial.split('\n');
+	result.reserve(initial.size());
+	int32 i = 0, l = lines.size();
+
+	while (i < l) {
+		for (; i < l; ++i) {
+			result.append(lines.at(i)).append('\n');
+			QString line = lines.at(i).trimmed();
+			if (line == qstr("Backtrace:")) {
+				++i;
+				break;
+			}
+		}
+
+		for (int32 start = i; i < l; ++i) {
+			QString line = lines.at(i).trimmed();
+			if (line.isEmpty()) break;
+
+			if (!QRegularExpression(qsl("^\\d+")).match(line).hasMatch()) {
+				if (!lines.at(i).startsWith(qstr("ERROR: "))) {
+					result.append(qstr("BAD LINE: "));
+				}
+				result.append(line).append('\n');
+				continue;
+			}
+			QStringList lst = line.split(' ', QString::SkipEmptyParts);
+			result.append(lst.at(0)).append(' ');
+			for (int j = 1, s = lst.size();;) {
+				if (lst.at(j).startsWith('_')) {
+					result.append(demanglestr(lst.at(j)));
+					if (++j < s) {
+						result.append(' ');
+						for (;;) {
+							result.append(lst.at(j));
+							if (++j < s) {
+								result.append(' ');
+							} else {
+								break;
+							}
+						}
+					}
+					break;
+				} else if (j > 2) {
+					result.append(lst.at(j));
+				}
+				if (++j < s) {
+					result.append(' ');
+				} else {
+					break;
+				}
+			}
+			result.append('\n');
+		}
+	}
+	return result;
+}
+
+int psShowCrash(const QString &crashdump) {
+	QString text;
+
+	QFile dump(crashdump);
+	if (dump.open(QIODevice::ReadOnly)) {
+		text = qsl("Crash dump file '%1':\n\n").arg(QFileInfo(crashdump).absoluteFilePath());
+		text += _showCrashDump(dump.readAll(), crashdump);
+	} else {
+		text = qsl("ERROR: could not read crash dump file '%1'").arg(QFileInfo(crashdump).absoluteFilePath());
+	}
+
+	QByteArray args[] = { "" };
+	int a_argc = 1;
+	char *a_argv[1] = { args[0].data() };
+	QApplication app(a_argc, a_argv);
+
+	ShowCrashReportWindow wnd(text);
+	return app.exec();
+}
+
 bool _removeDirectory(const QString &path) { // from http://stackoverflow.com/questions/2256945/removing-a-non-empty-directory-programmatically-in-c-or-c
     QByteArray pathRaw = QFile::encodeName(path);
     DIR *d = opendir(pathRaw.constData());
@@ -1243,15 +1349,15 @@ void psNewVersion() {
 	psRegisterCustomScheme();
 }
 
-bool _execUpdater(bool update = true) {
+bool _execUpdater(bool update = true, const QString &crashreport = QString()) {
     static const int MaxLen = 65536, MaxArgsCount = 128;
 
     char path[MaxLen] = {0};
     QByteArray data(QFile::encodeName(cExeDir() + "Updater"));
     memcpy(path, data.constData(), data.size());
 
-    char *args[MaxArgsCount] = {0}, p_noupdate[] = "-noupdate", p_autostart[] = "-autostart", p_debug[] = "-debug", p_tosettings[] = "-tosettings", p_key[] = "-key", p_path[] = "-workpath", p_startintray[] = "-startintray", p_testmode[] = "-testmode";
-    char p_datafile[MaxLen] = {0}, p_pathbuf[MaxLen] = {0};
+    char *args[MaxArgsCount] = {0}, p_noupdate[] = "-noupdate", p_autostart[] = "-autostart", p_debug[] = "-debug", p_tosettings[] = "-tosettings", p_key[] = "-key", p_path[] = "-workpath", p_startintray[] = "-startintray", p_testmode[] = "-testmode", p_crashreport[] = "-crashreport";
+    char p_datafile[MaxLen] = {0}, p_pathbuf[MaxLen] = {0}, p_crashreportbuf[MaxLen] = {0};
     int argIndex = 0;
     args[argIndex++] = path;
     if (!update) {
@@ -1276,6 +1382,14 @@ bool _execUpdater(bool update = true) {
         args[argIndex++] = p_path;
         args[argIndex++] = p_pathbuf;
     }
+	if (!crashreport.isEmpty()) {
+		QByteArray crashreportf = crashreport.toUtf8();
+		if (crashreportf.size() < MaxLen) {
+			memcpy(p_crashreportbuf, crashreportf.constData(), crashreportf.size());
+			args[argIndex++] = p_crashreport;
+			args[argIndex++] = p_crashreportbuf;
+		}
+	}
 
     pid_t pid = fork();
     switch (pid) {
@@ -1291,8 +1405,8 @@ void psExecUpdater() {
 	}
 }
 
-void psExecTelegram() {
-    _execUpdater(false);
+void psExecTelegram(const QString &crashreport) {
+    _execUpdater(false, crashreport);
 }
 
 bool psShowOpenWithMenu(int x, int y, const QString &file) {
diff --git a/Telegram/SourceFiles/pspecific_linux.h b/Telegram/SourceFiles/pspecific_linux.h
index 6fd335651..6248cc072 100644
--- a/Telegram/SourceFiles/pspecific_linux.h
+++ b/Telegram/SourceFiles/pspecific_linux.h
@@ -113,6 +113,10 @@ private:
     uint64 _psLastIndicatorUpdate;
 };
 
+void psWriteDump();
+void psWriteStackTrace(int file);
+int psShowCrash(const QString &crashdump);
+
 void psDeleteDir(const QString &dir);
 
 void psUserActionDone();
@@ -144,7 +148,7 @@ int psCleanup();
 int psFixPrevious();
 
 void psExecUpdater();
-void psExecTelegram();
+void psExecTelegram(const QString &arg = QString());
 
 bool psShowOpenWithMenu(int x, int y, const QString &file);
 
diff --git a/Telegram/SourceFiles/pspecific_wnd.cpp b/Telegram/SourceFiles/pspecific_wnd.cpp
index 3407fc421..effea1559 100644
--- a/Telegram/SourceFiles/pspecific_wnd.cpp
+++ b/Telegram/SourceFiles/pspecific_wnd.cpp
@@ -2267,15 +2267,16 @@ void psExecUpdater() {
 	}
 }
 
-void psExecTelegram() {
-	QString targs = qsl("-noupdate");
-	if (cRestartingToSettings()) targs += qsl(" -tosettings");
-	if (cLaunchMode() == LaunchModeAutoStart) targs += qsl(" -autostart");
-	if (cDebug()) targs += qsl(" -debug");
-	if (cStartInTray()) targs += qsl(" -startintray");
-	if (cTestMode()) targs += qsl(" -testmode");
-	if (cDataFile() != qsl("data")) targs += qsl(" -key \"") + cDataFile() + '"';
-
+void psExecTelegram(const QString &crashreport) {
+	QString targs = crashreport.isEmpty() ? qsl("-noupdate") : ('"' + crashreport + '"');
+	if (crashreport.isEmpty()) {
+		if (cRestartingToSettings()) targs += qsl(" -tosettings");
+		if (cLaunchMode() == LaunchModeAutoStart) targs += qsl(" -autostart");
+		if (cDebug()) targs += qsl(" -debug");
+		if (cStartInTray()) targs += qsl(" -startintray");
+		if (cTestMode()) targs += qsl(" -testmode");
+		if (cDataFile() != qsl("data")) targs += qsl(" -key \"") + cDataFile() + '"';
+	}
 	QString telegram(QDir::toNativeSeparators(cExeDir() + cExeName())), wdir(QDir::toNativeSeparators(cWorkingDir()));
 
 	DEBUG_LOG(("Application Info: executing %1 %2").arg(cExeDir() + cExeName()).arg(targs));
@@ -3059,7 +3060,7 @@ void psWriteStackTrace(int file) {
 #error "Platform not supported!"
 #endif
 
-	for (frameNum = 0; frameNum < 1000; ++frameNum) {
+	for (frameNum = 0; frameNum < 1024; ++frameNum) {
 		// get next stack frame (StackWalk64(), SymFunctionTableAccess64(), SymGetModuleBase64())
 		// if this returns ERROR_INVALID_ADDRESS (487) or ERROR_NOACCESS (998), you can
 		// assume that either you are done, or that the stack is so hosed that the next
diff --git a/Telegram/SourceFiles/pspecific_wnd.h b/Telegram/SourceFiles/pspecific_wnd.h
index 053945f3b..3d46e615f 100644
--- a/Telegram/SourceFiles/pspecific_wnd.h
+++ b/Telegram/SourceFiles/pspecific_wnd.h
@@ -153,7 +153,7 @@ int psCleanup();
 int psFixPrevious();
 
 void psExecUpdater();
-void psExecTelegram();
+void psExecTelegram(const QString &arg = QString());
 
 bool psShowOpenWithMenu(int x, int y, const QString &file);