Is there a way for a program to know if it's executed under the simulator and not on an actual CPU?
Alright, here's my solution for LPC2xxx chips, in case anyone is interested. It is based on the fact that most flash programming tools modify the program image in such a way that the sum of all interrupt vectors in the boot block will be 0, whereas under the simulator the program is executed "as is", without any modification.
#include <stdint.h> #include <stdbool.h> bool in_simulator(void) { uint32_t sum = 0; uint32_t * p; for (p = 0; p < (uint32_t *)0x20; p++) sum += *p; return sum != 0; }
I doubt that anyone cares, but any criticism and suggestions are welcome :)
Hi, Very nice solution...
Do you have a trick also to know if the Ulink is connected(Debug) or when the CPU is stand alone (No Ulink)?
Thanks, Doron
It would be simple to put a sim script in that watched for a particular variable / address to be written then modify it, invert it, or something else specific as desired. You likely would have ignore the zero init of the variable.
In the application, write this item then read it back - treating it as volatile. If it reads back different than written, it would indicate simulator.
This should be quite generic and not rely on specifics of the CPU, build configuration, or simulator flaws (features ) that do not exactly match the CPU.
Chad,
Yes, this is a good idea too. Its big advantage is that it's CPU-independent (I think you could use it with the 8051 as well), but the disadvantage is that it depends on a script that you have to create for every program that uses it.
Cheers, Sandy
It is based on the fact that most flash programming tools modify the program image in such a way that the sum of all interrupt vectors in the boot block will be 0,
But that reasoning, what you're describing isn't what you said you wanted to have. It's a way to detect flash programming tools' checksumming of the vector table, not one to detect the simulator.
And of course, nothing stops the person configuring the simulator from implementing the same kind of checksumming either to the program itself, or as part of the debugger startup script, thus completely fooling your "detection".
The reasoning is that a program without a correct checksum wouldn't get executed on an real CPU in the first place. So if it still does, it is very likely that it is executed under the simulator. But I agree this isn't a 100% sure method and this is the reason why I invited suggestions from people :)
Of course, nothing stops the person from configuring the simulator in such a way, as well as nothing makes the person do so, particularly as "the person" in question is me :) I can't think of a situation where someone would easily change configuration of my simulator and make these settings permanent for all projects without me noticing it.
Besides, I would be interested to take a look at the actual steps to "fool" the program into thinking it's run on the real hardware (bit of a script or anything). Honestly speaking, I don't even know how it could be done at the moment.
In Cortex-M3
if(CoreDebug->DHCSR & 1) { // Debugging with ULIK or similar ! } else { // No debugging tool }
The CPU doesn't check the vector's checksum, that would have to be something else running on the core like a boot loader.
A more effective method would be to determine a hardware register that the simulator fails to accurately reflect that of real hardware. ie bits stuck at zero or one, due to lack of silicon defining a function, or bits that are random, toggle, or reflect some state in another register. I might look at clock enable registers, or those within timers, there are hundreds of targets in any given SoC implementation.
That's right. This check is only reliable on LPC2xxx-based ISP-programmable devices, all of which come with a boot loader.
This is something to think about but so far I see two problems with this:
1) As you yourself have said, there are hundreds of registers that the simulator supports, so determining one that it fails to accurately simulate would be like looking for a needle in the hay. Besides, I have no idea how exactly to do this.
2) Such an inaccuracy is not an officially supported feature and relying on such things is generally a bad idea. The developers may change the behaviour of that register in the next release and our check will turn out invalid.
Is there a way to get in touch with the simulator developers and ask them this question?
Given this isn't a gate level simulation, I'd think there are more needles than hay. It's a target rich environment that's been optimized for speed not authenticity. If documented features limit you, strap some wire or logic externally that the simulator couldn't possibly know about.
Why is this important anyway? And why do you need to rely on it?
Well, certainly it's not so important since I've found a solution to my particular problem :) But I'm surprised there's no general/official way to do this kind of check and nobody even cares about it! Before posting here I did some googling and found nothing, not even a single mention of the problem! I'm sure I'm not the first person to need this.
So, I hope some simulator experts might see this thread and shed some light :)
You did quote two questions.
But none of your own text did answer any of the two questions. We still don't know the answer to the "why"...
You mean why a program would need to know whether or not it's running under the simulator? I need that for debugging. I cannot use any of the debug adapters due to the specifics of our device, so I have to use the simulator extensively. And as the simulator doesn't support many of our peripherals, I have to turn off some program components when I want to debug some others. Basically, I have to implement two configurations for the program depending on where it's being executed.
Before posting here I did some googling and found nothing, not even a single mention of the problem!
You seem to have completely overlooked that the reason for nobody mentioning this problem might be that this is not a problem. That's a typical result of trying to hide the context of your request from the people you seek help from.
And as the simulator doesn't support many of our peripherals, I have to turn off some program components when I want to debug some others. Basically, I have to implement two configurations for the program depending on where it's being executed.
And if you had told us that right away, you would have got the solution to your actual problem much earlier, rather than not-quite-solutions to what you thought the problem was.
You do not need to do detect the simulator. You need to tell your program that it's running in the simulator. That's what multi-target projects and compiler switches are for. You just build a special version of the program tailored to working on the simulator, and that's that.
You just build a special version of the program tailored to working on the simulator, and that's that.
I have to agree with that. It's probably an error on his part and likely to be a one off.
This is inconvenient to me. I'm running the program on the device and when I see something go wrong I launch the program in the IDE - and it's the same program, I don't need to change 10+ switches and recompile it.
So I definitely knew what I was doing when I was asking how to detect the simulator and not how to use compiler switches :)