Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.

About warning #15139

dom_beau
Beginner
616 Views

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

0 Kudos
7 Replies
SergeyKostrov
Valued Contributor II
616 Views
>>...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.
0 Kudos
dom_beau
Beginner
616 Views

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:

[cpp]

__asm

push xxx

[/cpp]

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?

0 Kudos
SergeyKostrov
Valued Contributor II
616 Views
I'd like to repeat that every case when that Warning is displayed needs to be reviewed and investigated.
0 Kudos
SergeyKostrov
Valued Contributor II
616 Views
>>...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 ).
0 Kudos
Vyacheslav_Z_Intel
616 Views

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

0 Kudos
dom_beau
Beginner
616 Views

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

0 Kudos
Vyacheslav_Z_Intel
616 Views

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

0 Kudos
Reply