About warning #15139

About warning #15139

Аватар пользователя dom_beau

Hello, I'm using Composer XE 2013.1.119. There is some code in assembler in our C++ projects and I get the following warning:

warning #15139: instruction saving a non-volatile register will not be unwound in the event of an exception.

Some of our functions/methods use a lot of assembler to speed up the process. But they generate this warning. I don't know how to solve it. I'm not sure about its signification. My guess is that the (assembler) instructions save a cpu register that is used to pass parameters. If these registers are modified, the program won't be able to unwind the call stack on an exception??? Am I right? If so, which registers are they? How to use them whithout generating this warning? Notice that I did not code these methods neither I'm a guru in __asm.

Thanks for you help!

Dominique

8 сообщений / 0 новое
Последнее сообщение
Пожалуйста, обратитесь к странице Уведомление об оптимизации для более подробной информации относительно производительности и оптимизации в программных продуктах компании Intel.
Аватар пользователя Sergey Kostrov

>>...I get the following warning:
>>
>>warning #15139: instruction saving a non-volatile register will not be unwound in the event of an exception.
>>
>>Some of our functions/methods use a lot of assembler to speed up the process. But they generate this warning. I don't know
>>how to solve it. I'm not sure about its signification. My guess is that the (assembler) instructions save a cpu register that is
>>used to pass parameters. If these registers are modified, the program won't be able to unwind the call stack on an exception?

Dominique,

It would be nice to see at least some piece of codes ( C, C++, assembler ), or a reproducer.

However, this is a Warning and it clearly informs that a Problem could occur in case of an Exception in that piece of codes. If you're unable to provide codes than every case when that Warning is displayed needs to be reviewed and investigated.

Sorry for a really generic response.

Аватар пользователя dom_beau

Hi,

I cannot send you a piece of code since it is the core of our software. But I found something interesting. Maybe you can confirm my suspicions. The warning occurs when there is:

__asm
push xxx

where xxx is a non-volatile register (RBX, R12-R15, RDI, RSI, RBP, RSP). I'm a newbie in assembler but maybe "pushing" a non-volatile register could forbid the stack to be unwound?

Аватар пользователя Sergey Kostrov

I'd like to repeat that every case when that Warning is displayed needs to be reviewed and investigated.

Аватар пользователя Sergey Kostrov

>>...If these registers are modified, the program won't be able to unwind the call stack on an exception??? Am I right? If so,
>>which registers are they?

Try to enable option that will create an assembler listing and review it ( you will see how registers are used / modified ).

Аватар пользователя Vyacheslav Zakharin (Intel)

Dominique,

Microsoft unwinding doesn't allow modification of the stack pointer (RSP) after fixed stack allocation happening on entry to a routine using RSP-base frame. There is just no way to specify such kind of action in the unwind tables.

For example, if your routine consists of the following instructions:
sub rsp, 40
call bar
;; inline asm begin
sub rsp, 4
<some code>
add rsp, 4
;; inline asm end
add rsp, 40
ret

A compiler won't be able to encode actions executed by "sub/add rsp, 4" into the unwind tables. Thus if <some code> generates an exception, RSP after the stack of this routine is unwinded will be off by 4, which may cause run-time problems in your program.

PUSH is just another instruction that decrements value of RSP register, so it may result in the same problems. And I agree that the warning message is misleading. There is another warning "#15138: instruction allocating stack space will not be unwound in the event of an exception" that describes the problem more accurately. We will try to fix this in one of next releases.

I would like to understand why you need to save original value of some non-volatile register. It shouldn't be required usually. If your code (either inline asm or C/C++ code) clobbers/changes original value of a non-volatile register, the compiler will save the original value on entry to the routine and restore it on exit. Along with that the compiler will generate proper unwinding tables containing information about how to restore the register in case of an exception. So you usually do not need to use explicit PUSH/POP instructions. Could you please explain why you need it?

Looking forward to your comments!

Thanks,
Slava

Аватар пользователя dom_beau

Hello Slava,

Many thanks for your help! My present job is to port a MSVS2005/ICC9.1 to MSVS2012/ICC13.0 solution with many projects. Many (new) warnings appeared will building the solution and I try to fix them because they can be very anoing (I got something like 20000 warnings!) Many of them are fixed now but this one remained a mystery. Now we solved it. I cannot tell you why the assembly code was like this because it was written long time ago by another developper. 

Thanks again,

Dominique

Аватар пользователя Vyacheslav Zakharin (Intel)

Hello Dominique,

I am glad to hear that you were able to rewrite your code and avoid the warning. Your program is more reliable now, which is what this warning was meant to help you to achive.

Thanks,
Slava

Зарегистрируйтесь, чтобы оставить комментарий.