细分错误-如何调试?

时间:2018-09-07 04:35:35

标签: linux debugging segmentation-fault

我的应用程序崩溃了,并在控制台上打印了以下内容:

  

sh [366]:/ bin / sh:第1行:367分段错误(核心已转储)。/myapp

我的问题是367在这里表示什么?

我在任何地方都找不到核心转储文件。
有什么线索可以在这种情况下调试分段错误吗?

3 个答案:

答案 0 :(得分:5)

367是进程ID(程序段错误)的进程ID。您可以在function* watch() { while (true) { try { yield call(delay,10000); yield call(getAllFromServer); } catch (error) { yield put(actions.setErrorInStore(error)); } } } function* watchPoll() { while (true) { yield take(actionType.WATCH_START); yield race([ call(watch), take(actionType.WATCH_PAUSE), take(actionType.WATCH_STOP) ]); } } export function* sagasNotificationWatcher() { yield takeLatest(actionType.GET_NOTIFICATIONS, getAllFromServer); yield takeLatest(actionType.GET_CURRENT_NOTIFICATION, setCurrent); yield takeEvery(actionType.SET_HIDDEN, setHidden); yield takeEvery(actionType.HIDE_SINGLE, hideSingleSelected); yield takeEvery(actionType.SET_READ, setStatus); yield takeEvery(actionType.SET_UNREAD, setStatus); yield throttle(1500, actionType.SEARCH_NOTIFICATIONS, getAllFromServer); yield takeLatest(actionType.SHOW_UNREAD, getAllFromServer); yield takeEvery(actionType.SET_FILTERS, getAllFromServer); yield takeEvery(actionType.SET_SEARCH_MODULE, getAllFromServer); yield call(watchPoll) // if i pass in this call just watch, then this works, but if watchPoll it's stopping on yield call(delay,10000); }调试器下运行程序。

先阅读How To Debug Small Programs,然后阅读documentation of gdb。考虑也使用valgrind

  

任何线索在这种情况下如何调试分段错误?

如果该故障可以重现,则非常简单。在gdb

下运行程序
  

我在任何地方都找不到核心转储文件。

请仔细阅读core(5)(和getrlimit(2);也许核心转储已被某些gdb bash内置函数禁用)。您的系统可能已配置(请参见proc(5))以其他方式转储内核(例如,通过systemd(1),可能在ulimit下)。可能看到coredumpctl(1)systemd-coredump(8)coredump.conf(5)

在编译应用程序with /var/lib/systemd/coredump/时,请不要忘记启用所有警告和调试信息(当然,可以改进代码以完全不发出警告)。

答案 1 :(得分:3)

通常,我调试分段错误的第一步是:

  1. 使用调试符号(-g选项)编译应用程序,但保留优化选项以避免太多改动

  2. gdb下运行gdb --args ./myprog,然后在命令提示符下运行r下的程序

如果幸运的话,程序崩溃了,请键入bt(回溯)以查看它在哪个函数中崩溃,从哪个函数中调用,依次类推直至主程序(或线程启动)。

如果可能的话,一个更好的选择是在valgrind下运行可执行文件,以查看它首先被发现的“不良”行为是什么。在许多情况下,做坏事情(例如在数组边界之外进行读取或写入操作)不会立即产生段错误,valgrid会向您显示在您无权访问的位置上的首次读取或写入操作(可以在程序正常执行时静默地“工作”)。使用valgrind的缺点是执行速度非常慢,因为该程序基本上是使用仿真处理器运行的;它是如此之慢,以至于可能无法在预期的上下文中运行该程序(例如,因为它需要与可能会超时的设备通信)。

另一个选择是使用地址清理器(-fsanitize=address)编译程序。这将在可执行文件本身中添加代码,以检查边界之外的内存访问或释放的内存。优点是,尽管执行速度仍然比常规的非插入式可执行文件慢,但比在valgrind下运行程序要快得多。

答案 2 :(得分:1)

如果核心转储不可用,GDB甚至可以使用.exe文件进行调试。

target exec -- Use an executable file as a target

以这种方式使用它:

(gdb) target exec a.exe