My binary (generated from C++) has two threads. When I care about exceptions, I care about exceptions thrown in one of them (the worker) but not the other.
Is there a way to tell gdb only to pay attention to one of the threads when using catch throw? The gdb manual (texinfo document) and googling suggest to me that this isn't possible, although I think I could request catching a specific type of exception, which hopefully only one of the threads would throw, using catch throw REGEXP.
Is there a way to tell gdb only to pay attention to one of the threads
The catch throw is really just a fancy way to set a breakpoint on __cxxabiv1::__cxa_throw (or similar), and you can make a breakpoint conditional on thread number, achieving the equivalent result.
Example:
#include <pthread.h>
#include <unistd.h>
void *fn(void *)
{
while(true) {
try {
throw 1;
} catch (...) {}
sleep(1);
}
return nullptr;
}
int main() {
pthread_t tid;
pthread_create(&tid, nullptr, fn, nullptr);
fn(nullptr);
return 0;
}
g++ -g -pthread t.cc
Using catch throw, you would get a breakpoint firing on the main and the second thread. But using break ... thread 2 you would only get the one breakpoint you care about:
gdb -q a.out
Reading symbols from a.out...
(gdb) start
Temporary breakpoint 1 at 0x11d6: file t.cc, line 17.
Starting program: /tmp/a.out
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Temporary breakpoint 1, main () at t.cc:17
17 pthread_create(&tid, nullptr, fn, nullptr);
(gdb) n
[New Thread 0x7ffff7a4c640 (LWP 1225199)]
## Note: GDB refuses to set thread-specific breakpoint until the thread actually exists.
18 fn(nullptr);
(gdb) break __cxxabiv1::__cxa_throw thread 2
Breakpoint 2 at 0x7ffff7e40370: file ../../../../src/libstdc++-v3/libsupc++/eh_throw.cc, line 77.
(gdb) c
Continuing.
[Switching to Thread 0x7ffff7a4c640 (LWP 1225199)]
Thread 2 "a.out" hit Breakpoint 2, __cxxabiv1::__cxa_throw (obj=0x7ffff0000be0, tinfo=0x555555557dc8 <typeinfo for int#CXXABI_1.3>, dest=0x0) at ../../../../src/libstdc++-v3/libsupc++/eh_throw.cc:77
77 ../../../../src/libstdc++-v3/libsupc++/eh_throw.cc: No such file or directory.
(gdb) bt
#0 __cxxabiv1::__cxa_throw (obj=0x7ffff0000be0, tinfo=0x555555557dc8 <typeinfo for int#CXXABI_1.3>, dest=0x0) at ../../../../src/libstdc++-v3/libsupc++/eh_throw.cc:77
#1 0x00005555555551b5 in fn () at t.cc:8
#2 0x00007ffff7d7eeae in start_thread (arg=0x7ffff7a4c640) at pthread_create.c:463
#3 0x00007ffff7caea5f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
(gdb) c
Continuing.
Thread 2 "a.out" hit Breakpoint 2, __cxxabiv1::__cxa_throw (obj=0x7ffff0000be0, tinfo=0x555555557dc8 <typeinfo for int#CXXABI_1.3>, dest=0x0) at ../../../../src/libstdc++-v3/libsupc++/eh_throw.cc:77
77 in ../../../../src/libstdc++-v3/libsupc++/eh_throw.cc
(gdb) bt
#0 __cxxabiv1::__cxa_throw (obj=0x7ffff0000be0, tinfo=0x555555557dc8 <typeinfo for int#CXXABI_1.3>, dest=0x0) at ../../../../src/libstdc++-v3/libsupc++/eh_throw.cc:77
#1 0x00005555555551b5 in fn () at t.cc:8
#2 0x00007ffff7d7eeae in start_thread (arg=0x7ffff7a4c640) at pthread_create.c:463
#3 0x00007ffff7caea5f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
Voilà -- thread-specific catch throw equivalent.
Related
This question has been asked before but the solutions proposed there do not work for me. The issue is when an unhandled exception occurs and std::terminate is invoked the original stack trace where the exception is thrown is gone. How can we get that?
Here is a simple test app where child thread throw an exception and std:: terminated is called. The core file does not show the original stack trace.
I tried below, none of them works --
i) std::set_terminate(myhandler) -- myhandler is called as expected but this does not affect stack unwinding.
ii) compile with -fno-exceptions -- no effect, likely because the exception is thrown from std library.
Any suggestions will be greatly appreciated!
$ cat thread.cpp
#include <utility>
#include <thread>
#include <chrono>
#include <cstdlib>
#include <iostream>
#include <vector>
void f1()
{
for (int i = 0; i < 10; ++i) {
std::cout << "Thread 1 executing\n";
std::this_thread::sleep_for(std::chrono::milliseconds(10));
// !!! create an exception, how to get the stack trace here.
std::vector<int> vec;
vec.reserve(-1);
}
}
int main()
{
std::thread t1(f1);
t1.join();
std::cout << "Done " << '\n';
}
$ g++ -g thread.cpp -pthread
$ ./a.out
Thread 1 executing
terminate called after throwing an instance of 'std::length_error'
what(): vector::reserve
Aborted (core dumped)
$gdb a.out core
...
Core was generated by `./a.out'.
Program terminated with signal SIGABRT, Aborted.
#0 0x00007f7e13084277 in __GI_raise (sig=sig#entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56 return INLINE_SYSCALL (tgkill, 3, pid, selftid, sig);
[Current thread is 1 (Thread 0x7f7e1304d700 (LWP 106036))]
Missing separate debuginfos, use: debuginfo-install libgcc-4.8.5-28.el7_5.1.x86_64 libstdc++-4.8.5-28.el7_5.1.x86_64
(gdb) thread apply all bt
Thread 2 (Thread 0x7f7e14054740 (LWP 106035)):
#0 0x00007f7e13423f97 in pthread_join (threadid=140179461691136, thread_return=0x0) at pthread_join.c:92
#1 0x00007f7e13c03e37 in std::thread::join() () from /lib64/libstdc++.so.6
#2 0x0000000000400f8f in main () at thread.cpp:22
Thread 1 (Thread 0x7f7e1304d700 (LWP 106036)):
#0 0x00007f7e13084277 in __GI_raise (sig=sig#entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1 0x00007f7e13085968 in __GI_abort () at abort.c:90
#2 0x00007f7e13baf7d5 in __gnu_cxx::__verbose_terminate_handler() () from /lib64/libstdc++.so.6
#3 0x00007f7e13bad746 in ?? () from /lib64/libstdc++.so.6
#4 0x00007f7e13bad773 in std::terminate() () from /lib64/libstdc++.so.6
#5 0x00000000004023de in execute_native_thread_routine ()
#6 0x00007f7e13422e25 in start_thread (arg=0x7f7e1304d700) at pthread_create.c:308
#7 0x00007f7e1314cbad in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:113
I am wrote on C++ multithread TCP server, for synchronization using boost:scoped_lock
After connecting to server client freezes.
in gdb i saw more threads in pthread_kill after call boost::mutex::lock
(gdb) info thread
277 Thread 808779c00 (LWP 245289330/xgps) 0x0000000802579d5c in poll () at poll.S:3
276 Thread 808779800 (LWP 245289329/xgps) 0x00000008019799bc in pthread_kill () from /lib/libthr.so.3
275 Thread 808779400 (LWP 245289328/xgps) 0x00000008019799bc in pthread_kill () from /lib/libthr.so.3
.....
246 Thread 808c92800 (LWP 245289296/xgps) 0x00000008019799bc in pthread_kill () from /lib/libthr.so.3
245 Thread 808643800 (LWP 245289295/xgps) 0x00000008019799bc in pthread_kill () from /lib/libthr.so.3
244 Thread 808643400 (LWP 245289294/xgps) 0x00000008019799bc in pthread_kill () from /lib/libthr.so.3
243 Thread 806c8f400 (LWP 245289292/xgps) 0x00000008019799bc in pthread_kill () from /lib/libthr.so.3
242 Thread 808643000 (LWP 245286262/xgps) 0x00000008019799bc in pthread_kill () from /lib/libthr.so.3
241 Thread 808c92400 (LWP 245289288/xgps) 0x00000008019799bc in pthread_kill () from /lib/libthr.so.3
[Switching to thread 205 (Thread 80863a000 (LWP 245289251/xgps))]#0 0x00000008019799bc in pthread_kill () from /lib/libthr.so.3
(gdb) where
#0 0x00000008019799bc in pthread_kill () from /lib/libthr.so.3
#1 0x0000000801973cfc in pthread_getschedparam () from /lib/libthr.so.3
#2 0x00000008019782fc in pthread_mutex_getprioceiling () from /lib/libthr.so.3
#3 0x000000080197838b in pthread_mutex_lock () from /lib/libthr.so.3
#4 0x0000000000442b2e in boost::mutex::lock (this=0x803835f10) at mutex.hpp:62
#5 0x0000000000442c36 in boost::unique_lock<boost::mutex>::lock (this=0x7fffe7334270) at lock_types.hpp:346
#6 0x0000000000442c7c in unique_lock (this=0x7fffe7334270, m_=#0x803835f10) at lock_types.hpp:124
#7 0x0000000000466e31 in XDevice::getDeviceIMEI (this=0x803835e20) at /home/xgps_app/device.cpp:639
#8 0x000000000049071f in XDevicePool::get_device (this=0x7fffffffd9c0, device_imei=868683024674230) at /home/xgps_app/pool_devices.cpp:351
Code at line device.cpp:639
IMEI
XDevice::getDeviceIMEI()
{
try {
boost::mutex::scoped_lock lock(cn_mutex);
return device_imei;
}
catch (std::exception &e )
{
cout << " ERROR in getDeviceIMEI " << e.what() << "\n";
}
return 0;
}
Code in pool_device
XDevicePtr
XDevicePool::get_device(IMEI device_imei)
{
XDevicePtr device;
unsigned int i = 0;
while(i < this->devices.size())
{
device = devices[i];
if (device->getDeviceIMEI() == device_imei) {
LOG4CPLUS_DEBUG(logger, "XDevicePool::get_device found!");
return device;
}
i++;
}
device.reset();
return device;
}
XDevicePtr
XDevicePool::get_device_mt(IMEI device_imei)
{
try
{
boost::mutex::scoped_lock lock(pool_mutex);
}
catch (std::exception & e)
{
LOG4CPLUS_ERROR(logger, "XDevicePool::get_device error! " << e.what());
}
// boost::mutex::scoped_lock lock(pool_mutex);
return get_device(device_imei);
}
Why after call to mutex lock thread terminating?
I think dead lock not reason for that behavior
Please help!
You have multiple locks.
Whenever you have multiple locks that can be required simultaneously you need to obtain them in a fixed order, to avoid dead-locking.
It seems likely that you have such a deadlock occurring. See Boost Thread's free function boost::lock http://www.boost.org/doc/libs/1_63_0/doc/html/thread/synchronization.html#thread.synchronization.lock_functions.lock_multiple for help acquiring multiple lock in reliable order.
You will also want to know about std::defer_lock.
Other than this, there might be interference from fork in multi-threaded programs. I think it's beyond the scope now to explain, unless you are indeed using fork in your process
tl;dr pthread_kill is likely a red herring.
Why after call to mutex lock thread terminating?
It doesn't. Your threads have not been terminated (as evidenced by them still appearing on info thread).
You seem to assume that pthread_kill kills the current thread. In fact, what pthread_kill does is send a signal to another thread. And even the sending is optional (if sig=0).
See the man page for further details.
In some of the answers to related questions I could see that gdb 7.3 should support displaying thread names atleast with 'info threads' command .
But I am not even getting that luxury. please help me to understand what I am doing wrong.
My sample code used for testing:
#include <stdio.h>
#include <pthread.h>
#include <sys/prctl.h>
static pthread_t ta, tb;
void *
fx (void *param)
{
int i = 0;
prctl (PR_SET_NAME, "Mythread1", 0, 0, 0);
while (i < 1000)
{
i++;
printf ("T1%d ", i);
}
}
void *
fy (void *param)
{
int i = 0;
prctl (PR_SET_NAME, "Mythread2", 0, 0, 0);
while (i < 100)
{
i++;
printf ("T2%d ", i);
}
sleep (10);
/* generating segmentation fault */
int *p;
p = NULL;
printf ("%d\n", *p);
}
int
main ()
{
pthread_create (&ta, NULL, fx, 0);
pthread_create (&tb, NULL, fy, 0);
void *retval;
pthread_join (ta, &retval);
pthread_join (tb, &retval);
return 0;
}
Output( using core dump generated by segmentation fault)
(gdb) core-file core.14001
[New LWP 14003]
[New LWP 14001]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/libthread_db.so.1".
Core was generated by `./thread_Ex'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x08048614 in fy (param=0x0) at thread_Ex.c:30
30 printf("%d\n",*p);
(gdb) info threads
Id Target Id Frame
2 Thread 0xb77d76c0 (LWP 14001) 0x00b95424 in __kernel_vsyscall ()
* 1 Thread 0xb6dd5b70 (LWP 14003) 0x08048614 in fy (param=0x0) at thread_Ex.c:30
(gdb) bt
#0 0x08048614 in fy (param=0x0) at thread_Ex.c:30
#1 0x006919e9 in start_thread () from /lib/libpthread.so.0
#2 0x005d3f3e in clone () from /lib/libc.so.6
(gdb) thread apply all bt
Thread 2 (Thread 0xb77d76c0 (LWP 14001)):
#0 0x00b95424 in __kernel_vsyscall ()
#1 0x006920ad in pthread_join () from /lib/libpthread.so.0
#2 0x080486a4 in main () at thread_Ex.c:50
Thread 1 (Thread 0xb6dd5b70 (LWP 14003)):
#0 0x08048614 in fy (param=0x0) at thread_Ex.c:30
#1 0x006919e9 in start_thread () from /lib/libpthread.so.0
#2 0x005d3f3e in clone () from /lib/libc.so.6
(gdb) q
As you can see I cant see any thread names that I have set. what could be wrong?
Note:
I am using gdb version 7.7 (Downloaded and compiled using no special options)
commands used to compile & install gdb : ./configure && make && make install
As far as I am aware, thread names are not present in the core dump.
If they are available somehow, please file a gdb bug.
I get thread name displayed on CentOS6.5, but not displayed on CentOS6.4 .
I am trying to implement a thread pool using ACE Semaphore library. It does not provide any API like sem_getvalue which is in Posix semaphore. I need to debug some flow which is not behaving as expected. Can I examine the semaphore in GDB. I am using Centos as OS.
I initialized two semaphores using the default constructor providing count 0 and 10. I have declared them as static in the class and initialized it in the cpp file as
DP_Semaphore ThreadPool::availableThreads(10);
DP_Semaphore ThreadPool::availableWork(0);
But when I am printing the semaphore in GDB using the print command, I am getting the similar output
(gdb) p this->availableWork
$7 = {
sema = {
semaphore_ = {
sema_ = 0x6fe5a0,
name_ = 0x0
},
removed_ = false
}
}
(gdb) p this->availableThreads
$8 = {
sema = {
semaphore_ = {
sema_ = 0x6fe570,
name_ = 0x0
},
removed_ = false
}
}
Is there a tool which can help me here, or shall I switch to Posix thread and re-write all my code.
EDIT: As requested by #timrau the output of call this->availableWork->dump()
(gdb) p this->availableWork.dump()
[Switching to Thread 0x2aaaae97e940 (LWP 28609)]
The program stopped in another thread while making a function call from GDB.
Evaluation of the expression containing the function
(DP_Semaphore::dump()) will be abandoned.
When the function is done executing, GDB will silently stop.
(gdb) call this->availableWork.dump()
[Switching to Thread 0x2aaaaf37f940 (LWP 28612)]
The program stopped in another thread while making a function call from GDB.
Evaluation of the expression containing the function
(DP_Semaphore::dump()) will be abandoned.
When the function is done executing, GDB will silently stop.
(gdb) info threads
[New Thread 0x2aaaafd80940 (LWP 28613)]
6 Thread 0x2aaaafd80940 (LWP 28613) 0x00002aaaac10a61e in __lll_lock_wait_private ()
from /lib64/libpthread.so.0
* 5 Thread 0x2aaaaf37f940 (LWP 28612) ThreadPool::fetchWork (this=0x78fef0, worker=0x2aaaaf37f038)
at ../../CallManager/src/DP_CallControlTask.cpp:1043
4 Thread 0x2aaaae97e940 (LWP 28609) DP_Semaphore::dump (this=0x6e1460) at ../../Common/src/DP_Semaphore.cpp:21
2 Thread 0x2aaaad57c940 (LWP 28607) 0x00002aaaabe01ff3 in __find_specmb () from /lib64/libc.so.6
1 Thread 0x2aaaacb7b070 (LWP 28604) 0x00002aaaac1027c0 in __nptl_create_event () from /lib64/libpthread.so.0
(gdb)
sema.semaphore_.sema_ in your code looks like a pointer. Try to find it's type in the ACE headers, then convert it to a type and print:
(gdb) p *((sem_t)0x6fe570)
Update: try to convert the address within the structure you posted to sem_t. If you use linux, ACE should be using posix semaphores, so type sem_t must be visible to gdb.
I am on mingw (gcc version 4.5.2).
I get a segfault when opening certain files, including PNGs and BMPs. It was working fine on a 128x128 PNG but when I started testing with larger files I started getting a segfault. There are no issues with the TGA format, though. I know the library works for the most part, but not knowing whether it will decide to crash and burn like this is not good.
gdb does not give me any hints about what's going on. I am able to compile DevIL from source, and I compiled a debug dll (--enable-debug for configure script) but it doesn't seem to support png (seems like I need to get a png12 library) but it doesn't get me very far.
I am trying to open a ~2MB BMP I made in GIMP. I run it through GDB and it sometimes will segfault but other times it warns of some stuff happening on the heap (lots of stuff i've never seen before). Here's a gdb run dump. All of the lines beginning with %%% are the output that is specific to my program, the rest comes from gdb.
$ gdb ./entropy_unittest_disp.exe loadpngdisplay
GNU gdb (GDB) 7.2
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from c:\Users\Steven\Dropbox\Programming\entropy_p5_makefile\cpp
\game/./entropy_unittest_disp.exe...done.
c:\Users\Steven\Dropbox\Programming\entropy_p5_makefile\cpp\game/loadpngdisplay:
No such file or directory.
(gdb) r
Starting program: c:\Users\Steven\Dropbox\Programming\entropy_p5_makefile\cpp\ga
me/./entropy_unittest_disp.exe
[New Thread 23284.0x5bb4]
%%%UNIT TEST BUILD: INTERNAL USE ONLY. DO NOT DISTRIBUTE
%%%Compiled on Sep 11 2011 at 09:45:38
%%%argc = 1: Main.cpp:119
%%%argv:
%%%0: c:\Users\Steven\Dropbox\Programming\entropy_p5_makefile\cpp\game/./entropy_un
%%%ittest_disp.exe
%%%←[36mStarting Test ilWritePng, at Image.cpp:8←[0m
%%%rm: cannot lstat `output_il.png': No such file or directory
%%%ilGetError() = 1292: Image.cpp:25
%%%Completed Test ilWritePng in 0.033 seconds
%%%←[36mStarting Test loadPNGDisplay, at Image.cpp:31←[0m
[New Thread 23284.0x445c]
[New Thread 23284.0x1fd8]
[New Thread 23284.0x1424]
%%%Number of Joysticks detected: 2
%%%Opening Joystick: Harmonix Guitar for Xbox 360 (Controller)
[New Thread 23284.0x526c]
[New Thread 23284.0x5a70]
[New Thread 23284.0x1ae8]
[New Thread 23284.0x5908]
[New Thread 23284.0x5974]
%%%Using GLEW 1.5.8
%%%OpenGL Vendor: NVIDIA Corporation
%%%OpenGL Renderer: GeForce GTX 260/PCI/SSE2
%%%OpenGL Version: 3.3.0
warning: HEAP[entropy_unittest_disp.exe]:
warning: Invalid address specified to RtlFreeHeap( 00350000, 04000000 )
Program received signal SIGTRAP, Trace/breakpoint trap.
0x772e0475 in ntdll!TpWaitForAlpcCompletion ()
from C:\Windows\system32\ntdll.dll
(gdb) where
#0 0x772e0475 in ntdll!TpWaitForAlpcCompletion ()
from C:\Windows\system32\ntdll.dll
#1 0x0028f510 in ?? ()
#2 0x772a29c0 in ntdll!RtlCopyExtendedContext ()
from C:\Windows\system32\ntdll.dll
#3 0x03fffff8 in ?? ()
#4 0x772e14cf in ntdll!TpQueryPoolStackInformation ()
from C:\Windows\system32\ntdll.dll
#5 0x00350000 in ?? ()
#6 0x7729ab3a in ntdll!AlpcMaxAllowedMessageLength ()
from C:\Windows\system32\ntdll.dll
#7 0x00350000 in ?? ()
#8 0x77243472 in ntdll!RtlLargeIntegerShiftRight ()
from C:\Windows\system32\ntdll.dll
#9 0x03fffff8 in ?? ()
#10 0x766398cd in msvcrt!free () from C:\Windows\syswow64\msvcrt.dll
#11 0x00350000 in ?? ()
#12 0x6180129c in _mm_free (aligned_ptr=0x8230020)
at c:/mingw/bin/../lib/gcc/mingw32/4.5.2/include/mm_malloc.h:71
#13 0x61801370 in DefaultFreeFunc (ptr=0x8230020)
at ./../src-IL/src/il_alloc.c:127
#14 0x618012ee in ifree (Ptr=0x8230020) at ./../src-IL/src/il_alloc.c:99
#15 0x618149f8 in iPreCache (Size=592128) at ./../src-IL/src/il_files.c:550
#16 0x618148a2 in iReadFile (Buffer=0x8100017, Size=1, Number=2313)
at ./../src-IL/src/il_files.c:499
#17 0x61808cf5 in ilReadUncompBmp (Header=0x28f829)
at ./../src-IL/src/il_bmp.c:486
#18 0x61808410 in iLoadBitmapInternal () at ./../src-IL/src/il_bmp.c:250
#19 0x618082f3 in ilLoadBmpF (File=0x766d2960) at ./../src-IL/src/il_bmp.c:199
#20 0x618082ba in ilLoadBmp (FileName=0x4c25f1 "folder.bmp")
at ./../src-IL/src/il_bmp.c:184
#21 0x61830bf0 in ilLoadImage (FileName=0x4c25f1 "folder.bmp")
at ./../src-IL/src/il_io.c:1827
#22 0x0040f66c in SDLSystemloadPNGDisplayHelper::RunImpl (this=0x28fc10)
at Image.cpp:40
#23 0x00461e74 in UnitTest::ExecuteTest<SDLSystemloadPNGDisplayHelper> (
testObject=..., details=...) at ../include/UnitTest++/ExecuteTest.h:25
#24 0x0040f2cd in TestSDLSystemloadPNGDisplay::RunImpl (this=0x4e5cf8)
at Image.cpp:31
#25 0x00463023 in UnitTest::ExecuteTest<UnitTest::Test> (testObject=...,
details=...) at src/ExecuteTest.h:25
#26 0x0044198d in UnitTest::Test::Run (this=0x4e5cf8) at src/Test.cpp:34
#27 0x00441d9a in UnitTest::TestRunner::RunTest (this=0x28fedc,
result=0x3517f0, curTest=0x4e5cf8, maxTestTimeInMs=0)
at src/TestRunner.cpp:61
#28 0x00466b7e in UnitTest::TestRunner::RunTestsIf<UnitTest::True> (
this=0x28fedc, list=..., suiteName=0x0, predicate=..., maxTestTimeInMs=0)
at ../include/UnitTest++/TestRunner.h:40
#29 0x004014e3 in UnitTest::RunAllTestsVerbose () at Main.cpp:72
#30 0x0040167d in main (argc=1, argv=0x3531d8) at Main.cpp:126
(gdb) c
Continuing.
warning: HEAP[entropy_unittest_disp.exe]:
warning: Invalid address specified to RtlFreeHeap( 00350000, 04000000 )
Program received signal SIGTRAP, Trace/breakpoint trap.
0x772e0475 in ntdll!TpWaitForAlpcCompletion ()
from C:\Windows\system32\ntdll.dll
(gdb) c
Continuing.
warning: HEAP[entropy_unittest_disp.exe]:
warning: Invalid address specified to RtlFreeHeap( 00350000, 04000000 )
Program received signal SIGTRAP, Trace/breakpoint trap.
0x772e0475 in ntdll!TpWaitForAlpcCompletion ()
from C:\Windows\system32\ntdll.dll
(gdb)
Continuing.
warning: HEAP[entropy_unittest_disp.exe]:
warning: Invalid address specified to RtlFreeHeap( 00350000, 04000000 )
Program received signal SIGTRAP, Trace/breakpoint trap.
0x772e0475 in ntdll!TpWaitForAlpcCompletion ()
from C:\Windows\system32\ntdll.dll
(gdb)
Continuing.
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 23284.0x5974]
0x05064225 in nvoglv32!DrvGetProcAddress ()
from C:\Windows\SysWOW64\nvoglv32.dll
(gdb)
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0x05064225 in nvoglv32!DrvGetProcAddress ()
from C:\Windows\SysWOW64\nvoglv32.dll
(gdb)
Continuing.
Program exited with code 030000000005.
(gdb)
The program is not being run.
(gdb) r
Starting program: c:\Users\Steven\Dropbox\Programming\entropy_p5_makefile\cpp\ga
me/./entropy_unittest_disp.exe
[New Thread 23428.0x49b8]
%%%UNIT TEST BUILD: INTERNAL USE ONLY. DO NOT DISTRIBUTE
%%%Compiled on Sep 11 2011 at 09:45:38
%%%argc = 1: Main.cpp:119
%%%argv:
%%%0: c:\Users\Steven\Dropbox\Programming\entropy_p5_makefile\cpp\game/./entropy_un
%%%ittest_disp.exe
%%%←[36mStarting Test ilWritePng, at Image.cpp:8←[0m
Program received signal SIGSEGV, Segmentation fault.
0x7723dfc4 in ntdll!LdrWx86FormatVirtualImage ()
from C:\Windows\system32\ntdll.dll
(gdb) where
#0 0x7723dfc4 in ntdll!LdrWx86FormatVirtualImage ()
from C:\Windows\system32\ntdll.dll
#1 0x1f002150 in ?? ()
#2 0x00000000 in ?? ()
(gdb)
the test ilWritePng is actually just having it write a .tga image file. That test works fine with the release dll (md5 = 59E291838AE2C88F5F71108E4845A84B) but this debug build I compiled has more issues.
I was so happy when I skimmed the doc and got DevIL up and running in like 10 minutes. I figured it was going to save me so much work...
This is making me start to wonder if I should just implement my own image file format (I would use PPM binary and shove it through a compression stream).
edit: source code:
#include "Texture.h" // for Pixel struct
#include "Script.h" // for lua (quick and dirty shell access)
TEST_FIXTURE(ILSystem, ilWritePng) { // ILSystem calls ilInit(), ilShutDown() in ctor, dtor respectively
ILuint image;
ilGenImages(1,&image);
CHECK(ilGetError()==0);
ilBindImage(image);
Pixel pixels[128*128];
for (int i=0;i<128;++i) { for (int j=0;j<128;++j) {
Pixel &p = pixels[i*128+j];
p.b = 0; p.g = i; p.r = j; p.a = 0xff;
}} // neat and simple test image, a greenish purplish gradient type thing.
CHECK(ilTexImage(128,128,1,4,IL_BGRA, IL_UNSIGNED_BYTE,pixels));
CHECK(ilGetError()==0);
{
LuaSystem l;
l.dostring("os.execute(\"rm output_il.tga\")"); // delete that file
}
ilSaveImage("output_il.tga");
PRINT_INT(ilGetError());
}
#ifdef LOAD_DISPLAY
#include "SDLOGL.h"
#include "Texture.h"
TEST_FIXTURE(SDLSystem, loadPNGDisplay) { // takes care of initing SDL and opengl context
ILSystem s; // RAII = peace of mind
// i can't use two fixtures in one unittest. but this does the same thing anyway.
ILuint image;
CHECK(ilGetError()==0);
ilGenImages(1,&image);
CHECK(ilGetError()==0);
ilBindImage(image);
CHECK(ilGetError()==0);
ilLoadImage("folder.bmp");
CHECK(ilGetError()==0);
ILubyte *pixelData = ilGetData(); CHECK(pixelData);
CHECK(ilGetError()==0);
GLuint tex = loadImage32(pixelData,ilGetInteger(IL_IMAGE_WIDTH),ilGetInteger(IL_IMAGE_HEIGHT),0);
// i do not know exactly how its encoded. but it seems like when loading pngs it is in RGBA format
PRINT_INT(ilGetInteger(IL_FORMAT_MODE));
CHECK(ilGetError()==0);
initOrthoRender();
drawTexture(tex);
CHECK(glGetError()==0);
SDL_GL_SwapBuffers();
SLEEP(500);
}
#endif //LOAD_DISPLAY