将 C 包装在 C++ 中,只是为了 try/catch

发布于 2024-08-07 02:01:26 字数 289 浏览 2 评论 0原文

所以,我有一个很大的遗留软件,用 C 语言编码。它是针对嵌入式系统的,所以如果出现问题,比如除以零、空指针取消引用等,除了重新启动之外,没有什么可做的。

我想知道是否可以将 main() 实现为 c++ 并将其内容包装在 try/catch 中。这样,根据抛出的异常类型,我可以在重新启动之前记录一些调试信息。

嗯,因为有多个进程,所以我可能必须包装每个进程,而不仅仅是 main(),但我希望您明白我的意思...

是否值得让现有的 C 代码(几个 100 Klocs)保持不变,除了用 try/catch 包装它?

So, I have a big piece of legacy software, coded in C. It's for an embedded system, so if something goes wrong, like divide by zero, null pointer dereference, etc, there's not much to do except reboot.

I was wondering if I could implement just main() as c++ and wrap it's contents in try/catch. That way, depending on the type of exception thrown, I could log some debug info just before reboot.

Hmm, since there are multiple processes I might have to wrap each one, not just main(), but I hope that you see what I mean...

Is it worthwhile to leave the existing C code (several 100 Klocs) untouched, except for wrapping it with try/catch?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

风为裳 2024-08-14 02:01:26

除以零或空指针解除引用不会产生异常(使用 C++ 术语)。 C 甚至没有异常的概念。如果您使用的是类 UNIX 系统,您可能需要安装信号处理程序(SIGFPESIGSEGV 等)。

Division by zero or null pointer dereferencing don't produce exceptions (using the C++ terminology). C doesn't even have a concept of exceptions. If you are on an UNIX-like system, you might want to install signal handlers (SIGFPE, SIGSEGV, etc.).

风向决定发型 2024-08-14 02:01:26

由于它是一个嵌入式应用程序,因此可能仅在一个平台上运行。

如果是这样,为除零和其他硬异常安装适当的中断处理程序/内核陷阱处理程序可能会更简单且侵入性更小。

在大多数情况下,只需几行代码即可完成此操作。检查操作系统是否支持此类可安装的异常处理程序。如果您正在使用无操作系统的系统,则可以直接挂接异常期间调用的 CPU 中断。

Since it's an embedded application it probably runs only on one platform.

If so its probably much simpler and less intrusive to install a proper interrupt handler / kernel trap handler for the division by zero and other hard exceptions.

In most cases this can be done with just a few lines of code. Check if the OS supports such installable exception handlers. If you're working on an OS-less system you can directly hook the CPU interrupts that are called during exceptions.

戏舞 2024-08-14 02:01:26

首先,除以零或空指针取消引用不会引发异常。 Fpe 异常在 GNU C 库中通过信号 (SIGFPE) 实现。并且是 C99 标准的一部分,而不是 C++ 标准的一部分。

基于我在嵌入式 C 和 C++ 开发方面的经验的一些提示。取决于您的嵌入式操作系统:

  • 除非您完全确定自己在做什么,否则不要在线程之间尝试/捕获。仅在同一线程内。每个线程通常都有自己的堆栈。
  • 在遗留的 C 代码中间抛出并捕获,将会导致问题,因为例如,当您跳到正常程序流之外的 catch 块时,分配的内存可能不会被回收,因此您会出现严重的泄漏。比嵌入式系统中除以零或空指针取消引用更成问题。
  • 如果要使用异常,请将它们放入 C++ 代码中,并在构造函数中分配其他“C”资源并在析构函数中释放。
  • 在 C++ 层之上捕获它们。

First of all, divide by zero or null pointer dereference won't throw exceptions. Fpe exceptions are implemented in the GNU C library with signals (SIGFPE). And are part of the C99 standard, not the C++ standard.

A few hints based in my experience in embedded C and C++ development. Depending on your embedded OS:

  • Unless you are absolutely sure of what you are doing, don't try/catch between threads . Only inside the same thread. Each thread usually has its own stack.
  • Throwing in the middle of legacy C code and catching, is going to lead to problems, since for example when you have jumped to the catch block out of the normal program flow, allocated memory may not be reclaimed, thus you have leaks which is far more problematic than divide by zero or null pointer dereference in an embedded system.
  • If you are going to use exceptions, throw them inside your C++ code with allocation of other "C" resources in constructors and deallocation in destructors.
  • Catch them just above the C++ layer.
枕花眠 2024-08-14 02:01:26

我不认为从 C 编译的机器代码在异常方面做同样的事情,因为为 C++ 编译的机器代码“知道”异常。也就是说,我认为期望能够使用 C++ 构造从 C 代码中捕获“异常”是不正确的。 C 不会抛出异常,并且没有任何东西可以保证当 C 代码做了坏事时发生的错误会被 C++ 的异常机制捕获。

I don't think machine code compiled from C does the same thing with regard to exceptions, as machine code compiled for C++ which "knows" about exceptions. That is, I don't think it's correct to expect to be able to catch "exceptions" from C code using C++ constructs. C doesn't throw exceptions, and there's nothing that guarantees that errors that happen when C code does something bad are caught by C++'s exception mechanism.

溇涏 2024-08-14 02:01:26

除以零、空指针取消引用不是 C 或 C++ 异常,而是硬件异常。

在 Windows 上,如果使用 _set_se_translator(),您可以获得硬件异常,例如封装在普通 C++ 异常中的硬件异常。

__try/__catch 也可能有帮助。在MSDN上查找__try/__catch、GetExceptionCode()、_set_se_translator(),你可能会找到你需要的。

Divide by zero, null pointer dereference are not C or C++ exceptions they are hardware exceptions.

On Windows you can get hardware exceptions like these wrapped in a normal C++ exception if _set_se_translator() is used.

__try/__catch may also help. Look up __try/__catch, GetExceptionCode(), _set_se_translator() on MSDN, you may find what you need.

黑凤梨 2024-08-14 02:01:26

我想我记得研究过如何处理 SIGSEGV (通常在取消引用无效指针或除以 0 时生成),我在网上找到的一般建议是:什么都不做,让程序死掉。我认为正确的解释是,当您遇到 SIGSEGV 陷阱时,有问题的线程的堆栈已被废弃,无法修复。

有人可以评论这是否属实吗?

I think I remember researching on how to handle SIGSEGV ( usually generated when derefing invalid pointer, or dividing by 0 ) and the general advise I found on the net was: do nothing, let the program die. The explanation, I think a correct one, is that by the time you get to a SIGSEGV trap, the stack of the offending thread is trashed beyond repair.

Can someone comment if this is true?

秋凉 2024-08-14 02:01:26

仅适用于 msvc

               
__try
{

int p = 0;
p=p / 0;
}
__except (1)
{
printf("Division by 0 \n");
}

Only work on msvc

               
__try
{

int p = 0;
p=p / 0;
}
__except (1)
{
printf("Division by 0 \n");
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文