I'm in trouble with this:
I've installed Allegro5 on Ubuntu, and compiled my Helloworld project
#include <allegro5\allegro.h> #include <allegro5\allegro_native_dialog.h> int main(void) {
ALLEGRO_DISPLAY *display=NULL;
if(!al_init()) {
al_show_native_message_box(NULL, NULL, NULL, "failed to initialize allegro!", NULL, NULL);
return -1;
}
display=al_create_display(640,
480);
if(!display) {
al_show_native_message_box(NULL, NULL, NULL, "failed to initialize display!", NULL, NULL);
return -1;
}
al_destroy_display(display);
return 0;
}
with " g++ -Wall TestProgram.cc pkg-config --libs allegro-5.0 allegro_font-5.0 allegro_ttf-5.0 ".
Running it on terminal, it gives me this error (or crash?) message:
nac#NAC:~$ ./a.out
nouveau: kernel rejected pushbuf: Bad file descriptor
nouveau: ch0: krec 0 pushes 1 bufs 1 relocs 0
nouveau: ch0: buf 00000000 00000002 00000004 00000004 00000000
nouveau: ch0: psh 00000000 00000004a8 00000004bc
nouveau: 0x00107b00
nouveau: 0x00000000
nouveau: 0x20217000
nouveau: 0x00000003
nouveau: 0x1000f010
After some tests I saw that it crashes on or after "al_destroy_display(display);", in fact, after that error I must ctrl+C to end the program.
How can I do??
This question is a few months old, but it comes up as the first hit when searching for this error. I had the same error running LinuxMint 17.2 with Allegro 5.0.10, and solved it by updating my graphics card (GeForce GTX 460) driver. Hope this helps future users.
I had a similar problem with Rstudio (it is quite famous bug on rstudio)
It is proposed to run it using the following command in terminal:
QT_XCB_FORCE_SOFTWARE_OPENGL=1 rstudio
so, in your case i think:
QT_XCB_FORCE_SOFTWARE_OPENGL=1 ./a.out
Related
I'm trying to write a kernel driver (module) that reads GPIO on a RPI3
I use ioremap to get access to the memory of the GPIO, but apparently it crashes.
I get an exception in the /var/log/messages log file
Aug 6 14:07:58 raspberrypi kernel: [ 220.900252] Exception stack(0xa796ffa8 to 0xa796fff0)
Aug 6 14:07:58 raspberrypi kernel: [ 220.900264] ffa0: fe5f5100 7eff8714 00000003 0002d064 00000000 00000004
Aug 6 14:07:58 raspberrypi kernel: [ 220.900277] ffc0: fe5f5100 7eff8714 0003fce8 0000017b 007e47d8 00000000 00000002 00000000
Aug 6 14:07:58 raspberrypi kernel: [ 220.900286] ffe0: 7eff8548 7eff8538 00022cb8 76cb9af0
Here is my module code:
#include <linux/module.h>
#include <linux/kernel.h>
#include <asm/io.h>
#define BCM2708_PERI_BASE 0x20000000
#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */
static int __init driver_init(void)
{
if ((gpio = ioremap(GPIO_BASE, 0xB0)) == NULL) {
printk(KERN_INFO "io remap failed\n");
return -EBUSY;
}
return 0;
}
static void __exit driver_exit(void)
{
iounmap(gpio);
}
module_init(driver_init);
module_exit(driver_exit);
Can someone tell me what I do wrong?
Is there a conflict with another driver? How can I check this?
base adress is 0x3F000000, not 0x2000000
I have written the following code using the POSIX pthread library:
#include <stdlib.h>
#include <pthread.h>
void *thread_function(void *arg) {
char *code = "1";
}
int main() {
int res;
pthread_t a_thread;
void *thread_result;
res = pthread_create(&a_thread, NULL, thread_function, NULL);
if (res != 0) {
perror("Thread creation failed");
exit(EXIT_FAILURE);
}
sleep(5);
printf("\nWaiting for thread to finish...\n");
res = pthread_join(a_thread, &thread_result);
printf("res[%d]\n",res);
if (res != 0) {
perror("Thread join failed");
exit(EXIT_FAILURE);
}
res = pthread_join(a_thread, &thread_result);
printf("res[%d]\n",res);
exit(EXIT_SUCCESS);
}
On executing the code I got the following output:
Waiting for thread to finish...
res[0]
Segmentation fault (core dumped)
In the code, I want to test What happens if you call the pthread_jion() function
twice after the thread is finished. The first call to the function is correct, and the second crash. The backtrace:
Core was generated by `./a.out'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 pthread_join (threadid=140150565050112, thread_return=0x7fffa0a2c508) at
pthread_join.c:47
47 if (INVALID_NOT_TERMINATED_TD_P (pd))
(gdb) bt
Python Exception exceptions.ImportError No module named gdb.frames:
#0 pthread_join (threadid=140150565050112, thread_return=0x7fffa0a2c508) at
pthread_join.c:47
#1 0x00000000004008d5 in main ()
And I check the pthread_join.c file:
39 int
40 pthread_join (threadid, thread_return)
41 pthread_t threadid;
42 void **thread_return;
43 {
44 struct pthread *pd = (struct pthread *) threadid;
45
46 /* Make sure the descriptor is valid. */
47 if (INVALID_NOT_TERMINATED_TD_P (pd))
48 /* Not a valid thread handle. */
49 return ESRCH;
In the line 47, the Macro definition checks Whether the pd is a valid thread handle. If not, return ESRCH(3).
However when I run the same code in another Linux environment, I got the following output:
Waiting for thread to finish...
res[0]
res[3]
Does it have anything to do with the environment? The two linux systems have same ldd version:
ldd (GNU libc) 2.17
same GLIBC:
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_3.4.9
GLIBCXX_3.4.10
GLIBCXX_3.4.11
GLIBCXX_3.4.12
GLIBCXX_3.4.13
GLIBCXX_3.4.14
GLIBCXX_3.4.15
GLIBCXX_3.4.16
GLIBCXX_3.4.17
GLIBCXX_3.4.18
GLIBCXX_3.4.19
GLIBCXX_3.4.20
GLIBC_2.3
GLIBC_2.2.5
GLIBC_2.14
GLIBC_2.17
GLIBC_2.3.2
GLIBCXX_FORCE_NEW
GLIBCXX_DEBUG_MESSAGE_LENGT
and the same linux kernel version:
Red Hat Enterprise Linux Server release 6.6 (Santiago)
pthread_join calls pthread_detach after the thread has terminated.
pthread_detach releases all the threads resources when the thread terminates.
From the documentation of pthread_detach
Attempting to detach an already detached thread results in
unspecified behavior.
So you have unspecified behaviour, so you can't guarantee what will happen afterwards.
At the very least, the memory pointed to by the threadid will be freed, leading to accessing freed memory.
In short, don't call pthread_join twice on the same threadid. Why would you want to?
Edit: even simpler: the man page for pthread_join says:
Joining with a thread that has previously been joined results in
undefined behavior.
As stated on the topic, i'm using objcopy to load SDL_Image images with MinGW over Eclipse Helios for windows.
I'm using the command: objcopy --input-target binary --output-target pei-i386 --binary-architecture i386 Lilothyn.jpg Lilothyn.o
That results in the file:
Lilothyn.o: file format pei-i386
Lilothyn.o
architecture: i386, flags 0x00000030:
HAS_SYMS, HAS_LOCALS
start address 0x00000000
Characteristics 0x305
relocations stripped
line numbers stripped
32 bit words
debugging information removed
Time/Date Thu Jan 01 00:00:00 1970
Magic 0000
MajorLinkerVersion 0
MinorLinkerVersion 0
SizeOfCode 00000000
SizeOfInitializedData 00000000
SizeOfUninitializedData 00000000
AddressOfEntryPoint 00000000
BaseOfCode 00000000
BaseOfData 00000000
ImageBase 00000000
SectionAlignment 00000000
FileAlignment 00000000
MajorOSystemVersion 0
MinorOSystemVersion 0
MajorImageVersion 0
MinorImageVersion 0
MajorSubsystemVersion 0
MinorSubsystemVersion 0
Win32Version 00000000
SizeOfImage 00000000
SizeOfHeaders 00000000
CheckSum 00000000
Subsystem 00000000 (unspecified)
DllCharacteristics 00000000
SizeOfStackReserve 00000000
SizeOfStackCommit 00000000
SizeOfHeapReserve 00000000
SizeOfHeapCommit 00000000
LoaderFlags 00000000
NumberOfRvaAndSizes 00000000
The Data Directory
Entry 0 00000000 00000000 Export Directory [.edata (or where ever we found it)]
Entry 1 00000000 00000000 Import Directory [parts of .idata]
Entry 2 00000000 00000000 Resource Directory [.rsrc]
Entry 3 00000000 00000000 Exception Directory [.pdata]
Entry 4 00000000 00000000 Security Directory
Entry 5 00000000 00000000 Base Relocation Directory [.reloc]
Entry 6 00000000 00000000 Debug Directory
Entry 7 00000000 00000000 Description Directory
Entry 8 00000000 00000000 Special Directory
Entry 9 00000000 00000000 Thread Storage Directory [.tls]
Entry a 00000000 00000000 Load Configuration Directory
Entry b 00000000 00000000 Bound Import Directory
Entry c 00000000 00000000 Import Address Table Directory
Entry d 00000000 00000000 Delay Import Directory
Entry e 00000000 00000000 CLR Runtime Header
Entry f 00000000 00000000 Reserved
Sections:
Idx Name Size VMA LMA File off Algn
0 .data 000024fb 00000000 00000000 000000c0 2**0
CONTENTS, ALLOC, LOAD, DATA
SYMBOL TABLE:
[ 0](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 _binary_Lilothyn_jpg_start
[ 1](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x000024fb _binary_Lilothyn_jpg_end
[ 2](sec -1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x000024fb _binary_Lilothyn_jpg_size
... and the other:
Tommy.o: file format pei-i386
Tommy.o
architecture: i386, flags 0x00000030:
HAS_SYMS, HAS_LOCALS
start address 0x00000000
Characteristics 0x305
relocations stripped
line numbers stripped
32 bit words
debugging information removed
Time/Date Thu Jan 01 00:00:00 1970
Magic 0000
MajorLinkerVersion 0
MinorLinkerVersion 0
SizeOfCode 00000000
SizeOfInitializedData 00000000
SizeOfUninitializedData 00000000
AddressOfEntryPoint 00000000
BaseOfCode 00000000
BaseOfData 00000000
ImageBase 00000000
SectionAlignment 00000000
FileAlignment 00000000
MajorOSystemVersion 0
MinorOSystemVersion 0
MajorImageVersion 0
MinorImageVersion 0
MajorSubsystemVersion 0
MinorSubsystemVersion 0
Win32Version 00000000
SizeOfImage 00000000
SizeOfHeaders 00000000
CheckSum 00000000
Subsystem 00000000 (unspecified)
DllCharacteristics 00000000
SizeOfStackReserve 00000000
SizeOfStackCommit 00000000
SizeOfHeapReserve 00000000
SizeOfHeapCommit 00000000
LoaderFlags 00000000
NumberOfRvaAndSizes 00000000
The Data Directory
Entry 0 00000000 00000000 Export Directory [.edata (or where ever we found it)]
Entry 1 00000000 00000000 Import Directory [parts of .idata]
Entry 2 00000000 00000000 Resource Directory [.rsrc]
Entry 3 00000000 00000000 Exception Directory [.pdata]
Entry 4 00000000 00000000 Security Directory
Entry 5 00000000 00000000 Base Relocation Directory [.reloc]
Entry 6 00000000 00000000 Debug Directory
Entry 7 00000000 00000000 Description Directory
Entry 8 00000000 00000000 Special Directory
Entry 9 00000000 00000000 Thread Storage Directory [.tls]
Entry a 00000000 00000000 Load Configuration Directory
Entry b 00000000 00000000 Bound Import Directory
Entry c 00000000 00000000 Import Address Table Directory
Entry d 00000000 00000000 Delay Import Directory
Entry e 00000000 00000000 CLR Runtime Header
Entry f 00000000 00000000 Reserved
Sections:
Idx Name Size VMA LMA File off Algn
0 .data 000834fe 00000000 00000000 000000c0 2**0
CONTENTS, ALLOC, LOAD, DATA
SYMBOL TABLE:
[ 0](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 _binary_Tommy_jpg_start
[ 1](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x000834fe _binary_Tommy_jpg_end
[ 2](sec -1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x000834fe _binary_Tommy_jpg_size
The problem is that this last file (Tommy.o) loads properly, while the 1st file (Lilothyn.o) doesn't. As you can see the two are seemingly similar.
My code is extensive so i'll post the relevant parts only.
Source.cpp:
int displayFillThread(SDL_Renderer *renderer, SDL_Window *window, bool *_end) throw()
{
std::cout << "Thread initializing..." << std::endl;
SDL_Texture *texture = getTextureFromStream(&binary_Lilothyn_jpg_start, binary_Lilothyn_jpg_size, window, renderer);
if (texture == NULL)
{
std::cout << "Thread: Failed to load image - " << SDL_GetError() << std::endl;
return 1;
}
std::cout << "Thread initialized!" << std::endl;
for(int i= 10; !*_end && i < 400; i+= 100)
for(int j= 10; !*_end && j < 400; j+= 100)
{
SDL_Delay(100);
AddTextureToRederer(renderer, texture, i, j, 100, 100);
SDL_RenderPresent(renderer);
}
return 0;
}
SDL_Texture *getTextureFromStream(char binary[], unsigned int binary_size, SDL_Window *window, SDL_Renderer *renderer) throw()
{
std::cout << "Starting getTextureFromJPEGStream!" << std::endl;
// char* st = loadFileObject(binary_start, binary_end);
SDL_RWops *rw = SDL_RWFromConstMem(binary, binary_size);
std::cout << "rw loaded!" << std::endl;
SDL_Surface *tmpSurf = IMG_Load_RW(rw, 0);
//SDL_Surface *tmpSurf = SDL_CreateRGBSurfaceFrom(Lilothyn_jpg, 123, 102, 24, 96, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
if (tmpSurf != NULL)
{
SDL_Surface *surf = SDL_ConvertSurfaceFormat(tmpSurf, SDL_GetWindowPixelFormat(window), 0);
if (surf != NULL)
{
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surf);
SDL_FreeSurface(surf);
std::cout << "tmpSurf loaded!" << std::endl;
return texture;
}//*/
// SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, tmpSurf);
SDL_FreeSurface(tmpSurf);
std::cout << "surf load failed!" << std::endl;
return NULL;
}
std::cout << "tmpSurf load failed!" << std::endl;
return NULL;
}
int main(int argc, char** argv)
{
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
{
std::cout << "SDL init Error: " << SDL_GetError() << std::endl;
exit(1);
}
SDL_Window *window = SDL_CreateWindow("SDL_Test", 0, 0, _SCREEN_WIDTH_, _SCREEN_HEIGHT_, SDL_WINDOW_OPENGL | SDL_RENDERER_ACCELERATED); // SDL_WINDOW_FULLSCREEN |
if (window == NULL)
{
std::cout << "Window init Error: " << SDL_GetError() << std::endl;
exit(1);
}
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
if (renderer == NULL)
{
SDL_ShowSimpleMessageBox(0, "Renderer init error", SDL_GetError(), window);
}
//SDL_Texture *texture = getTextureFromJPEGStream(binary_Tommy_jpg_start, binary_Tommy_jpg_end, binary_Tommy_jpg_size, window, renderer);
SDL_Texture *texture = getTextureFromStream(&binary_Tommy_jpg_start, binary_Tommy_jpg_size, window, renderer);
//getTextureFromImage("Resources/Tommy.jpg", window, renderer);
if (texture == NULL)
{
SDL_ShowSimpleMessageBox(0, "Background Texture init error", SDL_GetError(), window);
return 1;
}
SDL_RenderCopy(renderer, texture, NULL, NULL);
//AddTextureToRederer(renderer, FTex, 10, 10, 100, 100);
SDL_RenderPresent(renderer);
SDL_Event event;
bool _end = false;
std::cout << "Starting Thread!" << std::endl;
std::thread thread1;
try
{
thread1 = std::thread(displayFillThread, renderer, window, &_end);
std::cout << "Thread loaded!" << std::endl;
}
catch(std::exception& e)
{
std::cout << "Thread load failed: " << e.what() << std::endl;
return 1;
}
std::cout << "main while starting!" << std::endl;
while(!_end)
{
//...
Source.h:
#ifndef SOURCE_H_
#define SOURCE_H_
static int _SCREEN_WIDTH_ = 1024;
static int _SCREEN_HEIGHT_ = 800;
extern char binary_Tommy_jpg_start;
extern unsigned int binary_Tommy_jpg_size;
extern char binary_Lilothyn_jpg_start;
extern unsigned int binary_Lilothyn_jpg_size;
int displayFillThread(SDL_Renderer *renderer, SDL_Window *window, bool *_end) throw();
SDL_Texture *getTextureFromStream(char binary[], unsigned int binary_size, SDL_Window *window, SDL_Renderer *renderer) throw();
//...
And the output:
Starting getTextureFromJPEGStream!
rw loaded!
tmpSurf loaded!
Starting Thread!
Thread loaded!
Thread initializing...
main while starting!
Note that it didn't write the second "getTextureFromJPEGStream!" neither did it appear to have thrown an exception.
It compiles with no problems whatsoever so, is it possible that the Lilothyn.o file is being created corrupted? (I have rebuilt it more than once) And/or maybe the linker isn't linking correctly?
While executing, the program simple stops responding after loading the 1st image, while trying to load the 2nd.
Thank you for the replies.
I've solved this now, the problem was the types used on the .o file.
New code is as follows.
Source.h:
extern uint8_t binary_Lilothyn_jpg_start[];
extern uint8_t binary_Lilothyn_jpg_size[];
Source.cpp
SDL_Texture *getTextureFromStream(uint8_t binary[], uint8_t binary_size[], SDL_Window *window, SDL_Renderer *renderer) throw()
{
size_t converted_size = (size_t)((void *)binary_size);
SDL_Surface *tmpSurf = IMG_Load_RW(SDL_RWFromConstMem(binary, converted_size), 0);
if (tmpSurf != NULL)
{
//...
Thanks to all the viewers, I hope this helps!
I would like to create process dump file at the moment when access violation that will not be handled occurred.
Currently, I have registered mine, unhandled exception callback with:
SetUnhandledExceptionFilter(CustomUnhandledExceptionFilter);
CustomUnhandledExceptionFilter creates dump file and prints call stack.
But this approach has one flaw - it is done when AV has already happened, AV exception is thrown and has not been handled by thread it happened in. Unhandled exception callback is called when exception is about to leave thread scope and dump created at this point has no local variables of function that exception occurred since stack pointer is lost.
Is there an way to over come this? I would like to take a look at stack of thread that got AV at the moment AV happened.
VS
#include "stdafx.h"
#include <windows.h>
#include <dbghelp.h>
LONG WINAPI MyUnhandledExceptionFilter(EXCEPTION_POINTERS *ExceptionInfo)
{
HANDLE hFile = CreateFile(
L"proc.dmp",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
MINIDUMP_EXCEPTION_INFORMATION mei;
mei.ThreadId = GetCurrentThreadId();
mei.ClientPointers = TRUE;
mei.ExceptionPointers = ExceptionInfo;
MiniDumpWriteDump(
GetCurrentProcess(),
GetCurrentProcessId(),
hFile,
MiniDumpNormal,
&mei,
NULL,
NULL);
return EXCEPTION_EXECUTE_HANDLER;
}
int _tmain(int argc, _TCHAR* argv[])
{
SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
int* p = NULL;
*p = 1;
return 0;
}
WinDbg
Microsoft (R) Windows Debugger Version 6.12.0002.633 X86
Copyright (c) Microsoft Corporation. All rights reserved.
Loading Dump File [D:\Documents\Visual Studio 2012\Projects\Test\Debug\proc.dmp]
User Mini Dump File: Only registers, stack and portions of memory are available
Symbol search path is: SRV*C:\Symbols*http://msdl.microsoft.com/download/symbols
Executable search path is:
Windows 7 Version 7600 UP Free x86 compatible
Product: WinNt, suite: SingleUserTS
Machine Name:
Debug session time: Sat Dec 15 19:29:31.000 2012 (UTC + 4:00)
System Uptime: not available
Process Uptime: not available
......................
This dump file has an exception of interest stored in it.
The stored exception information can be accessed via .ecxr.
(8d8.1084): Access violation - code c0000005 (first/second chance not available)
eax=fffffffd ebx=005d0d78 ecx=0022f070 edx=778964f4 esi=005d0d38 edi=0022f110
eip=778964f4 esp=0022edd0 ebp=0022ede0 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ntdll!KiFastSystemCallRet:
778964f4 c3 ret
0:000> .ecxr
eax=00000000 ebx=7ffdf000 ecx=0022fa30 edx=778964f4 esi=0022fcf4 edi=0022fdcc
eip=0124157c esp=0022fcf4 ebp=0022fdcc iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246
*** WARNING: Unable to verify checksum for dump.exe
dump!wmain+0x3c:
0124157c c70001000000 mov dword ptr [eax],1 ds:0023:00000000=????????
0:000> dv
argc = 0n1
argv = 0x00280e38
p = 0x00000000
0:000> kb
*** Stack trace for last set context - .thread/.cxr resets it
ChildEBP RetAddr Args to Child
0022fdcc 01241b19 00000001 00280e38 0027f9c8 dump!wmain+0x3c [d:\documents\visual studio 2012\projects\test\dump\dump.cpp # 35]
0022fe1c 01241d0d 0022fe30 76051194 7ffdf000 dump!__tmainCRTStartup+0x199 [f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c # 533]
0022fe24 76051194 7ffdf000 0022fe70 778ab495 dump!wmainCRTStartup+0xd [f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c # 377]
0022fe30 778ab495 7ffdf000 7676831a 00000000 kernel32!BaseThreadInitThunk+0xe
0022fe70 778ab468 0124107d 7ffdf000 00000000 ntdll!__RtlUserThreadStart+0x70
0022fe88 00000000 0124107d 7ffdf000 00000000 ntdll!_RtlUserThreadStart+0x1b
0:000> u .
dump!wmain+0x3c [d:\documents\visual studio 2012\projects\test\dump\dump.cpp # 35]:
0124157c c70001000000 mov dword ptr [eax],1
01241582 33c0 xor eax,eax
01241584 5f pop edi
01241585 5e pop esi
01241586 5b pop ebx
01241587 81c4cc000000 add esp,0CCh
0124158d 3bec cmp ebp,esp
0124158f e8c0fbffff call dump!ILT+335(__RTC_CheckEsp) (01241154)
0:000> !analyze -v
*******************************************************************************
* *
* Exception Analysis *
* *
*******************************************************************************
GetPageUrlData failed, server returned HTTP status 404
URL requested: http://watson.microsoft.com/StageOne/dump_exe/0_0_0_0/50cc9743/dump_exe/0_0_0_0/50cc9743/c0000005/0001157c.htm?Retriage=1
FAULTING_IP:
dump!wmain+3c [d:\documents\visual studio 2012\projects\test\dump\dump.cpp # 35]
0124157c c70001000000 mov dword ptr [eax],1
EXCEPTION_RECORD: ffffffff -- (.exr 0xffffffffffffffff)
ExceptionAddress: 0124157c (dump!wmain+0x0000003c)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 00000001
Parameter[1]: 00000000
Attempt to write to address 00000000
DEFAULT_BUCKET_ID: NULL_POINTER_WRITE
PROCESS_NAME: dump.exe
ERROR_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.
EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.
EXCEPTION_PARAMETER1: 00000001
EXCEPTION_PARAMETER2: 00000000
WRITE_ADDRESS: 00000000
FOLLOWUP_IP:
dump!wmain+3c [d:\documents\visual studio 2012\projects\test\dump\dump.cpp # 35]
0124157c c70001000000 mov dword ptr [eax],1
MOD_LIST: <ANALYSIS/>
FAULTING_THREAD: 00001084
PRIMARY_PROBLEM_CLASS: NULL_POINTER_WRITE
BUGCHECK_STR: APPLICATION_FAULT_NULL_POINTER_WRITE
LAST_CONTROL_TRANSFER: from 01241b19 to 0124157c
STACK_TEXT:
0022fdcc 01241b19 00000001 00280e38 0027f9c8 dump!wmain+0x3c [d:\documents\visual studio 2012\projects\test\dump\dump.cpp # 35]
0022fe1c 01241d0d 0022fe30 76051194 7ffdf000 dump!__tmainCRTStartup+0x199 [f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c # 533]
0022fe24 76051194 7ffdf000 0022fe70 778ab495 dump!wmainCRTStartup+0xd [f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c # 377]
0022fe30 778ab495 7ffdf000 7676831a 00000000 kernel32!BaseThreadInitThunk+0xe
0022fe70 778ab468 0124107d 7ffdf000 00000000 ntdll!__RtlUserThreadStart+0x70
0022fe88 00000000 0124107d 7ffdf000 00000000 ntdll!_RtlUserThreadStart+0x1b
STACK_COMMAND: ~0s; .ecxr ; kb
FAULTING_SOURCE_CODE:
31: int _tmain(int argc, _TCHAR* argv[])
32: {
33: SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
34: int* p = NULL;
> 35: *p = 1;
36: return 0;
37: }
38:
SYMBOL_STACK_INDEX: 0
SYMBOL_NAME: dump!wmain+3c
FOLLOWUP_NAME: MachineOwner
MODULE_NAME: dump
IMAGE_NAME: dump.exe
DEBUG_FLR_IMAGE_TIMESTAMP: 50cc9743
FAILURE_BUCKET_ID: NULL_POINTER_WRITE_c0000005_dump.exe!wmain
BUCKET_ID: APPLICATION_FAULT_NULL_POINTER_WRITE_dump!wmain+3c
WATSON_STAGEONE_URL: http://watson.microsoft.com/StageOne/dump_exe/0_0_0_0/50cc9743/dump_exe/0_0_0_0/50cc9743/c0000005/0001157c.htm?Retriage=1
Followup: MachineOwner
---------
Try using AddVectoredExceptionHandler. The thread context of the moment of exception is passed as an argument to the callback proc of this method.
To keep the exception context intact you can create the minidump from an outer process, which debugs the process of interest with DebugActiveProcess API and receives exception events as a part of debugging. Minidump creation preceding release of the debugee with ContinueDebugEvent preserves call stack and exception context.
TL;DR: is my guess of a DLL loader lock deadlock correct in this instance and how can I be sure?
I have an intermittent deadlock (50%) in some code that involves CRT time functions and National Instruments DAQmx drivers (9.3.5f2). I'm using MSVC2008 Express to create an x86 executable (typical "release" settings, can supply if required) and I'm running on Win7 Pro x64. My code uses the time functions on the main thread and starts a new thread to handle updating an analogue output voltage (on a USB-6009):
#include <iostream>
#include <ctime>
#include <windows.h>
#include <process.h>
#include <NIDAQmx.h>
HANDLE g_TerminateEvent;
extern "C" unsigned int WINAPI DacUpdateThreadRunner(void *lpParam)
{
TaskHandle taskHandle;
DAQmxCreateTask("", &taskHandle);
DAQmxCreateAOVoltageChan(taskHandle, "Dev2/ao0", "", 0.0, 3.3, DAQmx_Val_Volts, "");
DAQmxStartTask(taskHandle);
float64 sample_value = 0.0;
bool quit = false;
while (!quit)
{
DWORD wait_result = WaitForSingleObject(g_TerminateEvent, 32);
if (wait_result == WAIT_OBJECT_0) quit = true;
else
{
DAQmxWriteAnalogScalarF64(taskHandle, 1, 1.0, sample_value, NULL);
}
}
DAQmxStopTask(taskHandle);
DAQmxClearTask(taskHandle);
return 0;
}
int main(void)
{
g_TerminateEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
unsigned int m_ThreadId;
uintptr_t m_Thread = _beginthreadex(NULL, 0, DacUpdateThreadRunner, NULL, 0, &m_ThreadId);
struct tm t;
time_t tt = time(NULL);
struct tm *temp = localtime(&tt);
memcpy(&t, temp, sizeof(struct tm));
for (int i = 0; i < 10; i++)
{
std::cout << "Main thread doing stuff " << i << std::endl;
Sleep(1000);
}
SetEvent(g_TerminateEvent);
CloseHandle((HANDLE)m_Thread);
return 0;
}
It only seems to deadlock if I have the call to localtime() in the code. Looking at the debug output in MSVS it seemed to lock while the 2nd thread was loading the (many) NI DLLs (the last DLLs to be loaded before the deadlock are National Instruments\MAX\mxs.dll, National Instruments\MAX\mxsutils.dll and SysWOW64\version.dll).
In the MSVC 2008 runtime localtime maps to localtime64() and apparently it uses thread local storage under Windows in order to be threadsafe.
I used WinDbg to get the call stacks (shown below) after the application deadlocked and used the !locks command but I cannot see why there would be a deadlock as I can't see any shared resource that both threads are locking. The locks command outputs Scanned 10 critical sections but nothing else (do I need to use a checked build of Windows?).
main thread:
ChildEBP RetAddr Args to Child
0035f078 77288df4 000001d0 00000000 00000000 ntdll_77250000!NtWaitForSingleObject+0x15
0035f0dc 77288cd8 00000000 00000000 00000000 ntdll_77250000!RtlpWaitOnCriticalSection+0x13e
0035f104 772a9520 773520c0 773271ca 0035f350 ntdll_77250000!RtlEnterCriticalSection+0x150
0035f144 751a1ee1 005e0000 0035f35c bf6b8258 ntdll_77250000!LdrGetDllHandleByMapping+0x3b
0035f304 751a1fd2 0035f350 0035f348 00000002 KERNELBASE!BasepLoadLibraryAsDataFileInternal+0x4f4
0035f324 751a2221 0035f350 0035f348 00000002 KERNELBASE!BasepLoadLibraryAsDataFile+0x19
0035f360 751993ad 0035f38c 00000000 006a7eb4 KERNELBASE!LoadLibraryExW+0x18a
0035f598 75199535 0035f630 72cbc018 00000002 KERNELBASE!ConvertTimeZoneMuiString+0xe4
0035f5bc 7519966b 0035f5d8 72cbbfc4 72cbc018 KERNELBASE!ConvertTimeZoneMuiStrings+0x155
0035f688 75199729 72cbbfc0 00000001 0035f6f0 KERNELBASE!GetTimeZoneInformationRaw+0x8c
0035f698 72c58d90 72cbbfc0 bf60abfe 0035f778 KERNELBASE!GetTimeZoneInformation+0xf
0035f6f0 72c59390 bf60aa2e 0035f778 00f625f8 MSVCR90!_set_timezone+0x168
0035f720 72c59e79 01103384 00f625f8 000001cc MSVCR90!__tzset+0x2e
0035f748 72c5a0b1 00f625f8 0035f778 00000001 MSVCR90!_localtime64_s+0x9f
0035f75c 01101107 0035f778 01103384 00000001 MSVCR90!_localtime64+0x1a
0035f784 011015e9 00000001 00f61850 00f62ba8 deadlock2!main+0x57 [c:\david\dev\nitests\deadlock2\deadlock2.cpp # 60]
0035f7c8 7509339a 7efde000 0035f814 77289ef2 deadlock2!__tmainCRTStartup+0x10f [f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c # 586]
0035f7d4 77289ef2 7efde000 7732789a 00000000 KERNEL32!BaseThreadInitThunk+0xe
0035f814 77289ec5 01101731 7efde000 00000000 ntdll_77250000!__RtlUserThreadStart+0x70
0035f82c 00000000 01101731 7efde000 00000000 ntdll_77250000!_RtlUserThreadStart+0x1b
second thread:
ChildEBP RetAddr Args to Child
0276e618 77288df4 0000021c 00000000 00000000 ntdll_77250000!NtWaitForSingleObject+0x15
0276e67c 77288cd8 00000000 00000000 72c83b4e ntdll_77250000!RtlpWaitOnCriticalSection+0x13e
0276e6a4 72c42f2a 72cbbab8 0276e978 0276e6ec ntdll_77250000!RtlEnterCriticalSection+0x150
0276e6b4 72c48a70 00000007 bd23bbe2 00f69170 MSVCR90!_lock+0x30
*** ERROR: Symbol file could not be found. Defaulted to export symbols for mxsutils.dll -
0276e6ec 1b4fc523 0276e700 00000105 0276e978 MSVCR90!_getcwd+0x13
WARNING: Stack unwind information not available. Following frames may be wrong.
0276e80c 1b4fd45c 0276e81c 0276e9a4 1b5009e7 mxsutils!mxsCheckComponent+0x67c3
0276e838 1b515a05 0276e9a4 0276e978 00000000 mxsutils!mxsCheckComponent+0x76fc
0276e994 1b51542a 0276e9a4 00f619c0 0276e9b0 mxsutils!std::_Init_locks::operator=+0x1a4f
0276e9d8 1b502aa0 0276eaf0 00f69170 00f619c0 mxsutils!std::_Init_locks::operator=+0x1474
0276eb54 1b4f163f 00000001 00000001 006b0300 mxsutils!CodeProject3rdParty::mxs_mxExceptionFilter+0x320
0276eba8 1b502831 1b240000 1b529f40 00000001 mxsutils+0x163f
*** ERROR: Symbol file could not be found. Defaulted to export symbols for mxs.dll -
0276ebc8 1b2414e9 00000001 00000000 00f62540 mxsutils!CodeProject3rdParty::mxs_mxExceptionFilter+0xb1
0276edf8 1b24593c 1b240000 00000001 00000000 mxs+0x14e9
0276ee3c 1b2459f6 1b240000 0276ee68 77289950 mxs!std::_Init_locks::operator=+0x44c
0276ee48 77289950 1b240000 00000001 00000000 mxs!std::_Init_locks::operator=+0x506
0276ee68 7728d8c9 1b2459d8 1b240000 00000001 ntdll_77250000!LdrpCallInitRoutine+0x14
0276ef5c 7728d78c 00000000 75717046 00000000 ntdll_77250000!LdrpRunInitializeRoutines+0x26f
0276f0c8 7728c4d5 0276f12c 0276f0f4 00000000 ntdll_77250000!LdrpLoadDll+0x4d1
0276f100 751a2288 0276f0f4 0276f144 0276f12c ntdll_77250000!LdrLoadDll+0xaa
*** ERROR: Symbol file could not be found. Defaulted to export symbols for nidmxfu.dll -
0276f13c 6dd8b3ad 00000000 00000000 006b03fc KERNELBASE!LoadLibraryExW+0x1f1
0276f568 6dd8b4d3 0276f86c 6ded4a38 0276f92c nidmxfu!nNIMSAI100::tFilterPreferences::~tFilterPreferences+0x65cd
0276f584 6dc39d62 0276f6cc 0276f728 0276f870 nidmxfu!nNIMSAI100::tFilterPreferences::~tFilterPreferences+0x66f3
00000000 00000000 00000000 00000000 00000000 nidmxfu!nNIMS100::tAttributeDatabase::getAttributeValueForString+0x12432
My guess is that the main thread has locked an internal lock in the MSVCRT and then went to load a DLL which it cannot because thread 2 has a DLL loader lock. Thread 2 tries to use getcwd() from the MSVCRT which then results in the deadlock. Is that an accurate assessment? If not, how could I go about getting more information to make sure?
I could probably work around it by re-ordering some of the code (e.g. use wxDateTime or the NI code from the main thread to pre-load the DLLs) if I was confident that was the problem. However, I don't want to just hide it and have it re-appear and bite me later.
So is there a way for me to verify what has caused the deadlock in this case?
Your diagnosis is correct. tzset holds a lock while calling LoadLibrary. Meanwhile, _getcwd is waiting for that same lock. mxsutils is calling _getcwd from inside its DllMain. Like most functions, _getcwd is not safe to call from DllMain. A temporary workaround would be to make a dummy call to localtime from main before you create any threads. A long-term fix would be to change msxutils so it doesn't call unsafe functions from inside DllMain.
I notice that you are calling wxDateTime::Now() without doing any initialization of the wxWidgets system. My guess would be that wxDateTime::Now() is relying on something that is initialized when you do a normal wxWidgets initialization. Have you tried not even starting your other thread, but simply checking that wxDateTime::Now() works OK like this?
I also notice that you are using wxWidgets v2.9.2. Recommend you upgrade to v2.9.4. Apart from many improvements that might help your situation, these is a fix to a bug in wxDateTime. Might not help with current problem, but will fix a problem you don't yet know you have