Is there a way to configure cppcheck with ability to specify positional argument number for alloc/dealloc - static-analysis

I work with the following functions:
flist_create(flist *cont) - allocates memory for an instance of
structure
flist_destroy(flist *cont) - deallocates memory
flist_put(flist *cont, char *val) - transfers memory ownership of val
to cont (flist_destroy will later free that memory, as part of cleaning up cont)
For the flist itself, I can just do:
<memory>
<alloc>flist_create</alloc>
<dealloc>flist_destroy</dealloc>
</memory>
But, I can't add flist_put as dealloc (for freeing up the value), as cppcheck will think that flist should be freed up).
Is there any way to configure cppcheck to tell it that only specified positional argument should be considered for dealloc?

After looking at the source code of cppcheck I found the answer:
<memory>
<alloc>flist_create</alloc>
<dealloc>flist_destroy</dealloc>
<dealloc arg="2">flist_put</dealloc>
</memory>
I find cppcheck manual to be somewhat lacking, as it doesn't have all possible use of cfg files documented...

Related

gsoap memory leak C applications

We are using gsoap for C client and server webservices implemented for blackfin running Linux.
We don't use any malloc in the application. But we see memory usage climbs over time. We are using soap_end to do a cleanup at the end of the call. But when the calls are invoked repeatedly memory usage slowly increasing, may be because of memory fragmentation. This is also impacting performance of the system
What's the preferred usage of gsoap where soap_malloc is not used much. For eg: If we use static arrays etc will it help?
Thanks,
nkr
I would not recommend using static data, there is no need for that.
To debug memory use, compile all your sources files with -DDEBUG. When you run your application you will see three files:
SENT.log the messages sent
RECV.log the messages received
TEST.log the debug log
The TEST.log is useful to check on messaging issues.
The other valuable information produced at runtime are error messages related to memory leaks or heap memory that is damaged (e.g. overruns) in your code. It is unlikely these will happen in the gSOAP engine, but better check.
To ensure proper allocation and deallocation of managed data:
soap_destroy(soap);
soap_end(soap);
I am using the auto-generated functions to allocate managed data:
SomeClass *obj = soap_new_SomeClass(soap);
and sporadically use soap_malloc for raw managed allocation, or to allocate an array of pointers, or a C string:
const char *s = soap_malloc(soap, 100);
but better is to allocate strings with:
std::string *s = soap_new_std__string(soap);
and arrays can be allocated with the second parameter, e.g. an array of 10 strings:
std::string *s = soap_new_std__string(soap, 10);
All managed allocations are deleted with soap_destroy() followed by soap_end(). After that, you can start allocating again and delete again, etc.
If you want to preserve data that otherwise gets deleted with these calls, use:
soap_unlink(soap, obj);
Now obj can be removed later with delete obj. But be aware that all pointer members in obj that point to managed data have become invalid after soap_destroy() and soap_end(). So you may have to invoke soap_unlink() on these members or risk dangling pointers.
A new cool feature of gSOAP is to generate deep copy and delete function for any data structures automatically, which saves a HUGE amount of coding time:
SomeClass *otherobj = soap_dup_SomeClass(NULL, obj);
This duplicates obj to unmanaged heap space. This is a deep copy that checks for cycles in the object graph and removes such cycles to avoid deletion issues. You can also duplicate the whole (cyclic) managed object to another context by using soap instead of NULL for the first argument of soap_dup_SomeClass.
To deep delete:
soap_del_SomeClass(obj);
This deletes obj but also the data pointed to by its members, and so on.
To use the soap_dup_X and soap_del_X functions use soapcpp2 with options -Ec and -Ed, respectively.
In principle, static and stack-allocated data can be serialized just as well. But consider using the managed heap instead.
Hope this helps.

What is the use of flag PF_MEMALLOC

When I am browsing some code in one device driver in linux, I found the flag PF_MEMALLOC is being set in the thread (process). I found the definition of this flag in header file, which saying that "Allocating Memory"
#define PF_MEMALLOC 0x00000800 /* Allocating memory */
So, my doubt here is, what exactly the use of this flag when set it in a process/thread like code current->flags |= PF_MEMALLOC;
This flag is used within the kernel to indicate a thread that is current executing with a memory-allocation path, and therefore is allowed to recursively allocate any memory it requires ignoring watermarks and without being forced to write out dirty pages.
This is to ensure that if the code that is attempting to free pages in order to satisfy an original allocation request itself has to allocate a small amount of memory to proceed, that code won't then recursively try to free pages.
Most drivers should not require this flag.

Delete dynamically allocated memory twice?

First I'd like to point out that I'm using a GNU GCC compiler. I'm using Code::Blocks as my IDE so I don't have to type in all the compiler junk into the Windows DOS command prompt. If I could be more specific about my compiler, what shows up as a line at the bottom of Cod::Blocks when I successfully compile is
mingw32-g++.exe -std=c++11 -g
Anyways, my question involves using the delete operator to release dynamically allocated memory. When I compile this code snippet:
int* x;
x = new int;
delete x;
delete x;
I don't get any warnings or errors or crashes. From the book I'm learning C++ from, releasing a pointer to a dynamically allocated memory chuck can only be done once, then the pointer is invalid. If you use delete on the same pointer again, then there will be problems. However, I don't get this problem.
Likewise, if I pass an object by value to a function, so that it is shallow copied, I get no error if I don't have a copy constructor to ensure deep copy (using raw pointers in the object). This means that when the function returns, the shallow copy goes out of scope, and invokes its destructor (where I'm using delete on a pointer). When int main returns, the original object goes out of scope, its destructor is invoked, and that same shallow copied pointer is deleted. But I have no problems.
I tried finding documentation online about the compiler I'm using and couldn't find any. Does this mean that the mingw32 compiler has some sort of default copy constructor it uses? Thus, I don't have to worry about creating copy constructors?
The compiler documentation is not likely to be helpful in this case: If it exists, it is likely to list exceptions to the C++ spec. It's the C++ spec that you need here.
When you delete the same pointer twice, the result--according to the C++ spec--is undefined. The compiler could do anything at all and have it meet spec. The compiler is allowed to recognize the fault and give an error message, or not recognize the fault and blow up immediately or sometime later. That your compiler appeared to work this time is no indication that the double delete is safe. It could be mucking up the heap in a way that results in a seg fault much later.
If you do not define a copy constructor, C++ defines one for you. The default copy constructor does a memberwise copy.
When you have the same object pointed to by multiple pointers, such as you do, consider using std::smart_ptr.

COM memory management

I have some questions regarding COM memory management:
I have a COM method:
STDMETHODIMP CWhitelistPolicy::GetWebsitesStrings(SAFEARRAY** result)
result = SAFEARRAY(BSTR). If I receive another SAFEARRAY(BSTR) from another interface method(in order to set *result) do I have to make copies of the strings received in order to pass them to *result and outside client? Or considering I will not use the strings for myself I can just pass them to the client (and passing out the ownership)?
2.
STDMETHODIMP CWhitelistPolicy::SetWebsitesStrings(SAFEARRAY* input)
Here I receive a BSTR array as input. Again my method is responsible for the memory allocated in input?
3.
STDMETHOD(SetUsers)(SAFEARRAY* input);
Here I call a method on another interface (SetUsers) and I allocate memory for the input SAFEARRAY. After I call SetUsers I can dispose of the SAFEARRAY? Memory is always copied when marshaling takes place isn't it? (in my case SetUsers method is called on an interface that is hosted as a COM DLL inside my process)
The way I think about it to answer questions like this is to think about a COM call that crosses machines. Then it's obvious for an [out] param; I the caller own and have to free the memory because the remote marshaling layer can't do it. For [in] parameters, it's obvious the marshaling layer must copy my data and again the remote marshaling layer can't free what I passed in.
A core tenet in COM is location neutrality, the rules when calling in the same apartment are the rules when using DCOM across machines.
You're responsible to free - you don't pass ownership when you call the next fnc because it could be remote and getting a copy, not your original data.
No - as the callee, you don't have to free it. If it's intra-apartment, it's the memory the caller provided and the caller has to free it. If it's a remote call, the server stub allocates it and will free it when the method returns.
Yes, you free it - no, it's not always copied (it might be), which is why the answer to 2 is no. If it's copied, there's a stub that allocated and the stub will free it.
Note my answers to your questions didn't cover the case of [in,out] parameters - see the so question Who owns returned BSTR? for some more details on this case.
Com allocation rules are complicated but rational. Get the book "essential com" by Don Box if you want to understand/see examples of all the cases. Still you're going to make mistakes so you should have a strategy for detecting them. I use gflags (part of Windbg) and its heap checking flags to catch when a double free occurs (a debug message is displayed and execution halted at the call with an INT 3). Vstudio's debugger used to turn them on for you when it launched the executable (it likely still does) but you can force them on with gflags under the image options tab.
You should also know how to use UMDH (also part of windbg) to detect leaks. DebugDiag is the newer tool for this and seems easier to use, but sadly, you can only have the 32 bit or 64 bit version installed, but not both.
The problem then are BSTRs, which are cached, make detecting double frees and leaks tricky because interacting with the heap is delayed. You can shut off the ole string cache by setting the environment variable OANOCACHE to 1 or calling the function SetOaNoCache. The function's not defined in a header file so see this SO question Where is SetOaNoCache defined?. Note the accepted answer shows the hard way to call it through GetProcAddress(). The answer below the accepted one shows all you need is an extern "C" as it's in the oleaut32 export lib. Finally, see this Larry Osterman blog post for a more detailed description of the difficulties caused by the cache when hunting leaks.

Fixed Memory I don't need to allocate?

I just need a fixed address in any win32 process, where I can store 8 bytes without using any winapi function. I also cannot use assembler prefixes like fs:. and I have no stack pointer.
What I need:
-8 bytes of memory
-constant address and present in any process
-read and write access (via pointer, from the same process)
-should not crash the application (at least not instantly) if modified.
Don't even ask, why I need it.
The only way I'm aware of to do this is to use a DLL with a shared section...
// This goes in a DLL loaded by all apps that want to share the data
#pragma data_seg (".sharedseg")
long long myShared8Bytes = 0; // has to be initialized or this fails
#pragma data_seg()
Then, you add the following to the link command for the dll:
/SECTION:sharedseg,RWS
I am also curious why you want this...
Not that I recommend this, but the PEB probably has some unused or inconsequential fields in it that you could overwrite. I still think this is a terrible idea, though.
constant address and present in any
process
You won't be able to achieve that. Win32 uses paged memory so different processes can access the same memory addresses even though it is different memory.

Resources