LHA圧縮ファイルの解凍でアクセス違反 – 固定ページ 3 – プログラミング – Home

LHA圧縮ファイルの解凍でアクセス違反
 
通知
すべてクリア

[解決済] LHA圧縮ファイルの解凍でアクセス違反

固定ページ 3 / 4

ロマ
 ロマ
(@ロマ)
ゲスト
結合: 18年前
投稿: 170
 

> 実行中に例外が出るのかと思っていました。

誤解を生む表現でした。
「実行中に例外が出て、中断してしまうのかと思っていました。」
のつもりてす。


返信引用
ロマ
 ロマ
(@ロマ)
ゲスト
結合: 18年前
投稿: 170
 

連投すまんです。

Debugで実行する前に、Debugメニューの例外で
Win32Exceptions/C0000005/例外がスローされたとき/デバッガーで中断
をチェックすると
例外が生じた箇所でプログラムの実行は中断されるようになります。

その後、プログラムを実行し、例外で中断すると、
呼び出し履歴を出すことができます。

呼び出し履歴に
UnlhaExtractMemを使用している関数が表示され、
コンテキストメニューでソースコードに移動したときに、
UnlhaExtractMemに矢印が出ていれば、
UnlhaExtractMemから例外が発生していることになります。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

> LPBYTE g_buf = (LPBYTE)GlobalAlloc(GMEM_FIXED, g_len+1);
> としてやってみたのですが、やはりアクセス違反となりました。
> 第1変数は、GHND、GPTR、GMEM_MOVEABLE も試しました。
アクセス違反になりましたか。
しかし、new文で毎回初期化するよりもいいと思います。


返信引用
確変
 確変
(@確変)
ゲスト
結合: 13年前
投稿: 35
Topic starter  

ロマ様
有り難うございます。
未熟者で済みません。呼び出し履歴が出ました。

KernelBase.dll!760e7ee4()
[下のフレームは間違っているか、または見つかりません。KernelBase.dllに対して読み
込まれたシンボルはありません。]
UNLHA32.DLL!10010258()
・・・同様の5行・・・
user32.dll!771df910()
・・・同様の2行・・・

となっており、「利用可能なソースがありません」というタグ・ウィンドウが出ます。
呼び出し履歴ウィンドウで右クリックして出るメニューの「ソースコードへの移動」は
グレー表示になっています。

「続行」→「デバッグ中のプログラムへ例外を渡しますか?」→「はい」で先へ進み終
了します。解凍は正しく行われています。

●話変わって
「猫でもわかるプログラミング」に UNLHA32.DLL を使った APIプログラムのサンプルが
あります。関数Unlha() による圧縮プログラムです。
http://www.kumei.ne.jp/c_lang/sdk3/sdk_272.htm
これをそっくりそのまま、VS2010でAPIプログラムとして作り、デバッグしたところ、ア
クセス違反は生じませんでした。
UnlhaExtractMem() 関数ではないので何とも言えませんが、も少し調べようと思ってい
ます。


返信引用
確変
 確変
(@確変)
ゲスト
結合: 13年前
投稿: 35
Topic starter  

VS2010でAPIアプリとして作った関数Unlha() による圧縮プログラムが、デバッグでアク
セス違反を生じませんでした。
そこで今度は、MFCアプリとして関数Unlha() による圧縮および解凍プログラムを作り、
デバッグしてみました。
念のため、UNICODE とマルチバイト文字セットの両方を確かめました。
やはり、すべての場合にアクセス違反が生じます。
圧縮および解凍は正しく行われます。

VSのデバッグ機能の誤診断と考えることはできないでしょうか。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

> VSのデバッグ機能の誤診断と考えることはできないでしょうか。
うーん、
 なにか思い当たる決定的な情報があれば誤診断としてマイクロソフトに
問い合わせることが出来ますが。外れれば調査という名目で有料になります。
 
VC2005のときは、OSはXPですね。
UNLHA32.DLLでW32APIからMFCに移行するときの注意事項はないですか。
作者にメールで聞いてみたらどうでしょうか。
>HARC hArc
>HWND m_hWnd
>INDIVIDUALINFO g_ii;
           #まだ他にもあるかもです。
はグローバル変数にして、何処の関数・クラスでも値が読めるように
しておくのがいいと思います。
INDIVIDUALINFOにはいろいろな情報が含まれているみたいですね。
異常な値になっているのはないか調べてみるのもいいかも知れないです。


返信引用
確変
 確変
(@確変)
ゲスト
結合: 13年前
投稿: 35
Topic starter  

> UNLHA32.DLLでW32APIからMFCに移行するときの注意事項はないですか。

> INDIVIDUALINFOにはいろいろな情報が含まれているみたい・・・

UNLHA32.DLL に同梱されているドキュメントを全部もう一度読み直してみました。
次の一文が気になります。
「UNLHA32.DLL の各 API が使用している構造体については,
すべてワードアラインメントをオフにしておく必要がありますので,
注意してください。」
ワードアラインメントのオン/オフはどうすればいいか解らないので、何もしていませ
ん。
影響あるでしょうか?


返信引用
確変
 確変
(@確変)
ゲスト
結合: 13年前
投稿: 35
Topic starter  

VSで、「プロジェクト」→「プロパティ」の中に「構造体メンバーのアライメント」と
いう項目を見つけました。
値は「既定」となっています。
他に、「1バイト」「2バイト」「4バイト」「8バイト」「16バイト」が選択できます。
全部やってみましたがアクセス委花同じく生じました。


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

とりあえずウチでは以下のプログラムは期待通りに動く模様。
Windows XP SP3 + Visual Studio 2008 Express + UNLHA32.DLL Ver 2.67a
# 現 LHA API って同時に1つしか開けないとかごみ以下なのね・・・

#define LZHFN _T(C:\\hoge\\aaj.lzh)
int _tmain() {
HARC hlzh=UnlhaOpenArchive(0, LZHFN, 0);
INDIVIDUALINFO inf;
int r;
BYTE* buf=0;
for (
r=UnlhaFindFirst(hlzh, _T(*), &inf);
r==0;
/*r=UnlhaFindNext(hlzh, &inf)*/
r= -1
) {
_tprintf(_T(%s %d->%d\n), inf.szFileName, inf.dwOriginalSize,
inf.dwCompressedSize);
}
UnlhaCloseArchive(hlzh);
_TCHAR cmd[256];
_stprintf_s(cmd, _T(%s %s), LZHFN, inf.szFileName);
buf=new BYTE[inf.dwOriginalSize];
DWORD sz;
int result=UnlhaExtractMem(0, cmd, buf, inf.dwOriginalSize, 0, 0, &sz);
_tprintf(_T(%.*S\n), inf.dwOriginalSize, buf);
return 0;
}

とりあえず試してみた範囲では「初回例外が発生しました」が出るのは、
UnlhaExtractMem がアーカイブファイルを開けない場合
と思われる。

UnlhaOpenArchive は開けない場合にきっちりエラーを返すが
UnlhaExtractMem はエラー処理を手抜きしているのか、例外投げてくる...

Windows Vista/7 の場合 UAC の関係で一部の保護ディレクトリ上にある
ファイルを開くには管理者権限が必要なわけだが
C:\ (ルートディレクトリ) C:\Windows C:\Program Files など
その辺に何かあるかもしれない。
アーカイブファイルを非保護ディレクトリにおいてみるとかとか。


返信引用
確変
 確変
(@確変)
ゲスト
結合: 13年前
投稿: 35
Topic starter  

API アプリではアクセス違反はありません。
MFC アプリで、発生したと表示されます。
ファイルを開くことは出来ています。解凍は正しくされています。


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

MFC ダイアログベースアプリでもうまく動いたけどなぁ
コードは先に掲げたものを OnBnClickedTestbtn1() にほぼそのままいれただけ。
(_tprintf → TRACE 程度の変更)
Win7 64bit SP1 + VS2005 Pro の MFC App x86 + UNLHA32.DLL 2.67a

なぜだかはよくわからないが、このイベントハンドラの中で記述した
UnlhaOpenArchive - UnlhaCloseArchive の近辺にブレイクポイントを置くと
それだけで実行時にアクセスエラーが出るが・・・
> unlhadlg.exe の 0x040ef66f でハンドルされていない例外が発生しました:
> 0xC0000005: Access violation
ブレイクポイントを置かないとか、置いても UnlhaCloseArchive の後ならば問題なし
# 詳細調べる気なし

よくありがちなシナリオとしては
・ Windows 自体の更新がなされていない (Win 7 なら SP1 が出てる)
・ Visual Studio の更新がなされていない (VS2010 なら SP1 が出てる)
・ UNLHA32.DLL と UNLHA32.LIB のバージョンが不整合している
 (コピーし忘れた、上書きしちゃったなど)
・カレントディレクトリが(プログラマの勝手な想定と)違う
とか?

「初回例外」が発生しても unlha32.dll 中で catch され正しく始末されているなら
それは「仕様」であって問題ないと判断していい。
もっともウチでは初回例外出てないんだが。


返信引用
確変
 確変
(@確変)
ゲスト
結合: 13年前
投稿: 35
Topic starter  

tetrapod様

ご親切に有り難うございます。
教えて戴いたコードをそっくりそのままで、API アプリおよび MFC アプリを作り、デバ
ッグしてみました。
どちらの場合もアクセス違反が発生します。
解凍は正しく行われます。

関数 Unlha() の場合は、API アプリではOKで、MFC アプリでアクセス違反が出ます。
何度も確認しました。
VS2010 を再起動した直後や Win 7 を再起動した場合等色々やってみました。
自分でインストールした常駐ソフト(複数)もアンインストールしました。

Windows 7 SP1、VS2010 SP1 です。
UNLHA32.DLL と UNLHA32.LIB のバージョンの不整合はありません。
> ・カレントディレクトリが(プログラマの勝手な想定と)違う
関数 Unlha() のときに生成されるファイルの場所(フォルダ)から見て、これはないと
思います。

整理すると:
関数 UnlhaExtractMem() 関数 Unlha()
API アプリ アクセス違反あり OK
MFC アプリ アクセス違反あり アクセス違反あり

微妙なところでしょうか。

--------------
「構造体のアラインメントをオフにする」とは、メモリに隙間なく詰め込む、つまり
プロジェクトの設定を「1バイト」にするということかなと考えました。
設定が「既定」(多分8バイト)でも「1バイト」でも、結果は同じ。


返信引用
確変
 確変
(@確変)
ゲスト
結合: 13年前
投稿: 35
Topic starter  

構造体 INDIVIDUALINFO の各項目には、正しい値が格納されています。


返信引用
ロマ
 ロマ
(@ロマ)
ゲスト
結合: 18年前
投稿: 170
 

UNLHA32.DLL fileversion=2.67.1.2 のバグですね。

UNICODEビルドで追ってみると
このdllが0x010000000にロードされた場合、
0x010003B7C xor ecx,ecx
このecxはlstrcpynWの2番目の引数になり、例外発生。
lstrcpynWは、例外をつぶしているので外に出ない。

その他
このテストに使用したLZHファイルは 多分DOSで作成した古いものですが、
INDIVIDUALINFO::dwCompressedSizeに解凍後のサイズが入っていました。


返信引用
ロマ
 ロマ
(@ロマ)
ゲスト
結合: 18年前
投稿: 170
 

間違い、訂正版です。

UnlhaExtractMemでの例外は
UNLHA32.DLL fileversion=2.67.1.2 のバグですね。

UNICODEビルドで追ってみると
このdllが0x10000000にロードされた場合、
0x10003B7C xor ecx,ecx
このecxはlstrcpynWの2番目の引数になり、例外発生。
lstrcpynWは、例外をつぶしているので外に出ない。

その他
このテストに使用したLZHファイルは 多分DOSで作成した古いものですが、
INDIVIDUALINFO::dwCompressedSizeに解凍後のサイズが入っていました。


返信引用
固定ページ 3 / 4

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました