HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2020
0510
vload_start からの vload_get でシステムエラーになる現象について4解決


リンク

2020/5/10(Sun) 12:33:04|NO.90322

お世話になります。
自作ゲームでセーブデータを扱うために、vload系命令を利用しています。
「セーブデータが壊れてゲームが落ちた」という連絡があり、(おそらくは何かが壊れている)データファイルを受け取りました。
調べて見ると、vload_start からの vload_get をした行で、エラー1(システムエラー)となり、報告の通りにソフトが落ちることを確認しました。
データファイルの最初のほうをバイナリエディタで確認してみましたが、壊れていないセーブデータと区別が付かず、どこが壊れているのか、ファイルを見ただけではどうにも分かりませんでした。
お聞きしたいことは以下です。
- vload_getがシステムエラーを出す原因として考えられることはなんでしょうか?dllがメモリオーバーランなどでaccess violationを出したとかでしょうか?それとも、明示的にエラー1を帰すコードがどこかに入っていますか?
- このへんを解析できそうな資料はどこかにありませんでしょうか?
データファイルの大部分は生きていそうなので、できればセーブデータを復旧させてあげたいです。
よろしくお願いします。



この記事に返信する


mikumo

リンク

2020/5/10(Sun) 16:28:28|NO.90323

エラーの原因についてはさっぱりですが…
いくつか考えられる手段を挙げてみます

1.
(すでに行っているかもしれませんが)
新しいスクリプトファイルからそのセーブデータに対してvload, vgetを実行して、同じようなエラーが出るか確かめてみる。

2.
Visual Studioのデバッグ実行を使う
ここから
http://dev.onionsoft.net/trac/openhsp/browser/trunk/plugins
hspdaのソースをダウンロードして、
こちらのページ
http://fe0km.blog.fc2.com/blog-entry-118.html
の#プラグインのデバッグの仕方に書かれている方法でvload_get関数あたりからステップ実行してみる。
(VS Community 2019でできました)

内部エラーが出た以上HSPのコードのどこかで例外が投げられた可能性が高い(と思う)ので、その場所を突き止めれば何らかの手掛かりになるかもしれません。

3.
(最後の手段ですが)ソースを参考にバイナリデータを直接読み出す(PValをもつHSP3VARFILEDATA構造体が変数の個数分並んだ構造をしている


こんなことしなくてもエラーの原因の見当がつくかたがいらっしゃるかもしれませんが…



3k(みけ)

リンク

2020/5/10(Sun) 16:37:58|NO.90324

> - vload_getがシステムエラーを出す原因として考えられることはなんでしょうか?

エラー -1 はHSP内のエラーでHSPERR_UNKNOWN_CODEですが、これは下記の2ケースで発生します。

〇HSPのコード内での明示的なエラー
 ※今はcode_get()内での単一の項目の評価時にのみ発生させるコードがないです。
 そしてそれが発生するのは大きく分けて、コードジェネレータ(hspcmp)のバグが、何らかの理由でメモリ的にバイトコードが壊れているか、の2択ですかね。
 前者はあまり考えられませんが、後者も結構ピンポイントでメモリアクセスしないといけないので、あまり現実的ではないですね。

〇HSP以外で発生した例外全て
 より正確には、HSP側が知らない例外(つまり、HSP内で発生させてない例外)です。
 この種の例外は通常はC++レイヤーで発生しうるものですが、他にOSレイヤー、ハードウェアレイヤーの例外も含まれたり含まれなかったりします。
 しかし、低レイヤーの例外はパフォーマンスやセキュリティも関係するため、含まれる・含まれないを決めるのはコンパイラです。
 もっと具体的にはコンパイル時の引数で決まったりするものなのですが、今のHSPでどうなってたかはちょっと確認しないと分からないです。
 しかしHSPのランタイムEXEのビルドはクローズドなので…。

ちなみに、hsp3.6b1で下記のようにnullアクセスさせてみたら何もいわずにしんだので、少なくともnullアクセスのAccessViolationは補足されてなさそうな雰囲気です。


dupptr a, 0, 16, vartype("int") a(0) = 10

> - このへんを解析できそうな資料はどこかにありませんでしょうか?

解析できる資料…かどうかは分かりませんが、vload/vsave系が含まれるプラグインはhspdaで、これのソースコードはOpenHSPでいうとplugins/win32/hspdaにあたります。
おそらくコード追うのが一番早いとは思いますが、これはプラグイン形式での提供になり、かつHSP内の変数へのアクセスとなるため、HSP内部に依存した処理が多くコード読むだけでは簡単ではないように見えます。

――――――――――
今回の件だと、どこが悪いかは聞いた報告からだとかなり調査が難しいので、せめて実際に失敗するデータ等がないと非常に厳しいように思います。
あるいは、それも難しいのであればご自分でhspdaやHSPのランタイムをビルドして、デバッグ実行するのが一番早いのではないでしょうか。



リンク

2020/5/10(Sun) 20:44:00|NO.90326

mikumoさん
検証を行ったときに、新しいスクリプトで実験していました。単純にファイルを読もうとするだけのものです。こちらでだめなようなので、やはりhspda内部での問題なのかなと思っています。
どうしてもどうしても何が何でも原因を調べるのであれば、hspdaのソース読む→デバッグ実行するしかなさそうですよね。正直やりたくないですが、自前パーサーを作るとか?

3kさん
私の予想としては、「HSP以外で発生した例外全て」の一種だと思っています。これは、発生タイミングから考えても正しいでしょう。exeにコンパイルしてからエラーを発生させると、エラーダイアログが表示されずにいきなり死ぬこともあるので……。
さらに推測を交えると、データファイルの途中の構造体のバイト列、またはファイルの最後らへんの数バイトが壊れていて、hspdaがパースするときに異常な値を読み込んでしまい、NULLアクセス・バッファオーバーラン・へんなmalloc/freeなどなどを実行してしまうために死ぬ…という感じなのかなと思います。まだhspdaのソースまで読んでないですが。
いずれにしても、

> おそらくコード追うのが一番早いとは思いますが、これはプラグイン形式での提供になり、かつHSP内の変数へのアクセスとなるため、HSP内部に依存した処理が多くコード読むだけでは簡単ではないように見えます。

というのがごもっとも、的を射て正しい回答だと思います。
現象を再現させられるデータはありますが、途方もなくデバッグに時間がかかりそうなので、今私が使える時間でデータを直すのは難しいのかなと考えます。
お知恵を貸してくださってありがとうございました。



おにたま(管理人)

リンク

2020/5/10(Sun) 21:39:45|NO.90327

ご報告ありがとうございます。
意図的にシステムエラーを出すコードは含まれていませんので、
単純なスクリプトでも、読み込みでエラーが発生するようであれば、何らかの不具合だと思われます。
お手数おかけしますが、具体的にエラーが発生するデータやURLなどを知らせて頂ければ、こちらで調査させて頂きます。



ONION software Copyright 1997-2023(c) All rights reserved.