2014-07-11 10 views
6

Ich habe ein C++ - Programm, das einige C-Routinen aufruft, die von Flex/Bison generiert werden.malloc() gibt die Adresse zurück, auf die ich nicht zugreifen kann

Wenn ich einen Windows 8.1 64-Bit-Plattform Ziel, schlug ich die folgende Ausnahme zur Laufzeit:

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 
} 

Zum Vergleich:

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

ich diese Ausnahme auf das folgende Stück Code verfolgt , woanders im Code (auch erzeugt von Flex/Bison), haben wir:

ich verfolgen d zurück zum malloc Anruf und beobachtet, dass malloc selbst die Adresse 0x000000005A818118 zurückgibt. Ich habe auch überprüft errno, aber es ist nicht nach dem Anruf auf malloc festgelegt.

Meine Frage ist: Warum gibt malloc mir eine Adresse, die ich nicht zugreifen kann, und wie kann ich es mir eine korrekte Adresse geben lassen?

Hinweis: Ich beobachte dieses Verhalten nur in Windows 8.1 64-Bit. Es geht mit anderen 32-Bit-Windows-Varianten sowie Windows 7 32-Bit.

Compilation Informationen: Ich habe dies auf einer Visual Studio 2012

Wenn es hilft, hier mit 64-Bit-Windows 8.1 Maschinen am Kompilieren der zerlegten 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 

Dank!

+0

Ich wiederholte dieses Segment mehrmals, 'malloc' gibt entweder' 00000000 -------- 'oder' FFFFFFFF -------- 'für die Adresse des" zugewiesenen "Speicherplatzes zurück. –

+0

Höchstwahrscheinlich ist es einem anderen, scheinbar nicht verwandten Teil des Codes gelungen, den Heap zu beschädigen (z. B. durch Überlaufen eines Heap-allokierten Puffers). Der Teil des Codes, den Sie betrachten, ist ein unschuldiges Opfer. –

+0

Ihr Programm befindet sich im Heap Corruption-Szenario. Sie können den Beitrag in diesem Artikel verweisen: http://stackoverflow.com/a/22074401/2724703 –

Antwort

3

Die wirkliche Antwort ist:

Wenn Sie Flex-generierte .c Quelle in Visual Studio kompilieren, ist es nicht stdlib.h ist (wo malloc definiert als zurückgeben void *) und Visual Studio nimmt einige eigene Definition, wobei mallocint zurückgibt. (Ich denke, es ist für eine Art von Kompatibilität)

Visual Studio druckt:

‚C4013 Warnung: 'malloc' undefined; unter der Annahme, extern Rückkehr int‘ sizeof (int) == 4, jedoch Werte in Zeigern auf x64-Systemen überschreiten häufig 4 Byte

So Ihre Zeiger auf niedrigen 4 Byte gerade geschnitten.

Es scheint, dieses Problem erscheint nur in x64 Bits Visual Studio in .c Dateien.

So wird, Lösung sein - nur stdlib.h selbst gehören, oder einige Makros definieren, die einschließlich stdlib.h in flex-generierte Quelle führen.

+0

Ich kann mir nur vorstellen, wie viele Stunden Sie mich gerade mit dieser Antwort gerettet haben. – Rafal

2

Unter normalen Umständen wird malloc() einen Zeiger auf gültigen, zugänglichen Speicher oder sonst NULL zurückgeben. Ihre Symptome zeigen also an, dass sich malloc() unspezifisch verhält. Ich vermute, dass Ihr Programm zu einem früheren Zeitpunkt außerhalb seines gültigen Speichers geschrieben hat, wodurch die Datenstrukturen, die intern von malloc() verwendet werden, korrumpiert werden.

Wenn Sie Ihren Prozess mit einem Laufzeitspeicheranalyse-Tool untersuchen, sollten Sie die Ursache des Problems ermitteln. [Siehe Beitrag für Anregungen auf Speicher-Analyse-Tool für Windows: Is there a good Valgrind substitute for Windows?]

+0

Danke, das ist ein guter Vorschlag. Ich werde es untersuchen, sobald ich einen Windows 8-kompatiblen Lecksucher installieren kann ... Ich habe Valgrind jedoch auf der Linux-Version dieser Anwendung ausgeführt, und es schien nichts Verdächtiges zu geben. Zu dem Zeitpunkt, an dem dieser Teil des Codes ausgeführt wird, habe ich nur 4 Bytes verloren (aufgrund einer Bibliotheksfunktion, die ich nicht ändern kann ...) –