精华内容
下载资源
问答
  • 应用程序崩溃定位查找 ()

    千次阅读 2015-10-12 10:29:12
    它发生在我们最好的: 你工作愉快地在您的应用程序,一切都很好,然后突然 — — 噗!— — 它的崩溃。...相反,您需要采取系统的方法和学习如何您的方式通过一个崩溃的原因。 第一要务是找出确切地在您的代码下崩溃

    它发生在我们最好的: 你工作愉快地在您的应用程序,一切都很好,然后突然 — — 噗!— — 它的崩溃。收纳!!(线索悲伤小提琴)。

    第一件事是: ,不要惊慌!

    固定崩溃并不需要硬。你可能会进一步恶化的情况,如果你抓狂,开始随意改变一些东西,希望该 bug 会神奇地消失如果只你说出正确的咒语。相反,您需要采取系统的方法和学习如何您的方式通过一个崩溃的原因。

    第一要务是找出确切地在您的代码下崩溃发生: 在哪个文件和哪些行。Xcode 调试器会帮助你这一点,但您需要了解如何善用它,而这正是本教程将告诉你!

    本教程是为所有的开发人员,从初级到高级。即使你是经验丰富的 iOS 开发者,你可能会捡拾了一些提示和技巧一路走来你不知道!

    入门

    下载示例项目你会看到,这是一个漏洞百出的程序!当你在 Xcode 中打开该项目时,它显示了至少八个编译器警告,始终是将来麻烦的预兆。顺便说一句,我们使用 Xcode 4.3 对于本教程,虽然 4.2 版应该工作一样。

    注:要跟随本教程中,应用程序需要运行在 iOS 5 模拟器。如果您在您的设备上运行应用程序,你还是会崩溃,但他们可能不会发生相同的顺序。

    在模拟器中运行应用程序,看看会发生什么。

    The app crashes immediately.

    嘿,它崩溃了!:-]

    基本上有两种类型的可能发生的崩溃: SIGABRT (也称为 EXC_CRASH) 和EXC_BAD_ACCESS (其中 SIGBUS 或 SIGSEGV 的名义也可以显示)。

    据崩溃去,SIGABRT 是一个非常好,因为它是受控制的崩溃。应用程序故意终止,因为系统识别应用程序做了它不能这样做。

    另一方面,EXC_BAD_ACCESS,是很难调试,因为它只有当应用程序进入损坏的状态,通常是由于内存管理问题。

    幸运的是,这第一次坠毁 (许多尚未来) 是 SIGABRT。SIGABRT 总是带有一条错误消息,您可以看到在 Xcode 的调试输出窗格 (底部窗口的右下角)。(如果看不到调试输出窗格中,点击你 Xcode 窗口以显示调试区域上右上角的视图图标部分的中间图标。如果仍然调试输出窗格不可见,您可能必须点击顶部的调试区域 — — 搜索字段旁边的图标的中间图标)。在这种情况下,它说,这样的事情:

    Problems[14465:f803] -[UINavigationController setList:]: unrecognized selector sent to
    instance 0x6a33840
    Problems[14465:f803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException',
    reason: '-[UINavigationController setList:]: unrecognized selector sent to instance 0x6a33840'
    *** First throw call stack:
    (0x13ba052 0x154bd0a 0x13bbced 0x1320f00 0x1320ce2 0x29ef 0xf9d6 0x108a6 0x1f743
    0x201f8 0x13aa9 0x12a4fa9 0x138e1c5 0x12f3022 0x12f190a 0x12f0db4 0x12f0ccb 0x102a7
    0x11a9b 0x2792 0x2705)
    terminate called throwing an exception

    很重要的是你学会破译这些错误消息,因为它们包含了什么问题的重要线索。在这里,有趣的部分是:

    [UINavigationController setList:]: unrecognized selector sent to instance 0x6a33840

    错误消息"无法识别的选择器发送以实例 XXX"意味着应用程序正试图调用不存在的方法。经常发生这种情况因为在错误的对象上调用的方法。在这里,所讨论的对象是 UINavigationController (位于 0x6a33840 的内存地址),方法是曲目:.

    知道飞机坠毁的原因是好的但是你第一次的行动方针是找出代码中此错误发生。你需要找到的名称的源文件和行为不端的行的编号。你可以使用调用堆栈(也称为栈跟踪或回溯)。

    当应用程序崩溃,Xcode 窗口切换到调试导航器的左窗格。报告显示在应用程序中,活跃的线程,并突出崩溃的线程。通常,将线程 1,主线程的应用程序,因为这是在哪里,你会做你的大部分工作。如果您的代码使用队列或后台线程,然后应用程序可能会崩溃中的其他线程。

    The call stack. It doesn't show everything yet.

    目前,Xcode 突出了在main.m main ()函数作为问题的根源。这不告诉你很多,所以你只好挖深一点。

    若要查看更多的调用堆栈,一路向右拖动滑块底部的调试导航。在崩溃的时刻,将显示完整的调用堆栈:

    The expanded call stack.

    每个从该列表中的项目是一个函数或方法,从应用程序或从 iOS 框架之一。调用堆栈显示你什么函数或方法是在应用程序中当前处于活动状态。调试器已暂停应用程序和所有这些函数和方法现在被冻结了。

    在底部, start (),函数在第一次调用。在某个地方在其执行它叫上面,main ()函数。这是该应用程序的起点,它总是会在底部附近。main ()又被称为UIApplicationMain()这是行的 (在 Xcode 的右窗格中突出显示的开头) 的绿色箭头指向在编辑器窗口中的行。

    UIApplicationMain()进一步上涨堆栈,调用_run方法上的 UIApplication 对象,称为CFRunLoopRunInMode(),称为CFRunLoopRunSpecific(),依此类推,一直到__pthread_kill.

    How a call stack works.

    所有的这些函数和方法中调用堆栈,除了main (),呈灰色。这是因为他们来自内置 iOS 框架。有是没有源代码提供给他们。

    此异常堆栈包含源代码唯一永恒的东西是main.m,所以这就是 Xcode 源代码编辑器中显示的内容,尽管它不是真的崩溃的真正来源。这往往混淆新的开发人员,但在一分钟内,我将显示你如何使它的意义。

    为了好玩,点击任何一个其他的项从栈跟踪,你会看到一堆的汇编代码,可能你不有太大的意义:

    If there is no source code, Xcode shows assembly.

    哦,要是我们有源代码的!:-]

    异常断点

    使应用程序崩溃的代码中,你如何找到行?好吧,每当你得到这样的栈跟踪,异常被引发 (你可以告诉,因为函数调用堆栈中的一个叫objc_exception_rethrow的应用.)

    当该程序抓住做不应该做的事情时,将发生异常。你现在看着是此异常的后果: 应用程序做了一些错事,异常,和 Xcode 显示你的结果。理想情况下,你会想要看到准确获取抛出该异常。

    幸运的是,你可以告诉 Xcode 来暂停程序,只是那一刻,使用异常断点。断点是在某一特定时刻暂停您的程序的调试工具。你会看到更多的人在本教程中,第二部分,但现在您将使用具体的断点将暂停程序,只是之前获取引发异常。

    若要设置异常断点,我们必须切换到断点导航:

    The Breakpoint Navigator

    底部是一个小小的 + 按钮。单击此按钮,然后选择添加异常断点:

    Adding the Exception Breakpoint

    新断点将添加到列表中:

    After the Exception Breakpoint has been added

    单击完成按钮关闭弹出框。Xcode 的工具栏中的断点按钮现在已启用的通知。如果你想要无任何已启用的断点运行应用程序,您可以简单地切换此按钮可关闭。但现在,离开它,再次运行该应用程序。

    After the crash, the problematic source line is now highlighted.

    这是更好!源代码编辑器现在指向一条线从源代码 — — 不再讨厌大会的东西 — — 和通知调用堆栈在左边 (您可能需要切换到调用堆栈通过取决于你怎么有 Xcode 设置中的调试导航) 也看起来不同。

    显然,罪魁祸首就是这条线在 AppDelegate 的应用程序: didFinishLaunchingWithOptions:方法:

    	viewController.list = [NSArray arrayWithObjects:@"One", @"Two"];

    再看看那条错误消息:

    [UINavigationController setList:]: unrecognized selector sent to instance 0x6d4ed20

    在代码中,"viewController.list = 东西"调用曲目:在幕后,因为"名单"是MainViewController类的属性。不过,根据错误消息 viewController 变量不指向到一个 MainViewController 对象,但对 UINavigationController — — 而且当然,UINavigationController 并没有"列表"属性!所以事情混淆了这里。

    打开要看到窗口的 rootViewController 属性实际上指向的演示图板文件:

    The storyboard has a navigation controller.

    啊哈哈!演示图板的初始视图控制器是一个导航控制器。这解释了为什么 window.rootViewController 是一个 UINavigationController 对象,而不是你期望的 MainViewController。若要解决此问题,请替换应用程序: didFinishLaunchingWithOptions:以下列:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
    	UINavigationController *navController = (UINavigationController *)self.window.rootViewController;
    	MainViewController *viewController = (MainViewController *)navController.topViewController;
    	viewController.list = [NSArray arrayWithObjects:@"One", @"Two"];
    	return YES;
    }

    首先你从 self.window.rootViewController,对 UINavigationController 的引用,然后一旦你有了这些你也可以得到指针到 MainViewController 索要其 topViewController 导航控制器。现在 viewController 变量应该指向正确的对象。

    注:每当你得到一个"无法识别选择器发送到实例 XXX"错误,请检查该对象是正确的类型和它实际上已具有该名称的方法。通常你会发现,你是对对象调用方法不同比你想象的因为一个指针变量可能不包含正确的值。

    The different parts of the "Unrecognized selector" error message.

    此错误的另一个常见原因是方法名称的拼写错误。你会看到一个这样的例子在位。

    你第一次内存错误

    那应该固定我们第一个问题。再次运行该应用程序。哎呦,它坠毁在同一行上,现在只有一个 EXC_BAD_ACCESS 错误。这意味着应用程序有一个内存管理问题。

    Our first EXC_BAD_ACCESS error.

    与内存相关的崩溃的来源很难精确定位,因为邪恶可能更早在程序中完成。如果一块故障代码的内存结构使人腐化,这结果可能不会显示,直到很久以后,和在一个完全不同的地方。

    事实上,bug 可能永远不会出现在你在所有测试时,前后只有它丑陋的头在你的客户的设备上。你不想这样的事情发生!

    然而,这个特定的崩溃,很容易解决。如果你看看源代码编辑器,Xcode 一直在警告你说这条线一直以来。在左边的行号上看到黄色的三角形吗?指示编译器警告。如果你点击黄色三角形,Xcode 应该弹出一个"修复它"建议像这样:

    Xcode warns about a missing sentinel.

    通过给它的对象,列表和此类列表 NSArray 对象应该终止使用零代码初始化,哨兵警告中提到。但这并不做和现在 NSArray 获取混为一谈。它试图读取,并不存在的对象和应用程序崩溃硬。

    这是你真的不应该做,尤其是因为 Xcode 已经警告您关于它的错误。修复代码,如下所示添加到列表中的零 (或只是可以从菜单中选择"修复它"选项):

    	viewController.list = [NSArray arrayWithObjects:@"One", @"Two", nil];

    "此类不是键值编码兼容"

    运行该应用程序,再来看什么其他有趣的 bug 这个项目已经在商店为您。和你知道吗?它再次崩溃在main.m上。由于异常断点仍处于启用状态,我们看不到任何突出显示的应用程序源代码,这次失事真正没有发生任何应用程序源代码中。调用堆栈证实这: 这些方法都不属于该应用程序,除了main ():

    The call stack for the "key value coding" crash.

    如果你从楼顶下来看通过的方法名称,有 NSObject 和键-值编码发生了一些东西。下面是[UIRuntimeOutletConnection 连接]呼吁。我也不知道什么是,但它看起来像它已经跟连接插座。下面,是谈论从笔尖加载视图的方法。因此,那已经给你一些线索。

    然而,没有方便错误信息是 Xcode 的调试窗格中。这是因为没有尚未引发该异常。异常断点已暂停程序,只是之前它会告诉你异常的原因。有时你得到部分的错误信息与异常断点启用,而有时你不知道。

    若要查看完整的错误消息,请单击调试器工具栏中的"继续程序执行"按钮:

    The Continue Program Execution button.

    您可能需要单击它不止一次,但然后您会收到错误消息:

    Problems[14961:f803] *** Terminating app due to uncaught exception 'NSUnknownKeyException', 
    reason: '[<MainViewController 0x6b3f590> setValue:forUndefinedKey:]: this class is not
    key value coding-compliant for the key button.'
    *** First throw call stack:
    (0x13ba052 0x154bd0a 0x13b9f11 0x9b1032 0x922f7b 0x922eeb 0x93dd60 0x23091a 0x13bbe1a 
    0x1325821 0x22f46e 0xd6e2c 0xd73a9 0xd75cb 0xd6c1c 0xfd56d 0xe7d47 0xfe441 0xfe45d 
    0xfe4f9 0x3ed65 0x3edac 0xfbe6 0x108a6 0x1f743 0x201f8 0x13aa9 0x12a4fa9 0x138e1c5 
    0x12f3022 0x12f190a 0x12f0db4 0x12f0ccb 0x102a7 0x11a9b 0x2872 0x27e5)
    terminate called throwing an exception

    作为之前,您可以忽略底部的数字。他们代表调用堆栈,但你已经有了,以一种更方便 — — 和可读!— — 在左边的调试导航中的格式。

    有趣的片段如下:

    • NSUnknownKeyException
    • MainViewController
    • "此类不是键值编码兼容为关键的按钮"

    异常,NSUnknownKeyException 的名称通常是很好的指标是错误。它告诉你有什么地方是"未知的钥匙"。某天某地,显然是 MainViewController,和关键被命名为"按钮"。

    当我们建立了所有这一切都发生加载笔尖时。应用程序使用演示图板,而不是笔尖,但内部演示图板只是一个集合家发钞银行,因此它必须是一个演示图板中的错误。

    查阅 MainViewController 插座:

    The button outlet in the storyboard.

    在连接检查器中,您可以看到的视图控制器中心 UIButton 连接到 MainViewController 的"按钮"插座。因此,情节提要/笔尖指插座命名"按钮,"但根据错误消息,它找不到这个插座。

    看一看MainViewController.h:

    @interface MainViewController : UIViewController
     
    @property (nonatomic, retain) NSArray *list;
    @property (nonatomic, retain) IBOutlet UIButton *button;
     
    - (IBAction)buttonTapped:(id)sender;
     
    @end

    @property 定义为"按钮"插座有,是什么问题吗?如果你一直关注编译器的警告,你可能会发现它已经。

    如果没有,请查阅MainViewController.m/s @synthesize 列表。现在看到的问题吗?

    代码不实际上多 @synthesize 按钮属性。它告诉 MainViewController,它有一个名为"按钮,"而不为它提供支持实例变量和 getter 和 setter 方法 (这是什么所 @synthesize 做)。

    低于现有的 @synthesize 线,若要解决此问题在MainViewController.m中添加以下内容:

    @synthesize button = _button;

    现在应用程序应该不再崩溃当你运行它!

    注:该错误通常"此类不是键值编码兼容键 XXX"时发生加载实际上并不存在的属性是指的笔尖。这通常发生在你删除插座属性,从您的代码,但不是能从笔尖的连接。

    按下按钮

    现在,该应用程序的工作 — — 或在至少启动没有问题 — — 同时,点击该按钮的时间。

    The app finally starts up.

    哇!应用程序崩溃与 SIGABRT 在main.m上。在调试窗格中的错误消息是:

    Problems[6579:f803] -[MainViewController buttonTapped]: unrecognized selector sent
    to instance 0x6e44850

    堆栈跟踪并不是太富有启发性。它列出一大堆的方法相关的一种方法或其他发送事件和执行操作,但是你已经知道了涉及行为。毕竟,你点击 UIButton 和,结果在被调用 IBAction 方法。

    当然,你看到这个错误消息之前。被调用的方法不存在。这次的目标对象,MainViewController,看起来是那个合适的人,因为操作方法通常住在包含按钮的视图控制器。并且如果你看一下MainViewController.h,IBAction 方法是确实有:

    - (IBAction)buttonTapped:(id)sender;

    或者是它吗?错误消息表示方法名称是buttonTapped,但 MainViewController 有一种方法命名为buttonTapped:,以冒号结尾因为此方法接受一个参数 (名为"发件人")。方法名称的错误消息,从另外一方面,不包括冒号和因此不带任何参数。该方法的签名而是看起来像这样:

    - (IBAction)buttonTapped;

    在这里发生了什么?该方法最初没有参数 (某物所允许的操作方法),在这段时间的演示图板中建立了连接到这个按钮触摸内部事件。然而,一些时间后,方法签名更改为包含"发件人"参数,但未更新演示图板。

    您可以在连接检查器按钮上的演示图板中看到:

    The button's connections in the storyboard.

    首先断开连接事件 (单击小 X) 触摸里面,然后再将其连接到主视图控制器但这次选择buttonTapped:方法。请注意,在检查器中连接有现在一个冒号后的方法名称。

    运行应用程序,再点击按钮。什么?!你再"无法识别选择器"的消息,尽管这一次它正确地标识方法作为buttonTapped:,用冒号。

    Problems[6675:f803] -[MainViewController buttonTapped:]: unrecognized selector sent
    to instance 0x6b6c7f0

    如果你仔细看,编译器警告应指向你的解决方案再一次。Xcode 抱怨,MainViewController 的执行是不完整。具体来说,方法定义为buttonTapped:找不到。

    Xcode shows an incomplete implementation warning.

    来看看MainViewController.m的时间。当然似乎是buttonTapped:方法在那里,虽然......等等,它拼错了:

    - (void)butonTapped:(id)sender

    容易修复。重命名的方法:

    - (void)buttonTapped:(id)sender

    请注意,你不一定需要将它声明为 IBAction,虽然你可以这样做,如果你认为是整齐的。

    注:这种事情是很容易赶上如果你注意到编译器警告。就个人而言,我将所有警告视为致命错误 (甚至还有选项为此生成设置屏幕中 Xcode) 和之前运行的应用,以及 Xcode 是很擅长指出了愚蠢的错误,像这些一样,它是明智的要注意这些提示,我会搞定的他们每一个人。

    摆弄内存

    你知道钻: 运行应用程序,点击按钮,等待飞机坠毁。没错,就是这样:

    The app crashes on NSLog().

    它是那些 EXC_BAD_ACCESS,另一个呀!幸运的是,在 Xcode 显示你到底在哪里崩溃发生了,在buttonTapped:方法:

    	NSLog("You tapped on: %s", sender);

    有时这些错误可能需要一两个片刻登记在你的头脑,但再次 Xcode 借伸出援助之手 — — 只是水龙头黄色的三角形,看看有什么不对:

    Objective-C strings must have a @ prefix.

    NSLog()采用目的型 C 字符串,不是普通旧 C-字符串,所以插入 @ 将修复它:

    	NSLog(@"You tapped on: %s", sender);

    你会注意到黄色警告三角不会消失。这是因为这条线有可能或不可能会崩溃,您的应用程序的另一个 bug。那些有趣的人。有时代码工作就好 — — 或至少出现上班就好 — — 而在其他时间它会崩溃。(当然,这些各种各样的崩溃仅发生在客户的设备上,从来没有对你自己)

    让我们看看新的警告是:

    Xcode warns about a format string issue.

    %S 说明符为 C 样式字符串。C 字符串是只是一段记忆 — — 一个普通老的字节数组 — — 那终止由所谓的"NUL 字符,"真的只值 0。例如,C 字符串"崩溃!"看起来像这样在内存中:

    What a C-string looks like in memory.

    每当你使用一个函数或期望的 C 样式字符串的方法,你必须确保字符串的值为 0,以结束或功能将不能识别的字符串已经结束。

    现在,当您指定 %s 以NSLog()格式字符串 — — 或在 NSString 的 stringWithFormat — — 该参数被解释好像它是一个 C 字符串。在这种情况下,"发件人"为参数,而是指向一个 UIButton 对象,这当然是 C 字符串的指针。如果无论"发件人"指向包含一个 0 字节,则NSLog()不会崩溃,但输出的东西如:

    You tapped on: xËj

    实际上,你可以看到这来自何处。再次运行该应用程序,点击按钮,等待飞机坠毁。现在,在左半部分的调试窗格中,右键单击"发件人"并选择"查看内存的 * 发件人"选项 (请务必选择一个带有星号在发件人)。

    The view memory menu option.

    Xcode 现在将显示你的内存内容在该地址,而它正是NSLog()打印出来。

    Xcode shows the contents of memory.

    然而,就不能保证是 NUL 字节,一个字节,你可能只是作为容易遇到 EXC_BAD_ACCESS 错误。如果你总是测试您的应用程序可能不会发生长时间在模拟器上,作为这种情况下总是可能对你有利你特定的测试环境中。这使得这些类型的 bug 很难跟踪。

    当然,在这种情况下 Xcode 已经警告你关于错误的格式说明符,所以这个 bug 是很容易找到。但每当你使用 C 字符串或者直接操作内存,你必须非常小心,不糊弄别人的记忆。

    如果你幸运的话,该应用程序将会总是崩溃和 bug 很容易找到,但更常见的是,应用程序将仅崩溃有时 — — 使这一问题很难再重现!— —,然后寻找 bug 可以采取上空前绝后。

    修复NSLog()语句,如下所示:

    	NSLog(@"You tapped on: %@", sender);

    运行应用程序并再一次摁下按钮。NSLog()做什么它应该,但看起来好像你不会崩溃在buttonTapped:尚未。

    调试器和交朋友

    这个最新的崩溃,Xcode 指向线:

    	[self performSegueWithIdentifier:@"ModalSegue" sender:sender];

    在调试窗格中还有没有消息。像你以前,但也可以键入命令在调试器中得到错误消息,您可以按继续程序执行按钮。这样做的好处是应用程序在同一个地方可以呆在暂停。

    如果您正在运行这从模拟器,你可以键入后 (lldb) 提示以下内容:

    (lldb) po $eax

    LLDB 是默认调试器 Xcode 4.3 和起来。如果你使用的旧版本的 Xcode,然后你有了 GDB 调试器。他们分享一些基本的命令,所以如果你 Xcode 提示说 (gdb) 而不是 (lldb),你应该仍然能够跟着没有问题。(顺便说一句,你可以切换中的计划编辑器中 Xcode 下运行操作, 调试器。你可以访问计划编辑器通过 Alt 点击运行在你 Xcode 窗口左上角的图标)。

    蒲命令代表"打印对象"。$eax 符号指 CPU 寄存器之一。发生的异常,这个寄存器将包含指向 NSException 对象的指针。注: $eax 仅适用于模拟器,如果你需要使用的设备上调试注册 $r0。

    例如,如果您键入:

    (lldb) po [$eax class]

    您将看到这样的事情:

    (id) $2 = 0x01446e84 NSException

    这些数字不重要,但很明显你在处理一个 NSException 对象在这里。

    在此对象上,可以从 NSException 调用的任何方法。例如:

    (lldb) po [$eax name]

    这会给你这个案例的 NSInvalidArgumentException,异常的名称和:

    (lldb) po [$eax reason]

    这会给你的错误消息:

    (unsigned int) $4 = 114784400 Receiver (<MainViewController: 0x6b60620>) has no
    segue with identifier 'ModalSegue'

    注:当你只是做"po $eax"时,它将调用该对象上的"描述"方法和打印它,在这种情况下也给你的错误消息。

    这就解释了什么: 你正在尝试执行名为"ModalSegue"的界限,但显然 MainViewController 上有没有这种界限。

    情节提要并显示的继续存在,但你忘记了要设置它的标识符,一个典型的错误:

    Giving the segue an identifier.

    变化的界限标识符为"ModalSegue"。再次运行该应用程序 — — 等待它 — — 点击按钮。哎哟,这不更崩溃的时间!但这里是挑逗的我们接下来的部分 — — 表视图,其中显示了本不应该是空!


    跳转:应用程序崩溃定位查找 (二)

    展开全文
  • linux如何让一个程序崩溃后自动重启

    千次阅读 2020-03-19 16:39:17
    编写一个shell脚本,轮询监控应用的进程,如果出现崩溃进程不在的情况下,自动启动应用程序 touch restart.sh(新建...linux如何让一个程序崩溃后自动重启 chmod 777 restart.sh (赋予权限,默认-rw-rw-r–没有可执行...

    https://jingyan.baidu.com/article/39810a23a124dfb636fda612.html

    编写一个shell脚本,轮询监控应用的进程,如果出现崩溃进程不在的情况下,自动启动应用程序

    touch restart.sh(新建一个重启脚本)

    linux如何让一个程序崩溃后自动重启
    chmod 777 restart.sh (赋予权限,默认-rw-rw-r–没有可执行权限,不赋予权限脚本运行不了)

    执行玩chmod之后,权限已经改变-rwxrwxrwx

    linux如何让一个程序崩溃后自动重启
    vi restart.sh(编辑文件)

    循环每隔10秒查看下应用程序进程是否存在,不存在则启动应用,存在则睡眠10秒继续检测

    #!/bin/sh

    while true

    do

    ps -ef | grep “填入你自己的程序名” | grep -v “grep”

    if [ “$?” -eq 1 ]

    then

    ./run.sh #启动应用,修改成自己的启动应用脚本或命令

    echo “process has been restarted!”

    else

    echo “process already started!”

    fi

    sleep 10

    done

    linux如何让一个程序崩溃后自动重启
    ./restart.sh (启动脚本),启动完成之后,则可以看到每隔10秒打印一次“process already started!”,这个表示应用程序在运行不需要重启

    linux如何让一个程序崩溃后自动重启
    为了演示程序崩溃的情况,手动杀掉应用程序的进程

    linux如何让一个程序崩溃后自动重启
    杀完进程之后,再看刚刚启动的监控脚本打印日志情况,从图中可以看到,“process has been restarted!”,表示已经重启应用成功了。不确定的还可以自己去看下应用程序是否在运行

    linux如何让一个程序崩溃后自动重启步骤阅读
    END
    注意事项
    上面演示的是直接启动脚本,在退出会话的时候会停止,要使用nohup的方式启动监控脚本

    展开全文
  • 取消应用程序崩溃后弹出的对话框

    千次阅读 2016-09-23 15:18:04
    正常情况下,应用程序崩溃后,会弹出对话框,显示崩溃相关信息。有时候,用户并不希望出现这对话框,所以需要取消。  这里有两篇博文介绍了方法,经过验证有效:如何取消WIN2008下应用报错后弹出的对话框 程序已...

      正常情况下,应用程序崩溃后,会弹出对话框,显示崩溃相关信息。有时候,用户并不希望出现这个对话框,所以需要取消。

      这里有两篇博文介绍了方法,经过验证有效:如何取消WIN2008下应用报错后弹出的对话框 程序已停止 要求关闭程序关闭Windows 2008下面应用程序出错后的提示

      除此之外,还可以利用AeDebug进行配置,不弹出对话框,参考的是这篇文章:程序崩溃时利用注册表自动转储内存DMP

      我导出了注册表,直接导入就可以了:

    Windows Registry Editor Version 5.00
    
    [HKEY_CURRENT_USER\Software\Microsoft\Windows\Windows Error Reporting]
    "DontShowUI"=dword:00000001
    
    [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug]
    "UserDebuggerHotKey"=dword:00000000
    "Debugger"="exit"
    "Auto"="1"
    


    展开全文
  • MetaTrader是一款可编程的交易端(在其上编写的程序称为MQL程序),terminal.exe是MetaTrader的进程,MQL程序调用dll(VC++)进行网络通信(获取数据并显示在K线图表之上),在dll接口函数里开了一个线程等待并接收...
  • WINCE下如何诊断应用程序崩溃

    千次阅读 2012-07-22 22:59:31
    无论你是一个单纯的电脑用户还是一名高级软件工程师,都一定对程序崩溃不陌生。做为一名Windows CE应用程序开发者,你也一定遇到过下图这种场景: 这个对话框告诉你,有一个叫installer.exe的程序在地址00019320...

    无论你是一个单纯的电脑用户还是一名高级软件工程师,都一定对程序崩溃不陌生。做为一名Windows CE应用程序开发者,你也一定遇到过下图这种场景:

    这个对话框告诉你,有一个叫installer.exe的程序在地址00019320处崩溃了。如果这个程序归你负责,那么你的问题就来了:怎么找出这个BUG?这篇文章我想谈谈我在这方面的一些经验。
    Windows CE的崩溃界面给出的信息十分的少,其中最有用的无疑是崩溃地址,如果你能从崩溃地址定位到源代码去,这个问题可以说就解决了一半。
    从地址定位到源代码的方法有几种。一种是利用MAP文件:你可以在BUILD程序时生成MAP文件。MAP文件是一个文本文件,其中主要记录了各个函数入口对应的地址信息。比如这个例子中,崩溃地址对应的入口是:
    0001:000082f4 ??1?$CComPtr@UIImage@@@ATL@@QAA@XZ 000192f4 f i ImageViewer.obj

    MAP文件的好处是它是文本文件,可以人工阅读,缺点是信息不够多,只能定位到函数级别,而且要看懂MAP文件你需要有足够的经验,比如其中那串长长的貌似乱码的字符串是C++函数经过name mangling处理后的结果,没有一定的经验你根本没法还原出实际的函数。
    另一种方法是利用PDB文件,PDB文件收集了应用程序的调试符号。PDB文件提供的信息很全,不过你得需要一定的工具才能解读它。如果你是一个经验丰富的Windows桌面平台的应用程序开发者,你可能听说过MSJ(Microsoft System Journal)这本杂志。如果你曾经看过这本杂志,应该对Bugslayer不陌生。在这篇文章中,Bugslayer介绍了他做的一个工具:CrashFinder。CrashFinder可以从崩溃地址通过查询相应的PDB文件直接定位到导致崩溃的源代码行。幸运的是,由于Windows CE可执行程序及其PDB文件的格式和Windows桌面系统上的是一样的,因此CrashFinder也可以用来定位Windows CE程序的崩溃地址。下面是CrashFinder显示的结果:

    CrashFinder提供的信息十分有用,但是不够直观。为此我在Remote Process Explorer提供了一个更方便的界面,它可以直接显示源代码,并把导致崩溃的那一行highlight出来:

    PDB文件里包含着大量的调试信息可以帮助你诊断应用程序错误,因此一般来说即使是正式release的版本,你也应该生成并维护好这些PDB文件。使用PDB文件的关键是崩溃的应用程序和PDB文件一定要匹配,否则它不但不能帮到你,反而会误导你。下图是VS2005中设置生成PDB文件和MAP文件的地方:

    前面说过,Windows CE的崩溃界面给出的信息十分少,很多时候我们还需要更多的信息才能定位问题,另外有些Windows CE设备可能根本没有显示器。为解决这一问题,Windows CE在应用程序崩溃时还同时往外(一般是串口)输出相关的崩溃信息。比如这个例子中,如果你正好接着调试串口,开着HyperTerminal,那么在程序崩溃的时候你会看到这样的信息:

    Data Abort: Thread=8d661000 Proc=81a477c0 &apos;installer.exe&apos; 
    AKY=00000401 PC=00019320(installer.exe+0x00009320) RA=00019094(installer.exe+0x0 
    0009094) BVA=16080100 FSR=00000007

    我相信Windows CE开发者一定也对这几行信息很熟悉。怎么利用这些信息诊断程序的问题?这里面最关键的信息是PC和RA给出的地址信息。PC就是上面提到的崩溃地址,根据这个地址用CrashFinder或者我的Remote Process Explorer里的Crack Address界面可以定位到导致崩溃的源代码行;RA是PC的返回地址(Return Address),根据这个地址可以找到导致崩溃的上一级函数,这个信息也很重要,因为很多时候崩溃的原因往往是上层函数往底层函数传递了非法参数导致的,比如你的应用程序用一个非法的窗口类调用MFC函数,崩溃地址在MFC函数里面,但是出问题的地方在你的调用代码里。下图是RA地址对应的源代码:

    除了PC和RA,其他信息也可以提供一些参考作用:BVA是ARM中的Fault Address Register(FAR),是引起Data Abort的虚拟地址,比如说你的程序试图访问一个非法地址里的内容,那么Data Abort时BVA就是这个非法地址;FSR是Fault Status Register,指明导致异常的原因,FSR的解释可以看这里。要注意的是Thread和Proc给出的不是Thread Id/Thread Handle或者Process Id/Process Handle,它们给出的是该Thread或Proc对应的内核对象的指针,类似于Window NT平台的TEB和PEB的概念。由于你看到崩溃信息时线程已经退出了,因此根据这个信息在事后你无法知道是哪个线程出的错。以后我将介绍一种系统级的logging机制,这种机制可以把每条log的Thread Id、TEB等信息同时记录下来,这样在崩溃时就可以根据Data Abort的TEB信息和先前log中出现的TEB,找到出错的线程。这样,你不但可以定位到错误的源代码,还能找到运行错误代码的线程,将大大提高解决问题的效率。

    展开全文
  • iphone应用程序崩溃问题(

    千次阅读 2010-10-28 11:54:00
    iphone应用开发...下面就是一个崩溃问题。 Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<SendMessageViewController 0x24b260> setValue:forUndefinedKey:]: this clas
  • 如何诊断Windows CE的应用程序崩溃

    千次阅读 热门讨论 2008-07-15 18:06:00
    无论你是一个单纯的电脑用户还是一名高级软件工程师,都一定对程序崩溃不陌生。做为一名Windows CE应用程序开发者,你也一定遇到过下图这种场景:这个对话框告诉你,有一个叫installer.exe的程序在地址00019320处...
  • 我想请教一个问题哈,我的程序F5调试可以运行,Ctrl+F5也可以运行,但是生成的Debug和Release文件夹里面的应用程序就无法打开,程序直接崩溃了 ![图片说明]...
  • 用C++编了一个小软件,正常双击.exe可以打开,但是用cmd执行这个应用程序,软件就崩溃,请教这是为什么?
  • 你的应用程序是否经常被用户评价:崩溃、闪退、卡死,但是由于安卓机型的多样性和用户环境的复杂性,又很难甚至无法排查出应用程序的出错代码?又由于项目进度的原因不得不搁置,从而导致BUG不断累积最终导致用户...
  • 我的应用程序崩溃,现在怎么办? - 第1部分 要做的第件事是:不要惊慌! 固定崩溃并不需要是硬的。你可能恶化的情况下,如果你吓坏了,并开始改变的东西是随机的,希望这bug会奇迹般地消失,只要你说...
  • 当我点击应用程序的logo,闪屏后,就会从intent中调用的第一个类。但是当tab加载后, onPreExecute() 一旦执行,应用程序就奔溃了。 public class HomeActivity extends Activity{ private static final ...
  • 我们在开发应用程序时难免会遇到出现没有被try...catch抓住的RunTimeException信息,从而导致程序异常崩溃退出,大大的影响了用户体验。那么有没有什么方法能避免这现象呢?网上查资料,果然有,...
  • 大家在调试过程中,经常会遇见莫名其妙的程序崩溃,那我们应该怎么查看这些崩溃的详情呢? 经百度,有以下方法: 首先是编写两类 CrashApplication package com.example.endtwo; import android.app....
  • 问题描述Linux内存使用量超过阈值,使得Java应用程序无可用内存,最终导致程序崩溃。即使在程序没有挂掉时把程序停掉,系统内存也不会被释放。找原因的过程这问题已经困扰我好几月了,分析过好多次都没有找到...
  • 系统为WIN7,开发工具VS2010,应用程序在大部分电脑上运行正常,在台电脑上运行段时间总是报上述错误,然后崩溃。替换msvcr100这库还是不行,后来,不知道怎么回事,在这台电脑上可以正常运行了,但是最近在另...
  • 在《如何诊断Windows CE的应用程序崩溃》一文中我介绍了如何利用Remote Process Explorer的Crack Address功能定位程序的崩溃地址。但是看起来还是有很多人不知道怎么使用这工具,这篇文章详细介绍一下。首先要确保...
  • 对于windows管理员来说,进行问题诊断的最大挑战之一,是一个用户应用程序发生异常终止或者崩溃。因为崩溃或者终止的不连续性,想要捕捉到应用程序的误操作是非常困难的。其留下的寻找问题原因的线索也是非常少的。 ...
  • 《对“XXX::Invoke”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须这些委托保持活动状态,直到确信不会再次调用它们》的问题的解决方法
  • 可就在这时,前方技术支持来急电,用户使用过程中,程序core dump,要求开发人员紧急定位。经与用户交流,得知:在xxx操作下,问题可重现。于是,开发人员便打开几时万行的代码,检视与操作场景相关的部分,试图找到...
  • 1、在现场设置程序崩溃时的自动内存转储,得到dump文件  在windows 注册表如下项:  //HKEY_LOCAL_MACHINE/Software/Microsoft/Windows NT/CurrentVersion/AeDebug  中提供了调试器的相关设置。  Debugger...
  • C++程序崩溃解决方案

    千次阅读 2018-11-02 13:24:08
    C++程序崩溃如何进行异常捕获处理?特别是发布版本为Release版本,要想保留现场和复现就更加困难。本文较少几种捕获程序异常定位问题的方案。
  • 在我们的程序崩溃的时候,往往是不容易查找运行到哪一步出错了,或者是不容易查找崩溃的原因,这时候我们可以引进windows的api 来进行系统级别的崩溃日志收集,当应用程序崩溃时候自动生成.dump崩溃日志文件。...
  • 会先弹出对话框提示用户是否允许程序执行这些操作,如果用户选择允许则接下来的操作一切正常,如果用户选择拒绝之后,程序后面的工作将无法正常允许,甚至崩溃。  那么如何判断用户是拒绝还是允许了该权限呢?...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 234,566
精华内容 93,826
关键字:

如何让一个应用程序崩溃