2016-07-19 14 views
0

Der Funktionsaufruf zu mmap64() ist wie folgt:mmap64() funktioniert in Red Hat 6.6, aber nicht in Red Hat 7.2

addr = (unsigned char*) mmap64(NULL, regionSize, PROT_READ|PROT_WRITE, MAP_SHARED, FileDesc, (unsigned long long)regionAddr); 

Die Argumente haben in der Regel Werte wie folgt:

regionSize = 0x20000; 
FileDesc = 27; 
regionAddr = 0x332C0000; 

Offensichtlich sind diese Werte im Code nicht fest codiert, aber ich möchte Ihnen nur zeigen, was die typischen Werte für sie sind.

Das Problem:

mmap64() -Aufruf funktioniert perfekt in Red Hat Linux 6.6, Kernel-Version: 2.6.32-504.16.2.el6.x86_64. Es schlägt in Red Hat Linux 7.2, Kernel-Version: 3.10.0-327.13.1.el7.x86_64 fehl.

Kein Unterschied in Code, soweit ich weiß.

Das zurückgegebene Errno ist "ungültiges Argument" oder errno # 22 (EINVAL). Mit Blick auf diese Referenz http://linux.die.net/man/3/mmap64, ich sehe 3 Possiblilities für die EINVAL Fehler:

  1. Wir mögen es nicht Adr, Länge oder Offset (beispielsweise sind sie zu groß ist, oder nicht auf einer Seitengrenze ausgerichtet). -> wahrscheinlich Schuldige in meiner Situation.
  2. (seit Linux 2.6.12) Länge war 0. -> Unmöglich, überprüft Länge (RegionSize) Wert im Debug-Druck, es war 0x20000.
  3. Flags enthielten weder MAP_PRIVATE noch MAP_SHARED oder enthielten beide Werte. -> Kann nicht so sein, wie Sie von meinem Funktionsaufruf sehen können, nur MAP_SHARED Flag wurde als Argument angegeben.

So bin ich im Moment fest. Ich bin mir nicht sicher, wie das zu debuggen ist. Dieses Problem ist zu 100% reproduzierbar. Hat jemand Tipps, was sich zwischen den beiden OS-Versionen geändert haben könnte?

+1

Warum einfach 'mmap()' ohne das Suffix verwenden, wenn Sie ausführbare 64-Bit-Dateien erstellen? Macht das für Ihr Problem einen Unterschied? Sind Sie sicher, dass der von Ihnen angegebenen Region bereits nichts zugewiesen ist? Was würde passieren, wenn Sie 'mmap64()' wählen würden, wo der Speicher abgelegt werden soll? –

+3

Das letzte Argument wird in der Synopsis als 'offset' bezeichnet ([' mmap64() '] (http://linux.die.net/man/3/mmap64)), und: _'offset' muss ein Vielfaches von sein die Seitengröße, wie sie von 'sysconf (_SC_PAGE_SIZE) zurückgegeben wird. ._ Ist Ihr Wert ein Vielfaches der Seitengröße? Es sieht für mich so aus, als hätte es zu wenige nachfolgende Nullen im Hex (ein Vielfaches von 512, nicht von 4K oder größer). –

Antwort

3

Übertragung von Kommentaren in eine Antwort (wobei einige Kommentare als nicht relevant beschnitten wurden).

Warum nicht einfach mmap() ohne das Suffix verwenden, wenn Sie ausführbare 64-Bit-Dateien erstellen? Macht das für Ihr Problem einen Unterschied?

Allerdings denke ich, Ihr Problem ist, was Sie regionAddr anrufen. Das letzte Argument zu mmap64() wird offset in der Synopse genannt, und:

offset must be a multiple of the page size as returned by sysconf(_SC_PAGE_SIZE) .

Ist Ihr Wert regionAddr ein Vielfaches der Seitengröße? Es sieht für mich so aus, als hätte es zu wenige nachfolgende Nullen im Hex (es ist ein Vielfaches von 512, aber kein Vielfaches von 4K oder größer).


Beachten Sie, dass die Frage, die ursprünglich einen anderen Wert auf dem Display für regionAddr hatte - auch die Kommentare unten.

regionAddr = 0x858521600; 

and

addr = (unsigned char*) mmap64(NULL, regionSize, PROT_READ|PROT_WRITE, MAP_SHARED, FileDesc, (unsigned long long)regionAddr); 

Mit den überarbeiteten Informationen (dh der Wert in regionAddr0x332C0000 oder dezimal 828521600 ist), ist es weniger als offensichtlich, was schief läuft.

+0

Danke für den Tipp. sysconf (_SC_PAGE_SIZE) = 4096. Der Offset ist 789315584 (0x2F0C0000) beim ersten Versuch, 853278720 (0x32DC0000) beim zweiten Versuch. Es ist ein Vielfaches der Seitengröße (es sei denn meine Mathematik ist falsch). Ich grabe tiefer in den Offset, weil es das einzige Ding ist, das hier schief gehen könnte. – Splaty

+1

Das ist nicht, was die Frage sagt: 'regionAddr = 0x858521600;' und 'addr = (vorzeichenloses Zeichen *) mmap64 (NULL, regionSize, PROT_READ | PROT_WRITE, MAP_SHARED, FileDesc, (unsigned long long) regionAddr);'. Sie können richtig sein, dass Ihr realer Code in Ordnung sein sollte (sowohl '0x2F0C0000' als auch' 0x32DC0000' sind auf 256 KiB-Grenzen ausgerichtet), aber wir können Ihnen nicht helfen, wenn Sie uns den echten Code nicht zeigen. –

+0

Ja, ich habe einen Fehler in meiner ursprünglichen Frage gemacht. regionAddr sollte dezimal 858521600 (0x332C0000) sein. Über den echten Code ist es kompliziert und proprietär. Ich habe keine gute Idee, wie ich das zu einer guten Frage machen kann. Ich werde tiefer auf das Offset-Argument eingehen, da ich glaube, dass dies das einzige Argument ist, das hier falsch laufen könnte. Gibt es eine Möglichkeit für mmap(), einen anderen Fehler als "ungültiges Argument" zum Debuggen anzugeben? – Splaty

Verwandte Themen