I wonder that how to disable address sanitizer insert checking function when memory access.
As I know that address sanitizer pass insert the checking function to detect out of access or buffer overflow..etc.[(https://github.com/llvm/llvmproject/blob/main/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp) ]
I want to disable that address sanitizer insert the checking function.
Is there any flag to disable to insert checking function?
Or, How to disable address sanitizer code to check?
Thank you!
Have a nice day :)
I expect to check the code line in AddressSanitizer.cpp
You can't disable different parts of the instrumentation independently - the instrumentation is done holistically both to check memory accesses and maintain the relevant metadata. If you want to track metadata similar to Address Sanitizer but w/o its checking, you'd have to write a new sanitizer pass to implement that.
However, you can disable Address Sanitizer on a more granular basis. For example, you con link together files where some are compiled with -fsanitize=address and some are not. You can also disable it using a function attribute:
https://clang.llvm.org/docs/AddressSanitizer.html#disabling-instrumentation-with-attribute-no-sanitize-address
You can see this in action here:
https://cpp.compiler-explorer.com/z/rj95nKMY8
#include <iostream>
__attribute__((no_sanitize("address")))
int uninstrumented_access(int* array, int index) {
return array[index];
}
int access(int* array, int index) {
return array[index];
}
int main() {
int *array = new int[10]();
(void)uninstrumented_access(array, 42);
std::cerr << "No ASan error from un-instrumented access due to attribute!\n";
(void)access(array, 42);
std::cerr << "No ASan error even from instrumented access!\n";
}
Here, uninstrumented_access disables all of the ASan checks. If you look at the Compiler Explorer output, you'll see that there is no ASan error from that function, but the normal version of it does produce an error.
Related
When I compile and run the below piece of code the exe crashes yet doesn't provide information of any sort regarding why it crashed. (Seg faults etc. not reported). Here is the sample code that I tried:
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector <int> values;
int temp = values.back();
cout << temp << endl;
return 0;
}
The same piece of code when compiled and run-on Linux produce a seg fault. Is there something to be configured specifically in windows to let console applications generate information regarding runtime errors?
Calling std::vector::back on an empty vector is undefined behavior. The compiler or runtime aren't required to emit a diagnostic. There might be a tool or sanitizer that could help depending on the compiler you're using.
Is there something to be configured specifically in windows to let console applications generate information regarding runtime errors?
The problem is that value.back() causes undefined behavior (because your vector is empty). The effect of undefined behavior is undefined. It might result in a seg fault, but also could just exit the application. You can't enforce a segfault for that, and not really enforce a crash.
Using static analyzers and increasing the warning level can help in certain cases. But there is no way to detect all possible errors.
Let's start with a minimal working example:
main.cpp:
#include <iostream>
#include <string>
int main() {
std::cout << "hello " + std::to_string(42);
return 0;
}
I compile this code using the following flags:
[g++/clang++] -std=c++11 -g -Og --coverage -Wall -o main main.cpp
clang 4.0.1
gcc 4.8.5.
I get only 50% code coverage, since the compiler generates exception code, which is not executed, as explained in another stackoverflow question.
The problem is that disabling exceptions via -fno-exceptionsis not an option for me. The code I am writing unit tests for uses exceptions, so disabling all of them is not an option.
In order to generate a report I'm using gcovr, in case of clang++ additionally llvm-cov gcovto convert it. But I am not bound to these tools, so if you have other tools that do not show this behaviour please suggest them!
Basically I need a way to compile/write unit tests for this code and get 100% branch / conditional coverage with exceptions enabled. Is there a way?
Well, I believe your intention is not actually test this small piece of code, but use the concept in a project...
The code you entered throws an exception - bad_alloc is thrown when you have no memory left to store the string that will be created with std::to_string. To be 100% safe, std::to_string should be surrounded with try-catch, where you could handle your exception.
To build a 100% code coverage unit test, you will need to force the exception to happen - in this specific case it is almost impossible to guarantee, since the parameter is a constant number. But, in your project, you probably have some data to be allocated whose size is variable - in this case, you can isolate in your code the methods that allocate memory, to test them separately. Then you pass to these methods, in the test function, a huge amount to be allocated to evaluate what you have put on your catch block (and check if you are handling it properly).
For instance, this code should throw the exception, you could use it to inspire yourself when building your tests (source):
// bad_alloc.cpp
// compile with: /EHsc
#include<new>
#include<iostream>
using namespace std;
int main() {
char* ptr;
try {
ptr = new char[(~unsigned int((int)0)/2) - 1];
delete[] ptr;
}
catch( bad_alloc &ba) {
cout << ba.what( ) << endl;
}
}
However, if you are not planning to handle all bad_alloc exceptions (or absolutely all exceptions) in your code, there is no way to get 100% coverage - since it won't be 100% covered... Most of the cases, true 100% coverage is unnecessary, though.
In the following code snippet there is an error that is not trivial but I would have expected tools like AddressSanitizer to catch it.
#include <vector>
#include <iostream>
int main ()
{
std::vector<int> toto;
toto.push_back(2);
int const& titi = toto[0];
toto.pop_back();
std::cout << titi << std::endl;
return 1;
}
When scopping the vector and printing outside of the scope the catch reference an error is thrown use-heap-after-free.
But when there is no scope, the std::vector implementation will probably not release the memory after the pop_back thus the reference is still pointing towards valid memory.
I have search around and I found that you can manually poison memory and I was wondering if this has been implemented in STL (https://github.com/google/sanitizers/wiki/AddressSanitizerManualPoisoning)
This has been implemented in Clang (libc++) and relatively recent GNU (libstdc++) STLs (see Asan wiki for details).
One problem with this feature is that it breaks separate sanitization i.e. ability to sanitize only parts of your app (e.g. only executable and not the libs). The issue is that if vector is pushed in unsanitized and popped in sanitized code, the pusher will not be aware that it needs to unpoison the buffer. For this reason it's disabled by default in GCC (define _GLIBCXX_SANITIZE_VECTOR to enable it), Clang still has it one by default for unclear reasons.
I have two empty functions called TestFunc and TestFunc2, and I assigned their addresses to two variables.
void TestFunc()
{
}
__declspec(naked) void TestFunc2()
{
}
int main()
{
DWORD* test = (DWORD*)TestFunc;
DWORD* test2 = (DWORD*)TestFunc2;
printf("TestFunc is %p at test is %p\n", TestFunc, test);
printf("TestFunc2 is %p at test2 is %p\n", TestFunc2, test2);
getchar();
}
After assignment, the value of the two variables actually differ from what they are assigned.
However, in a printf statement, the output shows that they are the same. Any ideas why is this happening?
This is caused by incremental linking in Visual Studio, from this page you can learn that one of the drawbacks of this is:
An incrementally linked program is functionally equivalent to a program that is non-incrementally linked. However, because it is prepared for subsequent incremental links, an incrementally linked executable, static library, or dynamic-link library file:
Is larger than a non-incrementally linked program because of padding of code and data. Padding enables the linker to increase the size of functions and data without recreating the file.
May contain jump thunks to handle relocation of functions to new addresses.
and those jump thunks is what your have observed.
if you disable this option (vs2015):
Linker -> All Options -> Enable Incremental Linking to NO
then your addresses will be equal.
If you look closer in disassembly what is at the address which you have assigned to DWORD*, you will find that there is a jump to your function:
TestFunc:
000000014001117C jmp TestFunc (01400116D0h)
It has to do with the platform specific runtime environment your code is compiled to. C++ allows the runtime to do some pointer arithmetics behind the scene. It is dangerous to write any code that relies on this runtime behaviour.
If you really want to know, take a look at the assembler code at the memory. My guess would be that the runtime uses an extra jump table perhaps for the new edit and continue debug functionality that is improved/changed with each release of visual studio.
I have some c++ code but I don't know what. For the purposes of example let's say it is:
//main.cpp
#include<iostream>
using namespace std;
int T[100];
int main()
{
for(int i = 0; i < 100; ++i)
T[i] = i;
int x;
cin>>x;
cout<<T[x]<<endl;
return 0;
}
I'm compiling it by cl /O2 /nologo /EHsc main.cpp and running by main < inFile.in. Let's say that inFile.in content is one number 500 and new line. The output is some random number because program reads memory under the address T+500 and printing it.
I want to get runtime error in such cases (any possibility of checking is something like this happened). Is this possible without access to main.cpp?
To be specific I'm running all this programmatically by Process class in C# in ASP.Net MVC Application. I want to check did program threw exception / read not reserved memory etc.
Is this a feature you want to use for development purposes only, or also in your production environment?
In case of development purposes only you may try to run your application under some tool for runtime checking (like Valgrind/Dr Memory), or change the way you compile it to include runtime debug checks (is not guaranteed to work in described case, but helps in many others). Keep in mind that this will make your application much slower (thus should be used only for applications under development)
When it comes to production environment, I am not aware of any way of doing what you want to - in general you can only count on OS segmentation fault in case of reading out of available memory (if you have luck - if you don't it'll "work").
For the exception thing, I'm not 100% sure I understand what you mean - is this "why did the program terminate" ? In such case on you might get a core dump of crashed application (in case of normal termination I assume you have return codes), and you can inspect it later to either get crash reason or possibly also try to recover some data. For instructions how to collect dumps on Windows, you may check out:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb787181%28v=vs.85%29.aspx
However, this is also a feature that is more useful in development environment than in production.
If You can't modify above program's source then run it in 'outside' environment (shell) and get returned value and test it against 0 - any other value would me incorrect behavior.
It is also good to verify such programs' input data that you know it can't handle so rather than waiting for it to crash you can prevent it from happening.
If You could modify program then simple solution would be to use std::vector or std::deque which are similar but important is to use at() method and not the operator[] operator as the at() method checks bounds
#include<iostream>
#include<vector>
using namespace std;
std::vector<int> T(100);
int main()
{
for(int i = 0; i < 100; ++i)
T[i] = i;
int x;
cin>>x;
cout<<T.at(x)<<endl;
return 0;
}
if at() will be called with bad out-of-bound parameter then exception will be throw which You can catch like this:
try{
cin>>x;
cout<<T.at(x)<<endl;
}
catch(...)
{
cout << "exception while accessing vector's data" << endl;
}