我有一个C ++程序,经验证的API用户(非交互式用户,因此这里没有重大的安全/完整性暴露)可以传递一个参数,该参数成为printf()的格式字符串(实际上,对于vsnprintf()) 。当然,糟糕的格式说明符会使程序爆炸。我已经记录了这一点并且它是可以接受的 - 但有没有办法捕获printf()错误而不是让C运行时断言?
环境几乎是标准的Posix(z / OS XLC,FWIW)。
感谢。
答案 0 :(得分:1)
使用sigsetjmp()/siglongjmp()
。
在使用可能错误的格式之前调用sigsetjmp()
,并为使用siglongjmp()
调用的上下文调用sigsetjmp()
的SIGSEGV和SIGBUS安装自定义处理程序。
请确保在不需要它们之后使用恢复信号处理程序,以免SIGSEGV在其他地方导致意外结果。
此处示例:
http://www-01.ibm.com/support/knowledgecenter/ssw_ibm_i_72/apis/sigsetj.htm
答案 1 :(得分:0)
请参阅BOOST格式库 - http://www.boost.org/doc/libs/1_58_0/libs/format/
格式库提供了一个类,用于根据格式字符串格式化参数,printf也是如此,但有两个主要区别:
format将参数发送到内部流,因此完全是类型安全的,并且自然支持所有用户定义的类型。
您可以在此库中使用C ++异常。
答案 2 :(得分:0)
我很想推荐一个简单的C ++风格的try / catch:
. . .
try
printf(...)
catch (...)
printf("An error happened handling your printf string!")
...
但我认为你试过这个并且有理由说它不能满足你的需求。
更深层的替代方案是LE条件处理程序 - 它本质上是一个回调例程,可以在发生异常时随时控制,并且它包含一种在错误发生后恢复执行的方法。阅读更多Googling CEEHDLR或查看"处理错误情况,异常和信号" XL C / C ++编程指南的一节。
在紧要关头,您还可以使用ESTAE / ESPIE宏将调用包装到printf()以在运行时看到之前捕获错误...是的,它需要几行汇编程序,但很多时候它会#39 ;这种方式可能更加细化。
祝你好运!
答案 3 :(得分:-1)
回答标题:
if(printf("...") < 0)
{
perror("printf error message");
exit;
}
添加。 工作示例
wchar_t wide[2];
wide[0] = 129;
wide[1] = 0;
if(printf("%ls", wide) < 0)
perror("detect error");