Ketika pemrograman kadang-kadang hal-hal rusak. Anda membuat kesalahan dan program Anda mencoba membaca dari alamat yang salah.
Satu hal yang menonjol bagi saya bahwa seringkali pengecualian itu seperti:
Access violation at address 012D37BC in module 'myprog.exe'. Read of address 0000000C.
Sekarang saya melihat banyak log kesalahan dan apa yang menonjol bagi saya adalah: 0000000C. Apakah ini alamat "khusus"? Saya melihat pelanggaran akses lainnya dengan pembacaan yang buruk tetapi alamatnya tampak acak, tetapi yang ini terus kembali dalam situasi yang sama sekali berbeda.
windows
error-handling
error-messages
Pieter B
sumber
sumber
0000000C
itu jauh lebih umum daripada00000008
, tetapi tidak ada jawaban yang tampaknya sama sekali: /System.Runtime.CompilerServices.RuntimeHelpers.OffsetToStringData
adalah12=0x0C
alasan mengapa offset ini lebih umum.Jawaban:
00000000
adalah alamat khusus (penunjuk nol).0000000C
hanya apa yang Anda dapatkan ketika Anda menambahkan offset 12 ke pointer nol, kemungkinan besar karena seseorang mencoba untuk mendapatkanz
anggota struktur seperti yang di bawah ini melalui pointer yang sebenarnya nol.sumber
Di Windows adalah ilegal untuk melakukan dereferensi seluruh halaman pertama dan terakhir , dengan kata lain 64 KiB pertama atau terakhir dari memori proses (rentang
0x00000000
ke0x0000ffff
dan0xffff0000
ke0xffffffff
dalam aplikasi 32-bit).Ini untuk menjebak perilaku undereferencing dari pointer nol atau indeks ke dalam array nol. Dan ukuran halaman adalah 64 KiB sehingga Windows hanya harus mencegah halaman pertama atau terakhir ditetapkan rentang yang valid.
Ini tidak akan melindungi terhadap petunjuk yang tidak diinisialisasi yang dapat memiliki nilai apa pun (termasuk alamat yang valid).
sumber
Adapun mengapa
0x0C
tampaknya lebih umum daripada0x08
(apakah itu benar-benar? Saya tidak tahu; dan dalam jenis aplikasi apa?), Ini mungkin ada hubungannya dengan pointer tabel metode virtual. Ini benar-benar lebih dari komentar (menebak-nebak massa :), tetapi ini agak lebih besar, jadi begini ... Jika Anda memiliki kelas dengan metode virtual, bidangnya sendiri akan digeser oleh0x04
. Misalnya, kelas yang mewarisi dari kelas virtual lain mungkin memiliki tata letak memori seperti ini:Apakah ini skenario umum, atau bahkan dekat? Saya tidak yakin. Namun, perhatikan bahwa dalam aplikasi 64-bit, ini bisa menjadi lebih menarik ketika digeser ke
0x0C
nilai:Jadi sebenarnya ada banyak kasus di mana aplikasi mungkin memiliki tumpang tindih yang signifikan dalam offset null-pointer. Ini mungkin bidang pertama dalam kelas anak, atau penunjuk tabel metode virtual - diperlukan setiap kali Anda memanggil metode virtual apa pun, jadi jika Anda memanggil metode virtual pada
null
penunjuk, Anda akan mendapatkan pelanggaran akses pada Offset VMT. Prevalensi nilai khusus ini mungkin ada hubungannya dengan beberapa API umum yang menyediakan kelas yang memiliki pola pewarisan yang serupa, atau lebih mungkin, antarmuka tertentu (sangat mungkin untuk beberapa kelas aplikasi, seperti game DirectX). Mungkin saja bisa melacak beberapa penyebab umum sederhana seperti ini, tetapi saya cenderung menyingkirkan aplikasi yang melakukan null dereferencing dengan cepat, jadi ...sumber