Malloc () returns an address that I cannot access

I have a C ++ program that calls some C routines created by Flex / Bison.

When I target the Windows 8.1 64-bit platform, at runtime I make the following exception:

Unhandled exception at 0x0007FFFA70F2C39 (libapp.dll) in application.exe: 0xC0000005: Access violation writing location 0x000000005A818118. 

I traced this exception with the following code snippet:

 YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; // This access is what throws the exception } 

For reference, in another place in the code (also created by Flex / Bison), we have:

 typedef struct yy_buffer_state *YY_BUFFER_STATE; struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; char *yy_buf_pos; yy_size_t yy_buf_size; // ... other fields omitted, // total struct size is 56 bytes } static void *yy_flex_alloc( yy_size_t size ) { return (void *) malloc( size ); } 

I turned to the malloc call and noticed that malloc itself returns the address 0x000000005A818118 . I also checked errno , but it is not installed after calling malloc .

My question is: why does malloc give me an address that I don’t have access to, and how can I get it to specify the correct address?

Note. I observe this behavior only on the 64-bit version of Windows 8.1. It runs with other 32-bit versions of Windows, as well as the 32-bit version of Windows 7.

Compilation Information: I am compiling this on a 64bit Windows 8.1 machine using Visual Studio 2012.

If this helps, here is the parsed code:

 // b = (YY_BUFFER_STATE) yy_flex_alloc( ... ) 0007FFFA75E2C12 call yy_flex_alloc (07FFFA75E3070h) 0007FFFA75E2C17 mov qword ptr [b],rax // if ( ! b ) YY_FATAL_ERROR( ... ) 0007FFFA75E2C1C cmp qword ptr [b],0 0007FFFA75E2C22 jne yy_create_buffer+30h (07FFFA75E2C30h) 0007FFFA75E2C24 lea rcx,[yy_chk+58h (07FFFA7646A28h)] 0007FFFA75E2C2B call yy_fatal_error (07FFFA75E3770h) // b->yy_buf_size = size 0007FFFA75E2C30 mov rax,qword ptr [b] 0007FFFA75E2C35 mov ecx,dword ptr [size] 0007FFFA75E2C39 mov dword ptr [rax+18h],ecx 

Thanks!

+6
source share
2 answers

The real answer is:

When you compile the generated Flex .c source in Visual Studio, it does not include stdlib.h (where malloc is defined as returning void * ) and Visual Studio accepts a specific definition where malloc returns int . (I think for some compatibility)

Prints of video studios:

'warning C4013:' malloc 'undefined; assuming extern returns int 'sizeof (int) == 4, but values ​​in pointers on x64 systems often exceed 4 bytes

Thus, your pointer is simply reduced to 4 bytes.

This problem seems to only appear on x64 bits of visual studio in .c files.

So, the solution will be - just enable stdlib.h yourself or define some macros that will lead to the generation of the generated generated source, including stdlib.h .

+3
source

Under normal circumstances, malloc () will return a pointer to the actual available memory or NULL. So your symptoms indicate that malloc () is behaving in an unspecified way. I suspect that at some point earlier your program wrote outside of its actual memory, thereby distorting the data structures used inside malloc ().

Examining your process with a run-time memory analysis tool will help you identify the source of the problem. [Cm. This is a post for suggestions on memory analysis tools for Windows: Is there a good Valgrind replacement for Windows? ]

+2
source

Source: https://habr.com/ru/post/972100/


All Articles