still reachable (false positive?) in custom exception - c++

This is my first attempt to write a custom exception class implementing a simple form of stack-trace.
This is the .h:
class error {
public:
error ();
error (const error & err);
~error ();
int level ();
private:
int _level;
};
And this is the .cpp:
error::error ()
: _level (0) {}
error::error (const error & err)
: _level (err._level) {}
error::~error () {}
int error::level () {
return ++_level;
}
Then I define two macros, one to create an error and throw it the first time (INIT_ERROR), and the other to kick the catched errors (KICK_ERROR):
#define WHERE(stream) {fprintf (stream, " %-30s [%s: %3d]\n", __FUNCTION__, __FILE__, __LINE__);}
#define INIT_ERROR {fprintf (stderr, "# 0"); WHERE (stderr); throw error ();}
#define KICK_ERROR {fprintf (stderr, "# %2d", err.level ()); WHERE (stderr); throw;}
As you expect, the use is as follow:
if (something wrong)
INIT_ERROR;
for the first time, and:
try {
// some code
}
catch (error & err) {
KICK_ERROR;
}
for all the other times.
However, DrMemory (I'm working on Windows Xp), alert me about still reachable blocks:
ERRORS FOUND:
0 unique, 0 total unaddressable access(es)
0 unique, 0 total uninitialized access(es)
0 unique, 0 total invalid heap argument(s)
0 unique, 0 total GDI usage error(s)
0 unique, 0 total warning(s)
0 unique, 0 total, 0 byte(s) of leak(s)
0 unique, 0 total, 0 byte(s) of possible leak(s)
3 unique, 3 total, 16 byte(s) of still-reachable allocation(s)
ERRORS IGNORED:
3 potential leak(s) (suspected false positives)
For completeness, this is the main:
void fun3 () {
fprintf (stderr, "nothing special");
INIT_ERROR;
}
void fun2 () {
try {
fun3 ();
}
catch (error & err) {
KICK_ERROR;
}
}
void fun1 () {
try {
fun2 ();
}
catch (error & err) {
KICK_ERROR;
}
}
int main () {
try {
fun1 ();
}
catch (error & err) {
cerr << "error catched in main" << endl;
}
}
Is this something wrong in my code?
Suggestions?

Still reachable allocations are not leaks, this is memory that is still available to the program at exit. It might be allocated from the libraries you use. I would not worry about them.

I don't think that there are any leaks. Your code seems valid. I think that the three blocks are just the allocated objects that were still alive at the precise point of time when program was starting its cleanup-on-death, if you might call that so.
I mean, something trivial like, std::cout, your exception and some lingering temporary string ;)
If you'd like to verify that, add a top-level TRY/CATCH at the most outer scope od MAIN that calls your exception test, so that the exception will be actually caught, stack unwound and so that the program will exit normally. That way, after catch/unwind, the lingering exception object and other should be cleaned up and probalby you will see LESS still-reachables.
Not necessarily zero, that depends on libraries used and the way that "DrMemory" of yours account for CRT "baseline memory footprint", sorry I don't know how to call that better..

Related

How can I maintain the call stack when I throw an exception from a thread in C++?

UPDATE 1
We run some large threads (threads with lots of code). We're not getting a reliable call stack that points us to the exception being thrown.
To make this example more reproducible and simpler, I boiled down the code to the following. I also removed the requirements of using /EHa and VS2013. This code is being compiled with VS2015 (v140) and default exception handling. I'm trying to figure out why the call stack doesn't ever seem to include the line that the std::runtime_error is thrown from.
#include <iostream>
#include <thread>
void myLongRunningMethod()
{
// Imagine lots of code here. We need to know where the exception
// is being thrown. Just knowing that it was thrown from this thread
// isn't sufficient.
std::cout << "..throwing from myLongRunningMethod()" << std::endl;
throw std::runtime_error("Test throw of std::runtime_error from thread"); // We would like to see this line in the call stack. We don't :(.
}
void main()
{
std::cout << "in main()" << std::endl;
// Spin up a thread and have it throw
std::cout << ".spinning up a thread" << std::endl;
std::thread t1(&myLongRunningMethod);
// Wait for thread to complete
std::cout << "...joining" << std::endl;
t1.join();
std::cout << "....join complete" << std::endl;
}
Output:
in main()
.spinning up a thread
..throwing from myLongRunningMethod()
...joining
Then I am presented with the abort() dialog. I click 'Retry'. Here is the callstack I get:
ucrtbased.dll!issue_debug_notification(const wchar_t * const message) Line 125 C++
ucrtbased.dll!__acrt_report_runtime_error(const wchar_t * message) Line 142 C++
ucrtbased.dll!abort() Line 51 C++
ucrtbased.dll!terminate() Line 59 C++
vcruntime140d.dll!FindHandler(EHExceptionRecord * pExcept, EHRegistrationNode * pRN, _CONTEXT * pContext, void * pDC, const _s_FuncInfo * pFuncInfo, unsigned char recursive, int CatchDepth, EHRegistrationNode * pMarkerRN) Line 714 C++
vcruntime140d.dll!__InternalCxxFrameHandler(EHExceptionRecord * pExcept, EHRegistrationNode * pRN, _CONTEXT * pContext, void * pDC, const _s_FuncInfo * pFuncInfo, int CatchDepth, EHRegistrationNode * pMarkerRN, unsigned char recursive) Line 439 C++
vcruntime140d.dll!__CxxFrameHandler(EHExceptionRecord * pExcept, EHRegistrationNode * pRN, void * pContext, void * pDC) Line 233 C++
ntdll.dll!ExecuteHandler2#20() Unknown
ntdll.dll!ExecuteHandler#20() Unknown
EhTestProject.exe!std::_Invoker_functor::_Call<void (__cdecl*)(void)>(void(*)() && _Obj) Line 1375 C++
EhTestProject.exe!std::_Pad::_Call_func(void * _Data) Line 209 C++
ucrtbased.dll!invoke_thread_procedure(unsigned int(__stdcall*)(void *) procedure, void * const context) Line 92 C++
ucrtbased.dll!thread_start<unsigned int (__stdcall*)(void *)>(void * const parameter) Line 115 C++
kernel32.dll!#BaseThreadInitThunk#12() Unknown
ntdll.dll!___RtlUserThreadStart#8() Unknown
ntdll.dll!__RtlUserThreadStart#8() Unknown
FURTHER UNDERSTANDING
I figured out why I was getting two dialog boxes (the main thread and the worker thread were each producing one). This was solved by adding a .join call to the main thread. Also, I do expect the thread to terminate on an unhandled exception (which explains why two of the three catch... blocks weren't getting entered).
ORIGINAL POST
Here's some code that isn't giving me the call stack I would expect and I'm unsure why. I've tried various combinations of try/catch without getting a full call stack.
I can't use the solution where std::current_exception is stored off
in a global because the threads in question are long running and we
don't join them to our main process.
We must use Async exception handling (/EHa), so a catch(...) block
will catch structured exceptions as well as standard exceptions, thus
treating all exceptions caught in a catch(...) block as fatal.
I can only use feautres supported by the v120 (2013) Microsoft C++ compiler.
Ideally, I want a full call stack to debug with. I'm having trouble figuring out why/how call stacks are being sliced.
// ------------------------------------------------------------
// Main.cpp
#include "OtherDll.h"
#include <iostream>
#include <memory>
#include <windows.h>
LPTOP_LEVEL_EXCEPTION_FILTER topLevelEF = nullptr;
static bool exceptionIsHandled = false;
LONG WINAPI UnhandledExceptionFilter(PEXCEPTION_POINTERS p)
{
std::cout << "....in UnhandledExceptionFilter (exceptionIsHandled = " << exceptionIsHandled << ")" << std::endl;
// Handle exception (in case the top-level try catch missed it)
return EXCEPTION_CONTINUE_SEARCH;
}
void main()
{
// Microsoft best practice is to call SetErrorMode()
::SetErrorMode(SEM_FAILCRITICALERRORS);
::SetThreadErrorMode(SEM_FAILCRITICALERRORS, nullptr);
// Setup the process global unhandled exception filter to be called for an unhandled exception occurs
topLevelEF = ::SetUnhandledExceptionFilter(UnhandledExceptionFilter);
std::cout << "in main()" << std::endl;
auto otherDll = std::make_unique<OtherDll>();
try
{
otherDll->throwStdRuntimeExceptionFromThread();
}
catch (...)
{
std::cout << "..caught(...) in main(). Rethrowing with throw." << std::endl;
exceptionIsHandled = true;
throw;
}
system("pause"); // Windows specific
}
// ------------------------------------------------------------
// OtherDll.h
#pragma once
#ifndef OTHERDLL_API
#define OTHERDLL_API
#endif
class OtherDll
{
public:
OTHERDLL_API OtherDll();
static OTHERDLL_API void throwStdRuntimeExceptionFromThread();
private:
static void myPrivateThrowMethod();
};
// ------------------------------------------------------------
// OtherDll.cpp
#define OTHERDLL_API __declspec(dllexport)
#include "OtherDll.h"
#include <thread>
#include <iostream>
OtherDll::OtherDll()
{
std::cout << "..in OtherDll CTOR" << std::endl;
}
void OtherDll::throwStdRuntimeExceptionFromThread()
{
try
{
std::cout << "....calling thread to throw from try" << std::endl;
std::thread t1(&OtherDll::myPrivateThrowMethod);
}
catch (...)
{
std::cout << "......in catch(...)" << std::endl;
// handle exception
throw; //crash the process
}
}
void OtherDll::myPrivateThrowMethod()
{
try
{
std::cout << "......throwing from thread try" << std::endl;
throw std::runtime_error("Test from thread");
}
catch (...)
{
std::cout << "......caught by thread catch(...). Rethrowing." << std::endl;
throw; // must always rethrow because catching SEH (like access violations that are unrecoverable)
}
}
Output:
in main()
..in OtherDll CTOR
....calling thread to throw from try
......throwing from thread try
......caught by thread catch(...). Rethrowing.
At this point a 'Microsoft Visual C++ Runtime Library' dialog pops up telling me that abort() has been called. I click Retry to debug the application. I then get the next line of output from my program:
....in UnhandledExceptionFilter (exceptionIsHandled = 0)
To add to my confusion, sometimes I get two of the aforementioned VisualC++ dialog boxes. Also, sometimes (very rarely)...it does give me the call stack I would expect. Here are the two call stacks I'll get:
99% of the time (not helpful):
msvcr120d.dll!_NMSG_WRITE(int rterrnum) Line 226 C
msvcr120d.dll!abort() Line 62 C
msvcr120d.dll!terminate() Line 97 C++
msvcp120d.dll!_Call_func(void * _Data) Line 39 C++
msvcr120d.dll!_callthreadstartex() Line 376 C
msvcr120d.dll!_threadstartex(void * ptd) Line 359 C
kernel32.dll!#BaseThreadInitThunk#12() Unknown
ntdll.dll!___RtlUserThreadStart#8() Unknown
ntdll.dll!__RtlUserThreadStart#8() Unknown
1% of the time (good stack):
MSVCR120D.dll!_NMSG_WRITE(int rterrnum) Line 226 C
MSVCR120D.dll!abort() Line 62 C
MSVCR120D.dll!terminate() Line 97 C++
OtherDll.dll!std::thread::~thread() Line 56 C++
OtherDll.dll!OtherDll::throwStdRuntimeExceptionFromThread() Line 47 C++
EhTestProject.exe!main() Line 47 C++

How to implement an exception handler with stack trace in C++ [duplicate]

I want to have a way to report the stack trace to the user if an exception is thrown. What is the best way to do this? Does it take huge amounts of extra code?
To answer questions:
I'd like it to be portable if possible. I want information to pop up, so the user can copy the stack trace and email it to me if an error comes up.
Andrew Grant's answer does not help getting a stack trace of the throwing function, at least not with GCC, because a throw statement does not save the current stack trace on its own, and the catch handler won't have access to the stack trace at that point any more.
The only way - using GCC - to solve this is to make sure to generate a stack trace at the point of the throw instruction, and save that with the exception object.
This method requires, of course, that every code that throws an exception uses that particular Exception class.
Update 11 July 2017: For some helpful code, take a look at cahit beyaz's answer, which points to http://stacktrace.sourceforge.net - I haven't used it yet but it looks promising.
It depends which platform.
On GCC it's pretty trivial, see this post for more details.
On MSVC then you can use the StackWalker library that handles all of the underlying API calls needed for Windows.
You'll have to figure out the best way to integrate this functionality into your app, but the amount of code you need to write should be minimal.
If you are using Boost 1.65 or higher, you can use boost::stacktrace:
#include <boost/stacktrace.hpp>
// ... somewhere inside the bar(int) function that is called recursively:
std::cout << boost::stacktrace::stacktrace();
I would like to add a standard library option (i.e. cross-platform) how to generate exception backtraces, which has become available with C++11:
Use std::nested_exception and std::throw_with_nested
This won't give you a stack unwind, but in my opinion the next best thing.
It is described on StackOverflow here and here, how you can get a backtrace on your exceptions inside your code without need for a debugger or cumbersome logging, by simply writing a proper exception handler which will rethrow nested exceptions.
Since you can do this with any derived exception class, you can add a lot of information to such a backtrace!
You may also take a look at my MWE on GitHub, where a backtrace would look something like this:
Library API: Exception caught in function 'api_function'
Backtrace:
~/Git/mwe-cpp-exception/src/detail/Library.cpp:17 : library_function failed
~/Git/mwe-cpp-exception/src/detail/Library.cpp:13 : could not open file "nonexistent.txt"
Unix: backtrace
Mac: backtrace
Windows: CaptureBackTrace
If you are using C++ and don't want/can't use Boost, you can print backtrace with demangled names using the following code [link to the original site].
Note, this solution is specific to Linux. It uses GNU's libc functions backtrace()/backtrace_symbols() (from execinfo.h) to get the backtraces and then uses __cxa_demangle() (from cxxabi.h) for demangling the backtrace symbol names.
// stacktrace.h (c) 2008, Timo Bingmann from http://idlebox.net/
// published under the WTFPL v2.0
#ifndef _STACKTRACE_H_
#define _STACKTRACE_H_
#include <stdio.h>
#include <stdlib.h>
#include <execinfo.h>
#include <cxxabi.h>
/** Print a demangled stack backtrace of the caller function to FILE* out. */
static inline void print_stacktrace(FILE *out = stderr, unsigned int max_frames = 63)
{
fprintf(out, "stack trace:\n");
// storage array for stack trace address data
void* addrlist[max_frames+1];
// retrieve current stack addresses
int addrlen = backtrace(addrlist, sizeof(addrlist) / sizeof(void*));
if (addrlen == 0) {
fprintf(out, " <empty, possibly corrupt>\n");
return;
}
// resolve addresses into strings containing "filename(function+address)",
// this array must be free()-ed
char** symbollist = backtrace_symbols(addrlist, addrlen);
// allocate string which will be filled with the demangled function name
size_t funcnamesize = 256;
char* funcname = (char*)malloc(funcnamesize);
// iterate over the returned symbol lines. skip the first, it is the
// address of this function.
for (int i = 1; i < addrlen; i++)
{
char *begin_name = 0, *begin_offset = 0, *end_offset = 0;
// find parentheses and +address offset surrounding the mangled name:
// ./module(function+0x15c) [0x8048a6d]
for (char *p = symbollist[i]; *p; ++p)
{
if (*p == '(')
begin_name = p;
else if (*p == '+')
begin_offset = p;
else if (*p == ')' && begin_offset) {
end_offset = p;
break;
}
}
if (begin_name && begin_offset && end_offset
&& begin_name < begin_offset)
{
*begin_name++ = '\0';
*begin_offset++ = '\0';
*end_offset = '\0';
// mangled name is now in [begin_name, begin_offset) and caller
// offset in [begin_offset, end_offset). now apply
// __cxa_demangle():
int status;
char* ret = abi::__cxa_demangle(begin_name,
funcname, &funcnamesize, &status);
if (status == 0) {
funcname = ret; // use possibly realloc()-ed string
fprintf(out, " %s : %s+%s\n",
symbollist[i], funcname, begin_offset);
}
else {
// demangling failed. Output function name as a C function with
// no arguments.
fprintf(out, " %s : %s()+%s\n",
symbollist[i], begin_name, begin_offset);
}
}
else
{
// couldn't parse the line? print the whole line.
fprintf(out, " %s\n", symbollist[i]);
}
}
free(funcname);
free(symbollist);
}
#endif // _STACKTRACE_H_
HTH!
AFAIK libunwind is quite portable and so far I haven't found anything easier to use.
I recommend http://stacktrace.sourceforge.net/ project. It support Windows, Mac OS and also Linux
Since the stack is already unwound when entering the catch block, the solution in my case was to not catch certain exceptions which then lead to a SIGABRT. In the signal handler for SIGABRT I then fork() and execl() either gdb (in debug builds) or Google breakpads stackwalk (in release builds). Also I try to only use signal handler safe functions.
GDB:
static const char BACKTRACE_START[] = "<2>--- backtrace of entire stack ---\n";
static const char BACKTRACE_STOP[] = "<2>--- backtrace finished ---\n";
static char *ltrim(char *s)
{
while (' ' == *s) {
s++;
}
return s;
}
void Backtracer::print()
{
int child_pid = ::fork();
if (child_pid == 0) {
// redirect stdout to stderr
::dup2(2, 1);
// create buffer for parent pid (2+16+1 spaces to allow up to a 64 bit hex parent pid)
char pid_buf[32];
const char* stem = " ";
const char* s = stem;
char* d = &pid_buf[0];
while (static_cast<bool>(*s))
{
*d++ = *s++;
}
*d-- = '\0';
char* hexppid = d;
// write parent pid to buffer and prefix with 0x
int ppid = getppid();
while (ppid != 0) {
*hexppid = ((ppid & 0xF) + '0');
if(*hexppid > '9') {
*hexppid += 'a' - '0' - 10;
}
--hexppid;
ppid >>= 4;
}
*hexppid-- = 'x';
*hexppid = '0';
// invoke GDB
char name_buf[512];
name_buf[::readlink("/proc/self/exe", &name_buf[0], 511)] = 0;
ssize_t r = ::write(STDERR_FILENO, &BACKTRACE_START[0], sizeof(BACKTRACE_START));
(void)r;
::execl("/usr/bin/gdb",
"/usr/bin/gdb", "--batch", "-n", "-ex", "thread apply all bt full", "-ex", "quit",
&name_buf[0], ltrim(&pid_buf[0]), nullptr);
::exit(1); // if GDB failed to start
} else if (child_pid == -1) {
::exit(1); // if forking failed
} else {
// make it work for non root users
if (0 != getuid()) {
::prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0);
}
::waitpid(child_pid, nullptr, 0);
ssize_t r = ::write(STDERR_FILENO, &BACKTRACE_STOP[0], sizeof(BACKTRACE_STOP));
(void)r;
}
}
minidump_stackwalk:
static bool dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor, void* context, bool succeeded)
{
int child_pid = ::fork();
if (child_pid == 0) {
::dup2(open("/dev/null", O_WRONLY), 2); // ignore verbose output on stderr
ssize_t r = ::write(STDOUT_FILENO, &MINIDUMP_STACKWALK_START[0], sizeof(MINIDUMP_STACKWALK_START));
(void)r;
::execl("/usr/bin/minidump_stackwalk", "/usr/bin/minidump_stackwalk", descriptor.path(), "/usr/share/breakpad-syms", nullptr);
::exit(1); // if minidump_stackwalk failed to start
} else if (child_pid == -1) {
::exit(1); // if forking failed
} else {
::waitpid(child_pid, nullptr, 0);
ssize_t r = ::write(STDOUT_FILENO, &MINIDUMP_STACKWALK_STOP[0], sizeof(MINIDUMP_STACKWALK_STOP));
(void)r;
}
::remove(descriptor.path()); // this is not signal safe anymore but should still work
return succeeded;
}
Edit: To make it work for breakpad I also had to add this:
std::set_terminate([]()
{
ssize_t r = ::write(STDERR_FILENO, EXCEPTION, sizeof(EXCEPTION));
(void)r;
google_breakpad::ExceptionHandler::WriteMinidump(std::string("/tmp"), dumpCallback, NULL);
exit(1); // avoid creating a second dump by not calling std::abort
});
Source: How to get a stack trace for C++ using gcc with line number information? and Is it possible to attach gdb to a crashed process (a.k.a "just-in-time" debugging)
on linux with g++ check out this lib
https://sourceforge.net/projects/libcsdbg
it does all the work for you
On Windows, check out BugTrap. Its not longer at the original link, but its still available on CodeProject.
I have a similar problem, and though I like portability, I only need gcc support. In gcc, execinfo.h and the backtrace calls are available. To demangle the function names, Mr. Bingmann has a nice piece of code. To dump a backtrace on an exception, I create an exception that prints the backtrace in the constructor. If I were expecting this to work with an exception thrown in a library, it might require rebuilding/linking so that the backtracing exception is used.
/******************************************
#Makefile with flags for printing backtrace with function names
# compile with symbols for backtrace
CXXFLAGS=-g
# add symbols to dynamic symbol table for backtrace
LDFLAGS=-rdynamic
turducken: turducken.cc
******************************************/
#include <cstdio>
#include <stdexcept>
#include <execinfo.h>
#include "stacktrace.h" /* https://panthema.net/2008/0901-stacktrace-demangled/ */
// simple exception that prints backtrace when constructed
class btoverflow_error: public std::overflow_error
{
public:
btoverflow_error( const std::string& arg ) :
std::overflow_error( arg )
{
print_stacktrace();
};
};
void chicken(void)
{
throw btoverflow_error( "too big" );
}
void duck(void)
{
chicken();
}
void turkey(void)
{
duck();
}
int main( int argc, char *argv[])
{
try
{
turkey();
}
catch( btoverflow_error e)
{
printf( "caught exception: %s\n", e.what() );
}
}
Compiling and running this with gcc 4.8.4 yields a backtrace with nicely unmangled C++ function names:
stack trace:
./turducken : btoverflow_error::btoverflow_error(std::string const&)+0x43
./turducken : chicken()+0x48
./turducken : duck()+0x9
./turducken : turkey()+0x9
./turducken : main()+0x15
/lib/x86_64-linux-gnu/libc.so.6 : __libc_start_main()+0xf5
./turducken() [0x401629]
Poppy can gather not only the stack trace, but also parameter values, local variables, etc. - everything leading to the crash.
The following code stops the execution right after an exception is thrown. You need to set a windows_exception_handler along with a termination handler. I tested this in MinGW 32bits.
void beforeCrash(void);
static const bool SET_TERMINATE = std::set_terminate(beforeCrash);
void beforeCrash() {
__asm("int3");
}
int main(int argc, char *argv[])
{
SetUnhandledExceptionFilter(windows_exception_handler);
...
}
Check the following code for the windows_exception_handler function:
http://www.codedisqus.com/0ziVPgVPUk/exception-handling-and-stacktrace-under-windows-mingwgcc.html
Cpp-tool ex_diag - easyweight, multiplatform, minimal resource using, simple and flexible at trace.
A working example for OSX (tested right now on Catalina 10.15). Not portable to linux/windows obviously. Probably it will be usefull to somebody.
In the "Mew-exception" string you can use backtrace and/or backtrace_symbols functions
#include <stdexcept>
#include <typeinfo>
#include <dlfcn.h>
extern "C" void __cxa_throw(void *thrown_object, std::type_info *tinfo, void (*dest)(void *));
static void (*__cxa_throw_orig)(void *thrown_object, std::type_info *tinfo, void (*dest)(void *));
extern "C" void luna_cxa_throw(void *thrown_object, std::type_info *tinfo, void (*dest)(void *))
{
printf("Mew-exception you can catch your backtrace here!");
__cxa_throw_orig(thrown_object, tinfo, dest);
}
//__attribute__ ((used))
//__attribute__ ((section ("__DATA,__interpose")))
static struct replace_pair_t {
void *replacement, *replacee;
} replace_pair = { (void*)luna_cxa_throw, (void*)__cxa_throw };
extern "C" const struct mach_header __dso_handle;
extern "C" void dyld_dynamic_interpose(const struct mach_header*,
const replace_pair_t replacements[],
size_t count);
int fn()
{
int a = 10; ++a;
throw std::runtime_error("Mew!");
}
int main(int argc, const char * argv[]) {
__cxa_throw_orig = (void (*)(void *thrown_object, std::type_info *tinfo, void (*dest)(void *)))dlsym(RTLD_DEFAULT, "__cxa_throw");
dyld_dynamic_interpose(&__dso_handle, &replace_pair, 1);
fn();
return 0;
}

How to use DrMemory to display and report a memory leak in C++?

I am trying to use DrMemory as it seems to be an easy to use Windows Memory Leaking detection tool: http://www.drmemory.org/
I purposely created the c++ app below that might have a memory leak.
#include <iostream>
using namespace std;
class Dog{
public:
int a;
string b;
Dog()
{
a = 1;
b = "alfred";
}
~Dog()
{
}
};
class Example{
public:
Dog* d1;
Dog* d2;
string a;
int b;
Example()
{
a = "test";
b = 15;
d1 = new Dog();
d2 = new Dog();
}
~Example()
{
//delete d;
}
};
void createObjects(){
for(unsigned int i=0; i < 200; i++)
{
Dog* d = new Dog();
Example* b = new Example();
}
Dog* d = new Dog();
d = NULL;
Example* b = new Example();
b = NULL;
}
int main()
{
createObjects();
return 0;
}
After building this app along with the following options (as instructed by DrMemory documentation) "-ggdb -static-libgcc -static-libstdc++" , I executed the executable with drmemory.exe, like this:
drmemory.exe TestingDrMemory.exe
However, I am not seeing any error/log message related to the memory leak and I am unable to identify the line in the source code that this occurs. Is this possible in DrMemory? What is the correct way to use this in order to identify/detect lines in the source code that cause the memory leak?
The log is below:
Dr. Memory version 1.7.0 build 5 built on Apr 4 2014 23:38:05
Dr. Memory results for pid 18240: "TestingDrMemory.exe"
Application cmdline: "TestingDrMemory.exe"
Recorded 104 suppression(s) from default C:\Program Files (x86)\Dr. Memory\bin\suppress-default.txt
===========================================================================
FINAL SUMMARY:
DUPLICATE ERROR COUNTS:
SUPPRESSIONS USED:
NO ERRORS FOUND:
0 unique, 0 total unaddressable access(es)
0 unique, 0 total uninitialized access(es)
0 unique, 0 total invalid heap argument(s)
0 unique, 0 total GDI usage error(s)
0 unique, 0 total handle leak(s)
0 unique, 0 total warning(s)
0 unique, 0 total, 0 byte(s) of leak(s)
0 unique, 0 total, 0 byte(s) of possible leak(s)
0 unique, 0 total, 0 byte(s) of still-reachable allocation(s)
ERRORS IGNORED:
2 potential error(s) (suspected false positives)
(details: C:\Dr. Memory\DrMemory-TestingDrMemory.exe.18240.000\potential_errors.txt)
18 potential leak(s) (suspected false positives)
(details: C:\Dr. Memory\DrMemory-TestingDrMemory.exe.18240.000\potential_errors.txt)
Details: C:\Dr. Memory\DrMemory-TestingDrMemory.exe.18240.000\results.txt
From the drmemory.org
If your application links with a static library that was built with frame pointer optimizations and you observe missing frames on your callstacks, try running with the Dr. Memory runtime options -no_callstack_use_top_fp, -no_callstack_use_fp, and -callstack_conservative. These will add some additional overhead on malloc-intensive applications, but should eliminate skipped frames.
Try running drmem with -batch -no_callstack_use_fp -no_callstack_use_top_fp

LuaPlus: How to make a function return a table?

I'm wondering how I you can create and register a function from the C++-side that returns a table when called from the Lua-side.
I've tried a lot of things but nothing did really work. :/
(sorry for the long code)
This for example won't work, because Register() expects a "luaCFunction"-styled function:
LuaPlus::LuaObject Test( LuaPlus::LuaState* state ) {
int top = state->GetTop();
std::string var( state->ToString(1) );
LuaPlus::LuaObject tableObj(state);
tableObj.AssignNewTable(state);
if (var == "aaa")
tableObj.SetString("x", "ABC");
else if (var == "bbb")
tableObj.SetString("x", "DEF");
tableObj.SetString("y", "XYZ");
return tableObj;
}
int main()
{
LuaPlus::LuaState* L = LuaPlus::LuaState::Create(true);
//without true I can't access the standard libraries like "math.","string."...
//with true, GetLastError returns 2 though (ERROR_FILE_NOT_FOUND)
//no side effects noticed though
LuaPlus::LuaObject globals = L->GetGlobals();
globals.Register("Test",Test);
char pPath[MAX_PATH];
GetCurrentDirectory(MAX_PATH,pPath);
strcat_s(pPath,MAX_PATH,"\\test.lua");
if(L->DoFile(pPath)) {
if( L->GetTop() == 1 ) // An error occured
std::cout << "An error occured: " << L->CheckString(1) << std::endl;
}
}
When I try to set it up as a luaCFunction-function it just crashes (0x3) and says:
Assertion failed: 0, file C:\......\luafunction.h, line 41
int Test( LuaPlus::LuaState* state ) {
int top = state->GetTop();
std::string var( state->ToString(1) );
LuaPlus::LuaObject tableObj(state);
tableObj.AssignNewTable(state);
if (var == "aaa")
tableObj.SetString("x", "ABC");
else if (var == "bbb")
tableObj.SetString("x", "DEF");
tableObj.SetString("y", "XYZ");
tableObj.Push();
return state->GetTop() - top;
}
For clarification: from the Lua side I wanted it to be callable like:
myVar = Test("aaa")
Print(myVar) -- output: ABC
EDIT: The Print function comes from here. And was basically the cause for this to not work. Print can only print strings not tables... The C++ code from above works fine if you just return 1.
This is the documentation that came with my LuaPlus version btw: http://luaplus.funpic.de/
I really hope you can help me.. I'm already starting to think that it is not possible. :'(
edit:
I totally forgot to say that using PushStack() lead into an error because "the member does not exist"...
After some painstaking probing from the long comment discussion, I'm posting this answer to help summary the situation and hopefully to offer some useful advice.
The main issue the OP was running into was that the wrong print function was being called in the lua test script. Contrary to the original code shown the real code the OP was testing against was calling Print(myVar) which is a custom provided lua_CFunction and not the builtin print function.
Somehow along the way, this ended up creating some instantiation of template <typename RT> class LuaFunction and calling the overloaded operator()(). From inspecting the luafunction.h from luaPlus any lua errors that occurs inside this call will get swallowed up without any kind of logging (not a good design decision on luaPlus's part):
if (lua_pcall(L, 0, 1, 0)) {
const char* errorString = lua_tostring(L, -1); (void)errorString;
luaplus_assert(0);
}
To help catch future errors like this, I suggest adding a new luaplus_assertlog macro. Specifically, this macro will include the errorString so that the context isn't completely lost and hopefully help with debugging. This change hopefully won't break existing uses of luaplua_assert from other parts of the API. In the long run though, it's probably better to modify luaplus_assert so it actually includes something meaningful.
Anyway here's a diff of the changes made:
LuaPlusInternal.h
## -81,5 +81,6 ##
} // namespace LuaPlus
#if !LUAPLUS_EXCEPTIONS
+#include <stdio.h>
#include <assert.h>
#define luaplus_assert(e) if (!(e)) assert(0)
## -84,5 +85,6 ##
#include <assert.h>
#define luaplus_assert(e) if (!(e)) assert(0)
+#define luaplus_assertlog(e, msg) if (!(e)) { fprintf(stderr, msg); assert(0); }
//(void)0
#define luaplus_throw(e) assert(0)
//(void)0
LuaFunction.h
## -21,7 +21,7 ##
class LuaFunction
{
public:
- LuaFunction(LuaObject& _functionObj)
+ LuaFunction(const LuaObject& _functionObj)
: functionObj(_functionObj) {
}
## -36,7 +36,7 ##
if (lua_pcall(L, 0, 1, 0)) {
const char* errorString = lua_tostring(L, -1); (void)errorString;
- luaplus_assert(0);
+ luaplus_assertlog(0, errorString);
}
return LPCD::Type<RT>::Get(L, -1);
}
In the change above, I opted not to use std::cerr simply because C++ streams tend to be heavier than plain-old C-style io functions. This is especially true if you're using mingw as your toolchain -- the ld linker is unable to eliminate unused C++ stream symbols even if your program never uses it.
With that in place, here's an example where an unprotected call is made to a lua function so you can see the errorString printed out prior to the crash:
// snip...
int main(int argc, const char *argv[])
{
LuaStateAuto L ( LuaState::Create(true) );
LuaObject globals = L->GetGlobals();
globals.Register("Test", Test);
globals.Register("Print", Print);
if(argc > 1)
{
/*
if (L->DoFile(argv[argc - 1]))
std::cout << L->CheckString(1) << '\n';
/*/
L->LoadFile( argv[argc - 1] );
LuaFunction<int> f ( LuaObject (L, -1) );
f();
//*/
}
}
Running the above will trigger the crash but will include a semi-helpful error message:
g++ -Wall -pedantic -O0 -g -I ./Src -I ./Src/LuaPlus/lua51-luaplus/src plustest.cpp -o plustest.exe lua51-luaplus.dll
plustest.exe plustest.lua
plustest.lua:2: bad argument #1 to 'Print' (string expected, got table)Assertion failed!
Program: G:\OSS\luaplus51-all\plustest.exe
File: ./Src/LuaPlus/LuaFunction.h, Line 39
Expression: 0
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
first you may try to register the function using RegisterDirect(), this may avoid lua_CFunction's problem, check the luaplus manual.like this
LuaPlus::LuaObject globals = L->GetGlobals();
globals.RegisterDirect("Test",Test);
second if I remeber to create a table have two solutions,like this
//first
LuaObject globalsObj = state->GetGlobals();
LuaObject myArrayOfStuffTableObj = globalsObj.CreateTable("MyArrayOfStuff");
//second
LuaObject aStandaloneTableObj;
aStandaloneTableObj.AssignNewTable(state);
check whether you have use the right function.
third I remember the lua stack object is not the luaobject, they have a conversion, may be you can try this
LuaStackObject stack1Obj(state, 1);
LuaObject nonStack1Obj = stack1Obj;
forth, like the function Test() you have give above, the table tableObj you have pushing onto the lua stack, you must remember to clear the object.

Allocating big space in C++ OS X

I'm learning exceptions in C++ and I was trying this:
int main(int argc, char* argv[]) {
double *p_x;
try {
p_x = new double[100000000000000];
delete p_x;
} catch (bad_alloc& ex) {
cout << "Memory not allocated !!\n";
}
return 0;
}
The exception gets caught but there's other stuff printed when executing this code. The output looks like:
Memory not allocated !!
Test9(13814) malloc: *** mmap(size=800000000000000) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
I don't know if it's somehow related to the version of g++ or maybe related to the OS X.
I mean, the program is catching the exception but what is the other stuff about?
It's glibc related. You can disable these messages with the mallopt(3) command:
mallopt(M_CHECK_ACTION, 0);