I am writing a CHIP-8 interpreter in C++ with SDL2. The source code is at https://github.com/robbie0630/Chip8Emu. There is a problem where it gets a segmentation fault with this ROM. I tried to debug the problem with GDB, but when I type bt, it displays an incomplete stack trace, only showing the top two functions, making me unable to effectively diagnose the problem. How do I get a full and useful stack trace?
EDIT: When I run bt, GDB displays this:
#0 0x0000000101411a14 in ?? ()
#1 0x0000000000406956 in Chip8_CPU::doCycle (this=0x7fffffffc7b0) at /my/home/code/Chip8Emu/src/cpu.cpp:223
#2 0x0000000000402080 in main (argc=2, argv=0x7fffffffe108) at /my/home/code/Chip8Emu/src/main.cpp:152
This is useless because ?? does not indicate anything, and line 223 of cpu.cpp is a function call.
EDIT 2: I ran valgrind on the program, and here is the output:
==11791== Conditional jump or move depends on uninitialised value(s)
==11791== at 0x406BA0: Chip8_CPU::doCycle() (cpu.cpp:215)
==11791== by 0x4020EF: main (main.cpp:152)
==11791==
==11791== Jump to the invalid address stated on the next line
==11791== at 0x101411A74: ???
==11791== by 0x4020EF: main (main.cpp:152)
==11791== Address 0x101411a74 is not stack'd, malloc'd or (recently) free'd
==11791==
==11791==
==11791== Process terminating with default action of signal 11 (SIGSEGV)
==11791== Access not within mapped region at address 0x101411A74
==11791== at 0x101411A74: ???
==11791== by 0x4020EF: main (main.cpp:152)
==11791== If you believe this happened as a result of a stack
==11791== overflow in your program's main thread (unlikely but
==11791== possible), you can try to increase the size of the
==11791== main thread stack using the --main-stacksize= flag.
==11791== The main thread stack size used in this run was 8388608.
==11791==
==11791== HEAP SUMMARY:
==11791== in use at exit: 7,827,602 bytes in 41,498 blocks
==11791== total heap usage: 169,848 allocs, 128,350 frees, 94,139,303 bytes allocated
==11791==
==11791== LEAK SUMMARY:
==11791== definitely lost: 0 bytes in 0 blocks
==11791== indirectly lost: 0 bytes in 0 blocks
==11791== possibly lost: 4,056,685 bytes in 36,878 blocks
==11791== still reachable: 3,770,917 bytes in 4,620 blocks
==11791== suppressed: 0 bytes in 0 blocks
==11791== Rerun with --leak-check=full to see details of leaked memory
==11791==
==11791== For counts of detected and suppressed errors, rerun with: -v
==11791== Use --track-origins=yes to see where uninitialised values come from
==11791== ERROR SUMMARY: 12 errors from 3 contexts (suppressed: 0 from 0)
Killed
EDIT 3: I ran GDB again, this time watching GfxDraw, and I noticed this happened:
Old value = (void (*)(array2d)) 0x1411bc4
New value = (void (*)(array2d)) 0x101411bc4
Chip8_CPU::doCycle (this=0x7fffffffc7a0) at /home/robbie/code/Chip8Emu/src/cpu.cpp:213
(gdb) cont
Continuing.
Thread 1 "Chip8Emu" received signal SIGSEGV, Segmentation fault.
0x0000000101411bc4 in ?? ()
So somehow GfxDraw is getting modified to an invalid function pointer. I can't figure out where it is modified, however.
After a few months, I finally identified the problem. Some nasty CHIP-8 programs make illegal memory accesses to the graphics memory that are outside of the bounds of the array and corrupt properties of the CPU (such as GfxDraw). I fixed this problem by accessing the graphics memory with at and ignoring std::out_of_range errors. It seems to work for now, so I'm declaring it the solution.
Related
I'm working on a C++ application (an OpenSSL assignment for university), and I'm running it through valgrind, as one does. I've noticed some rather strange output when the program fails due to invalid input:
==1739== HEAP SUMMARY:
==1739== in use at exit: 588 bytes in 6 blocks
==1739== total heap usage: 52 allocs, 46 frees, 99,206 bytes allocated
==1739==
==1739== 44 bytes in 1 blocks are possibly lost in loss record 3 of 6
==1739== at 0x483BE63: operator new(unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==1739== by 0x4C20378: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28)
==1739== by 0x4C03187: std::logic_error::logic_error(char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28)
==1739== by 0x4C0325C: std::invalid_argument::invalid_argument(char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28)
==1739== by 0x10FB6D: lab2::cryptoEngine::CBCCryptoEngine::encrypt() (CBCCryptoEngine.cpp:39)
==1739== by 0x10E355: main (main.cpp:135)
==1739==
==1739== 144 bytes in 1 blocks are possibly lost in loss record 4 of 6
==1739== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==1739== by 0x4BDB1F3: __cxa_allocate_exception (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28)
==1739== by 0x10FB5B: lab2::cryptoEngine::CBCCryptoEngine::encrypt() (CBCCryptoEngine.cpp:39)
==1739== by 0x10E355: main (main.cpp:135)
==1739==
==1739== LEAK SUMMARY:
==1739== definitely lost: 0 bytes in 0 blocks
==1739== indirectly lost: 0 bytes in 0 blocks
==1739== possibly lost: 188 bytes in 2 blocks
==1739== still reachable: 400 bytes in 4 blocks
==1739== of which reachable via heuristic:
==1739== stdstring : 44 bytes in 1 blocks
==1739== suppressed: 0 bytes in 0 blocks
==1739== Reachable blocks (those to which a pointer was found) are not shown.
==1739== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==1739==
==1739== For lists of detected and suppressed errors, rerun with: -s
The code causing it is just a regular exception that is thrown when an input file is invalid. The exception is caught properly like this:
try {
engine.encrypt(bad_argument); // Placeholder. The exception type stands, though...
}
catch (const std::invalid_argument &e) {
std::cerr << "Exception while encrypting file: " << e.what() << std::endl;
delete (engine);
exit(EXIT_FAILURE);
}
I'm not 100% sure what it means, and if it is even a problem, since the memory will be reclaimed by the OS anyway. But I've never seen this kind of thing before, and wanted to check.
So, my question is, what is it caused by? Should I fix it? If so, how?
std::logic_error's constructor allocated memory for the "explanatory string". This is what() returns to you, in the exception handler (std::invalid_argument inherits from std::logic_error).
Observe that the backtrace shows the constructor overload that takes a const char * for a parameter. It would've been acceptable if that literal const char * got stashed away, and handed back to you from what(). However there are various immaterial reasons why the constructor is coded to make a copy of the "explanatory string" so that its contents are wholly owned by the constructed std::logic_error.
Your exception handler quietly called exit() and the process terminated. At which point valgrind notified you that the aforementioned allocated memory wasn't destroyed. This is true, that memory wasn't deallocated.
Had your exception handler's scope ended naturally (without calling exit()), std::logic_error's destructor would've deleted the allocated memory, and everyone would've lived happily ever after.
TLDR: this is only a technical memory leak. It is technically true only because the rug was pulled from under the process, by calling exit.
Note that valgrind said "possibly" instead of "definitely". There's no doubt that you have a memory leak when valgrind "definitely" claims one. If it's just "possibly", then there may or may not be a real memory leak.
exit loses more or less everything not recursively owned by objects of static storage duration. Of course this includes everything recursively owned by things on the stack, but also the active exception object (its memory is allocated in an unspecified way). In this particular case, you lose a buffer owned by a std::string owned by the active exception object.
If you care about such things, don't use exit in the middle of things. Rethrow the exception, catch it in main, let the handler finish, and then call exit (or just fall out of main naturally). You probably shouldn't, as this is not a real leak (i.e. there is no memory allocated and lost by the program while it is still running).
My valgrind is telling me that it found non-freed heap memory for the most trivial C++ code.
My code is shown as follows:
#include <iostream>
#include <string>
int main() {
std::cout << "Hello!!!!" << std::endl;
return 0;
}
And the result of valgrind is here:
==12455== HEAP SUMMARY:
==12455== in use at exit: 72,704 bytes in 1 blocks
==12455== total heap usage: 2 allocs, 1 frees, 73,728 bytes allocated
==12455==
==12455== 72,704 bytes in 1 blocks are still reachable in loss record 1 of 1
==12455== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12455== by 0x4EC3EFF: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==12455== by 0x40106C9: call_init.part.0 (dl-init.c:72)
==12455== by 0x40107DA: call_init (dl-init.c:30)
==12455== by 0x40107DA: _dl_init (dl-init.c:120)
==12455== by 0x4000C69: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==12455==
==12455== LEAK SUMMARY:
==12455== definitely lost: 0 bytes in 0 blocks
==12455== indirectly lost: 0 bytes in 0 blocks
==12455== possibly lost: 0 bytes in 0 blocks
==12455== still reachable: 72,704 bytes in 1 blocks
==12455== suppressed: 0 bytes in 0 blocks
==12455==
==12455== For counts of detected and suppressed errors, rerun with: -v
==12455== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Is this a bug of valgrind?
This is due to the way the C++ standard library works. The containers allocate chunks of memory (called pools) and manage them internally. They use basically a memory manager of their own, rather than relying on system's memory manager. Therefore, when an object is destroyed, it's memory is freed by the internal allocator for reuse, but not given back to the operating system.
This is also described in valgrind's FAQ here.
To generalize a bit more, valgrind is a very useful tool, but you should not aim for 0 leaks, but rather to understand its reports and find leaks that indicate a problem in the code.
I use valgrind 3.14.0 under Ubuntu 19.04 and i dont get any detections. I ran with --leak-check=fulland without. Maybe its just some versions of valgrind.
I have a C++ program that uses a shared C library (namely Darknet) to load and make use of lightweight neural networks.
The program run flawlessly under Ubuntu Trusty on x86_64 box, but crashes with segmentation fault under the same OS but on the ARM device. The reason of the crash is that calloc returns NULL during memory allocation for an array. The code looks like the following:
l.filters = calloc(c * n * size * size, sizeof(float));
...
for (i = 0; i < c * n * size * size; ++i)
l.filters[i] = scale * rand_uniform(-1, 1);
So, after trying to write the first element, the application halts with segfault.
In my case the amount of the memory to be allocated is 4.7 MB, while there is more than 1GB available. I also tried to run it after reboot to exclude the heap fragmentation, but with the same result.
What is more interesting, when I am trying to load a larger network, it works just fine. And the two networks have the same configuration of the layer for which the crash happens...
Valgrind tells me nothing new:
==2591== Invalid write of size 4
==2591== at 0x40C70: make_convolutional_layer (convolutional_layer.c:135)
==2591== by 0x2C0DF: parse_convolutional (parser.c:159)
==2591== by 0x2D7EB: parse_network_cfg (parser.c:493)
==2591== by 0xBE4D: main (annotation.cpp:58)
==2591== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==2591==
==2591==
==2591== Process terminating with default action of signal 11 (SIGSEGV)
==2591== Access not within mapped region at address 0x0
==2591== at 0x40C70: make_convolutional_layer (convolutional_layer.c:135)
==2591== by 0x2C0DF: parse_convolutional (parser.c:159)
==2591== by 0x2D7EB: parse_network_cfg (parser.c:493)
==2591== by 0xBE4D: main (annotation.cpp:58)
==2591== If you believe this happened as a result of a stack
==2591== overflow in your program's main thread (unlikely but
==2591== possible), you can try to increase the size of the
==2591== main thread stack using the --main-stacksize= flag.
==2591== The main thread stack size used in this run was 4294967295.
==2591==
==2591== HEAP SUMMARY:
==2591== in use at exit: 1,731,358,649 bytes in 2,164 blocks
==2591== total heap usage: 12,981 allocs, 10,817 frees, 9,996,704,911 bytes allocated
==2591==
==2591== LEAK SUMMARY:
==2591== definitely lost: 16,645 bytes in 21 blocks
==2591== indirectly lost: 529,234 bytes in 236 blocks
==2591== possibly lost: 1,729,206,304 bytes in 232 blocks
==2591== still reachable: 1,606,466 bytes in 1,675 blocks
==2591== suppressed: 0 bytes in 0 blocks
==2591== Rerun with --leak-check=full to see details of leaked memory
==2591==
==2591== For counts of detected and suppressed errors, rerun with: -v
==2591== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 402 from 8)
Killed
I am really confused what might be the reason. Could anybody help me?
I wrote a socket server. And I realize when I hit Ctrl-C while it's running, there's some possible memory leak. I used valgrind to find this.
My server code is quite simple. Basically I create a Listener object, start a thread to accept connections and try to join that thread:
try {
Server::Listener listener(1234);
boost::thread l(boost::bind(&Server::Listener::start, &listener));
l.join();
} catch(exception& e) {
cout<<e.what()<<endl;
}
When I run valgrind, it give me:
==3580== Command: bin/Debug/p_rpc
==3580==
Listner started ...
in loop..
^C==3580==
==3580== HEAP SUMMARY:
==3580== in use at exit: 3,176 bytes in 24 blocks
==3580== total heap usage: 28 allocs, 4 frees, 4,328 bytes allocated
==3580==
==3580== 288 bytes in 1 blocks are possibly lost in loss record 21 of 24
==3580== at 0x4C29E46: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3580== by 0x4012084: _dl_allocate_tls (dl-tls.c:297)
==3580== by 0x4E3AABC: pthread_create##GLIBC_2.2.5 (allocatestack.c:571)
==3580== by 0x5260F9F: boost::thread::start_thread() (in /usr/lib/libboost_thread.so.1.49.0)
==3580== by 0x407B93: boost::thread::thread, boost::_bi::list1 > > >(boost::_bi::bind_t, boost::_bi::list1 > >&&) (thread.hpp:171)
==3580== by 0x404CA4: main (main.cpp:179)
==3580==
==3580== LEAK SUMMARY:
==3580== definitely lost: 0 bytes in 0 blocks
==3580== indirectly lost: 0 bytes in 0 blocks
==3580== possibly lost: 288 bytes in 1 blocks
==3580== still reachable: 2,888 bytes in 23 blocks
==3580== suppressed: 0 bytes in 0 blocks
==3580== Reachable blocks (those to which a pointer was found) are not shown.
==3580== To see them, rerun with: --leak-check=full --show-reachable=yes
==3580==
==3580== For counts of detected and suppressed errors, rerun with: -v
==3580== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)
Killed
It points out there's 288bytes possibly lost. I imagine I could use a signal handler to release this resourse. But I don't know how I do that. Can you give me an example please?
Cheers,
Elton
When a process closes, the OS automatically cleans up all memory owned by the process. You don't need to worry about freeing that memory when the program exits. The building is being demolished. Don't bother sweeping the floor and emptying the trash cans and erasing the whiteboards. And don't line up at the exit to the building so everybody can move their in/out magnet to out. All you're doing is making the demolition team wait for you to finish these pointless housecleaning tasks.
The kind of leaks you do need to worry about are those that continuously leak during the program's lifetime.
In principle, you can destroy the object there. There are restrictions on what you can do in a signal handler, and they mix very badly with threads. Note that in this area the compiler can do no (or very little) checking, the signal handler is just an ordinary function. Be extra careful.
The answers to this question give some details on how to do it.
I am new to the smart pointers world. I've done my reading and all of them stated that smart pointers will avoid leaking memory even when the program will exit after encountering an exception.
I wrote down a simple program to try this out, but Valgrind is telling me my program is leaking memory (three allocs and only one free).
This is the source code:
#include <iostream>
#include <memory>
using namespace std;
int main()
{
auto_ptr<int> ptr_int(new int(5));
throw std::bad_alloc();
cout << *ptr_int;
}
And this Valgrind report:
==27862== Memcheck, a memory error detector
==27862== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==27862== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==27862== Command: ./smart_pointers
==27862== Parent PID: 5388
==27862==
==27862==
==27862== HEAP SUMMARY:
==27862== in use at exit: 104 bytes in 2 blocks
==27862== total heap usage: 3 allocs, 1 frees, 120 bytes allocated
==27862==
==27862== 4 bytes in 1 blocks are still reachable in loss record 1 of 2
==27862== at 0x4026351: operator new(unsigned int) (vg_replace_malloc.c:255)
==27862== by 0x804878A: main (smart_pointers.cpp:8)
==27862==
==27862== 100 bytes in 1 blocks are possibly lost in loss record 2 of 2
==27862== at 0x4025BD3: malloc (vg_replace_malloc.c:236)
==27862== by 0x40E861A: __cxa_allocate_exception (in /usr/lib/libstdc++.so.6.0.14)
==27862== by 0x80487AE: main (smart_pointers.cpp:10)
==27862==
==27862== LEAK SUMMARY:
==27862== definitely lost: 0 bytes in 0 blocks
==27862== indirectly lost: 0 bytes in 0 blocks
==27862== possibly lost: 100 bytes in 1 blocks
==27862== still reachable: 4 bytes in 1 blocks
==27862== suppressed: 0 bytes in 0 blocks
==27862==
==27862== For counts of detected and suppressed errors, rerun with: -v
==27862== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 19 from 8)
Does using smart pointers guarantee the allocated resources will be destroyed even if an exception shows up?
If an exception is not handled, then it's implementation-defined whether the stack will be unwound before calling std::terminate.
If you handle the exception, then the smart pointer will work as expected.
Reference:
C++11 15.5.1 The std::terminate() function
1 In some situations exception handling must be abandoned for less subtle error handling techniques. These situations are:
........
— when the exception handling mechanism cannot find a handler for a thrown exception , or
........
2 In such cases std::terminate() is called. In the situation where no matching handler is found, it is implementation-defined whether or not the stack is unwound before std::terminate() is called.
When std::terminate() is called (as is the case for an uncaught exception), normal cleanup is not run (at least for the stack-frame of main()), and as such the memory you've allocated in that stack frame leaks, even though it's supposedly managed by a smart-pointer. When you're catching the std::bad_alloc in main(), and return normally, the smart-pointer will do it's duty.
If the exception is not caught, then the stack unwinding is implementation specific. Therefore in your case, it does not release the memory.
Also, auto_ptr is no longer recommended.
Use std::unique_ptr :
unique_ptr<int> ptr_int(new int(5));