diff options
Diffstat (limited to 'src/main_gui.cpp')
| -rw-r--r-- | src/main_gui.cpp | 87 |
1 files changed, 77 insertions, 10 deletions
diff --git a/src/main_gui.cpp b/src/main_gui.cpp index a2577ca..875988f 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.cpp | |||
| @@ -291,6 +291,50 @@ static void ParseStartupArguments(int argc, char* argv[]) | |||
| 291 | } | 291 | } |
| 292 | } | 292 | } |
| 293 | 293 | ||
| 294 | // Report a startup failure somewhere the user will actually see it. | ||
| 295 | // | ||
| 296 | // Every fatal path here wrote to stderr and to printf, and on the platform most | ||
| 297 | // people use, neither reaches anybody. printf is remapped to OutputDebugStringF, | ||
| 298 | // so it lands in debug.log inside the data directory. A -mwindows binary | ||
| 299 | // launched by double-clicking has no stderr at all, and AttachTerminal() cannot | ||
| 300 | // help: it attaches to a *parent* console, which a double-clicked exe does not | ||
| 301 | // have. | ||
| 302 | // | ||
| 303 | // So the program exited silently. Someone whose wallet.dat needs a newer build | ||
| 304 | // -- which is exactly what the wallet format guard was added to tell them -- | ||
| 305 | // double-clicked Bitflash and watched nothing happen. | ||
| 306 | // | ||
| 307 | // The box is deliberately not shown for a headless node: those run under | ||
| 308 | // scheduled tasks and services, where a modal dialog waits forever for a click | ||
| 309 | // nobody is there to make. Headless already has a console when it has one, and | ||
| 310 | // its output goes to stderr and the log as before. | ||
| 311 | static void FatalStartupError(bool fHeadless, const string& strWhat, const string& strDetail) | ||
| 312 | { | ||
| 313 | printf("FATAL: %s\n", strWhat.c_str()); | ||
| 314 | if (!strDetail.empty()) | ||
| 315 | printf("FATAL: %s\n", strDetail.c_str()); | ||
| 316 | |||
| 317 | AttachTerminal(); | ||
| 318 | fprintf(stderr, "%s\n", strWhat.c_str()); | ||
| 319 | if (!strDetail.empty()) | ||
| 320 | fprintf(stderr, "%s\n", strDetail.c_str()); | ||
| 321 | fflush(stderr); | ||
| 322 | |||
| 323 | #ifdef _WIN32 | ||
| 324 | if (!fHeadless && GetConsoleWindow() == NULL) | ||
| 325 | { | ||
| 326 | string strBody = strWhat; | ||
| 327 | if (!strDetail.empty()) | ||
| 328 | strBody += "\n\n" + strDetail; | ||
| 329 | strBody += "\n\nNothing was changed. More detail is in debug.log, " | ||
| 330 | "inside the data directory."; | ||
| 331 | MessageBoxA(NULL, strBody.c_str(), "Bitflash", MB_OK | MB_ICONERROR | MB_SETFOREGROUND); | ||
| 332 | } | ||
| 333 | #else | ||
| 334 | (void)fHeadless; | ||
| 335 | #endif | ||
| 336 | } | ||
| 337 | |||
| 294 | int main(int argc, char* argv[]) | 338 | int main(int argc, char* argv[]) |
| 295 | { | 339 | { |
| 296 | if (arg(argc,argv,"/help") || arg(argc,argv,"-help") || | 340 | if (arg(argc,argv,"/help") || arg(argc,argv,"-help") || |
| @@ -323,25 +367,47 @@ int main(int argc, char* argv[]) | |||
| 323 | // libdb_cxx-6.2.dll -> CDB::CDB(...) -> LoadBlockIndex(...) -> main() | 367 | // libdb_cxx-6.2.dll -> CDB::CDB(...) -> LoadBlockIndex(...) -> main() |
| 324 | // | 368 | // |
| 325 | // The program knew what had gone wrong and threw the reason away. | 369 | // The program knew what had gone wrong and threw the reason away. |
| 370 | // Needed here, long before the headless branch runs, because whether a | ||
| 371 | // startup failure may pop a dialog depends on it. | ||
| 372 | #ifdef BITFLASH_NO_GUI | ||
| 373 | bool fHeadlessStartup = true; | ||
| 374 | #else | ||
| 375 | bool fHeadlessStartup = arg(argc,argv,"/nogui") || arg(argc,argv,"-nogui") || | ||
| 376 | arg(argc,argv,"/daemon") || arg(argc,argv,"-daemon"); | ||
| 377 | #endif | ||
| 378 | |||
| 326 | string strErrors; | 379 | string strErrors; |
| 327 | printf("Loading block index...\n"); | 380 | printf("Loading block index...\n"); |
| 328 | try | 381 | try |
| 329 | { | 382 | { |
| 330 | if (!LoadBlockIndex()) { fprintf(stderr, "LoadBlockIndex failed\n"); return 1; } | 383 | if (!LoadBlockIndex()) |
| 384 | { | ||
| 385 | FatalStartupError(fHeadlessStartup, "Cannot load the block index.", ""); | ||
| 386 | return 1; | ||
| 387 | } | ||
| 331 | } | 388 | } |
| 332 | catch (const std::exception& e) | 389 | catch (const std::exception& e) |
| 333 | { | 390 | { |
| 334 | fprintf(stderr, "Cannot read the block index: %s\n", e.what()); | 391 | FatalStartupError(fHeadlessStartup, |
| 335 | fprintf(stderr, "blkindex.dat and blk0001.dat may be from another machine or " | 392 | strprintf("Cannot read the block index: %s", e.what()), |
| 336 | "incomplete. Deleting both is safe -- they are re-downloaded -- " | 393 | "blkindex.dat and blk0001.dat may be from another machine or " |
| 337 | "but never delete wallet.dat, which holds your keys.\n"); | 394 | "incomplete. Deleting both is safe -- they are re-downloaded -- " |
| 395 | "but never delete wallet.dat, which holds your keys."); | ||
| 338 | return 1; | 396 | return 1; |
| 339 | } | 397 | } |
| 340 | 398 | ||
| 341 | printf("Loading wallet...\n"); | 399 | printf("Loading wallet...\n"); |
| 342 | try | 400 | try |
| 343 | { | 401 | { |
| 344 | if (!LoadWallet()) { fprintf(stderr, "LoadWallet failed\n"); return 1; } | 402 | if (!LoadWallet()) |
| 403 | { | ||
| 404 | // LoadWallet() explains itself into strWalletLoadError when it | ||
| 405 | // knows why -- an unsupported wallet format, for one, which is the | ||
| 406 | // case this whole path exists to make visible. | ||
| 407 | FatalStartupError(fHeadlessStartup, "Cannot open wallet.dat.", | ||
| 408 | strWalletLoadError); | ||
| 409 | return 1; | ||
| 410 | } | ||
| 345 | 411 | ||
| 346 | // After the block index, so there is a chain to compare the wallet | 412 | // After the block index, so there is a chain to compare the wallet |
| 347 | // against, and before anything reports a balance. | 413 | // against, and before anything reports a balance. |
| @@ -349,10 +415,11 @@ int main(int argc, char* argv[]) | |||
| 349 | } | 415 | } |
| 350 | catch (const std::exception& e) | 416 | catch (const std::exception& e) |
| 351 | { | 417 | { |
| 352 | fprintf(stderr, "Cannot read wallet.dat: %s\n", e.what()); | 418 | FatalStartupError(fHeadlessStartup, |
| 353 | fprintf(stderr, "The file was left untouched. A wallet.dat written by a " | 419 | strprintf("Cannot read wallet.dat: %s", e.what()), |
| 354 | "different platform's Berkeley DB is the usual cause; back it " | 420 | "The file was left untouched. A wallet.dat written by a " |
| 355 | "up before trying anything else.\n"); | 421 | "different platform's Berkeley DB is the usual cause; back it " |
| 422 | "up before trying anything else."); | ||
| 356 | return 1; | 423 | return 1; |
| 357 | } | 424 | } |
| 358 | printf("Height=%d\n", nBestHeight); | 425 | printf("Height=%d\n", nBestHeight); |