• ベストアンサー

HP-UXへの移植でセグメンテーション障害が発生し、困っています

HP-UXへの移植で困っています。 strcpy(Month->Data,Data.arr); というコードがあり、今まではDigital Unix上では正常に動作していました。しかしHP-UX上でコンパイル、実行するとセグメンテーション障害が発生し、正常に動作しません。 どなたか助けてください。

質問者が選んだベストアンサー

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.6

ひとつ気になった点があります。 #1の補足にあるコードには、MONTH_RECの「定義」がありません。 そして、alloc_Month()では > Month= (MONTH_REC *)malloc(sizeof(struct Month_t)); とかやってますけど、 MONTH_REC と struct Month_t って本当に同じものですか? あと、alloc_Monthの実装も 使ってない変数 int iがある一方で、引数で貰ってきた ものを変数として使いまわしているし ちょっと首を傾げたくなる書き方です。 MONTH_REC* alloc_Month2(MONTH_REC *Month) { /* MONTH_REC *p = (MONTH_REC *)calloc(1, sizeof (struct Month_t)); */ MONTH_REC *p = (MONTH_REC *)calloc(1, sizeof (MONTH_REC)); MONTH_REC *q = Month; if (!p) { Exit(ERROR,__FILE__,__LINE__); } if (!q) { Month_top = p; } else { q->after = p; } Month_end = p; return p; } のような感じに書き換えたらどうなります? #あーqはいらなかったか。 あ、もうひとつ追加。 >alloc_Month()関数はNULLではありませんでしたが、strcpy(Month->Data,(char *)Data.arr); >手前でMonth->Dataをチェックしてみると 「Bad Address」とメッセージが返されてしまいました とありますが、この strcpyの実行直前の Month を %p 書式で出力したときの値と、 これを割り当てた alloc_Monthのなかでの memset(Month,NULL,sizeof(struct Month_t)); の前後での Monthを%p出力したときの値は 全部同じ値になってますか? Month_tの定義では typedef struct Month_t MONTH; struct Month_t{ struct Month_t *after; char Data[8+1]; }; なので、Monthが正しい値である場合に Month->Dataが 変な値(0?)になることはないと思いますが?

その他の回答 (5)

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.5

64bit環境の場合、0とNULLとのとり違いが致命的になりうる場合があります。 初級C言語Q&A(3) http://www.st.rim.or.jp/~phinloda/cqa/cqa3.html の Q 【関数呼び出しの0】  関数呼び出しの引数としてヌルポインタを書く場合、0と書いてはいけないと言われた。 [その他] BINARY HACKS - COLUN++ BLOG http://d.hatena.ne.jp/colun/20061203 NULLと0は等しい? あたりにその辺に絡んだ話があります。 詳しくは Binary Hacks ―ハッカー秘伝のテクニック100選: 本: 高林 哲,鵜飼 文敏,佐藤 祐介,浜地 慎一郎,首藤 一幸 http://amazon.jp/dp/4873112885 のHACK#49「64ビット環境で0とNULLの違いに気を付ける」 を読んでみてください。 ただ考え直すとmemsetは可変引数をとる関数じゃないし、 プロトタイプ宣言がちゃんとされていればキャストがかかるだろうし、 予測は外してるっぽいのには違いありませんが。 データモデルとは? http://www.oklab.org/language_c/lp64.html

回答No.4

私のコードの読み違いなら申し訳ないのですが、 alloc_Month()関数で、 if(!Month){ Exit(ERROR,__FILE__,__LINE__); } としているため、Month != NULL の場合は必ず Exit してしまいます。 結果、alloc_Month()関数の戻り値は必ず NULL なのではないでしょうか? Month = NULL の場合の memset(Month,NULL,sizeof(struct Month_t)); の動作は試していないのでどうなるのか分かりませんが。。 Month = NULL で戻ってきているため、直後の strcpy(Month->Data,(char *)Data.arr); でセグメンテーションフォルトになります。 Month が NULL になっている原因は分かりませんが、 alloc_Month()関数での malloc() が失敗すると戻り値が NULL となり、 Month に NULL が代入されてしまうこともありえます。 また少し質問とは外れますが、上記 memset() の第2引数が NULL は問題ないと思います。 ほとんどの処理系では、 stdio.h の中で #define NULL 0 と定義されています。HP-UX も同様だと思います。 NULL か 0 か '\0' かは、結局同じ値になるので、 私はコードの視認性を考え、その場に応じた書き方をするようにしています。

hatena9999
質問者

補足

alloc_Month()関数はNULLではありませんでしたが、strcpy(Month->Data,(char *)Data.arr); 手前でMonth->Dataをチェックしてみると「Bad Address」とメッセージが返されてしまいました。尚、今は memset(Month,NULL,sizeof(struct Month_t)); のNULLは一応、0に置き換えています。

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.3

ここまで状況が絞り込めているのなら、デバッガでステップ実行すれば すぐに場所をピンポイントで特定できそうな気がするんですが、 実は毎回発生するわけじゃなくて何かの拍子にSEGVが起きるとかだったりします? とりあえず共有メモリ領域を他のスレッドやプロセスがぶっ壊しているという 可能性はないとして、 Month= (MONTH_REC *)alloc_Month(Month); strcpy(Month->Data,(char *)Data.arr); ↑このalloc_Monthの呼び出し後に毎回SEGVしているということでいいですか? 一つだけ気になる部分があります。 alloc_Monthの中で >memset(Month,NULL,sizeof(struct Month_t)); というのがありますが、HP-UXって64ビットOSですよね? HP-UXのccがILP64なのかLP64なのか、はたまたLLP64なのかは知りませんが memsetの第二引数に NULL を渡しているのはまずいような気がします。 関数にしようとしては int を期待しているのにポインタを渡しているわけですから。 #もちろんそれで問題ない場合もありますが Digital UNIXでは発生していなかったということですので(たしかこれも 64ビットOSでしたよね?)あんまり自信はありません。 もしなんらかの理由でデバッガでステップ実行を試せないのなら、 alloc_Monthのところどころ(先頭とリターン直前の部分と、memsetの 前後くらいかな)で データがおかしくなっていないかチェックしてみてください。 Data.arrは見るのが大変でしょうが、Monthもぶっ壊れているということですから とりあえずこちらだけでも。

hatena9999
質問者

補足

アドバイスありがとうございます。 alloc_Monthの呼び出し後に毎回必ずSEGVしています。 memset(Month,NULL,sizeof(struct Month_t)); がおかしいとは思っていませんでした。NULLの部分を変更して実行してみます。

  • asuncion
  • ベストアンサー率33% (2126/6286)
回答No.2

構造体のメンバー arr を、どこでどのように定義しているのでしょうか?

hatena9999
質問者

補足

ANo.1の方の補足にコードのほうを記述していますので参考頂ければと思います。なお、定義は以下です。 <Month.h> typedef struct Month_t MONTH; struct Month_t{ struct Month_t *after; char Data[8+1]; }; MONTH *Get_Month_top();

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

そのstrcpyでSEGVしているんなら、パラメータの値をチェックしました? 多分移植前のシステムでは正常動作していたってのは勘違いで、 未初期化のポインタを使ってたりしていたのがたまたま動いていただけで HP-UXに持ってきたときにバグが顕在化しただけじゃないですか? つか助けろって言われたってたったそれだけの情報じゃ無理だって。

hatena9999
質問者

補足

以下今回のコードです。 <Month.h> typedef struct Month_t MONTH; struct Month_t{ struct Month_t *after; char Data[8+1]; }; MONTH *Get_Month_top(); <Month.c> static MONTH_REC *alloc_Month(); static MONTH_REC *Month_top; static MONTH_REC *Month_end; int Read_Month() { EXEC SQL BEGIN DECLARE SECTION; VARCHAR sqlstmt[4096]; VARCHAR Data[20]; EXEC SQL END DECLARE SECTION; MONTH_REC *Month = NULL; sprintf((char *)sqlstmt.arr, "SELECT\ D.Data\ FROM \ %s D \ WHERE \ TO_CHAR(D.YEARMONTH,'YYYYMM') = '%s' \ ",MONTH,YearMonth); sqlstmt.len = strlen((char *)sqlstmt.arr); EXEC SQL WHENEVER SQLERROR GOTO sql_error; EXEC SQL PREPARE S2 FROM :sqlstmt; EXEC SQL DECLARE C2 CURSOR FOR S2; EXEC SQL OPEN C2; EXEC SQL WHENEVER NOT FOUND DO break; while(1){ EXEC SQL FETCH C2 INTO :Data; Data.arr[Data.len] = NULL; Month= (MONTH_REC *)alloc_Month(Month); strcpy(Month->Data,(char *)Data.arr); } EXEC SQL WHENEVER NOT FOUND CONTINUE; EXEC SQL CLOSE C2; EXEC SQL WHENEVER SQLERROR CONTINUE; sql_error: Sql_Error(__FILE__,__LINE__); Sql_Rollback(__FILE__,__LINE__); Exit(ERROR,__FILE__,__LINE__); return -1; } MONTH_REC *alloc_Month(MONTH_REC *Month) { int i; if(!Month){ Month= (MONTH_REC *)malloc(sizeof(struct Month_t)); Month_top = Month; }else{ Month->after= (MONTH_REC *)malloc(sizeof(struct Month_t)); Month = Month->after; } if(!Month){ Exit(ERROR,__FILE__,__LINE__); } memset(Month,NULL,sizeof(struct Month_t)); Month_end = Month; return Month; } MONTH *Get_Month_top() { return Month_top; } パラメータの値ですが、不思議なことにalloc_Month関数の前までは"111"など正常値が入っているのですが、戻ってくるとData.arrが0x000x00x00に変化してしまいます。またMonthも0x00になってしまいます。

関連するQ&A

  • malloc呼び出し時のセグメンテーションフォルト

    UNIX(HP-UX)上でCプログラムを組んでおります。 その際、mallocでセグメンテーションフォルトが起こりました。 mallocでセグメンテーションフォルトが起こった場合、どのように調査するのか、また実際どのような原因で起こりうるのか教えていただけますでしょうか?

  • HP-UXで稼動していたHDDを別のマシンに接続する方法

    HP-UX10.2で稼動していたWSがダウンしました。 メーカーによるとCPUかMBの障害でHDDは大丈夫だそうです。 事情があって、HDDのデータを別マシンに移行 の作業を自力で行うことになりましたが、 Windowsの感覚で増設だけでうまくシステムマウント してくれるのでしょうか。 マシン詳細は以下の通りです。 障害のおきたWS:HP9000 C110 VLM使用 移行に使うWS:HP9000 712 どちらもHP-UX10.20です。 よろしく御願い致します。

  • 標準ヘッダファイルの中身は何に依存?

    stdio.h等の標準ヘッダファイルについて質問です。 HP-UX11.00でコンパイルが通っていたプログラムをHP-UX11.11に移植しようとしているのですが、うまくコンパイルが通りません。 stdio.hを取り込んだ辺りですでにエラーが出ているようなのでHP-UX11.00上のstdio.hをプログラムと同じ階層にコピーして、プログラム内でincludeする際に、静的にコピーしてきたファイルを指定しました。 これでコンパイルをするとエラーが無くなり、動作確認をしてみるとうまく動いているようなのですが、標準ヘッダファイルは、このように違うバージョンのOS上からコピーしてきて使っても平気なのでしょうか? 標準ヘッダファイルの中身は何に依存しているか教えてください。

  • runtime error発生で困っています。

    初めて質問させていただきますのでよろしくお願いいたします。 私はプログラミング知識は全くなく、単なるPCの利用者です。 EMOBILEのデータカードを今まで使用しておりましたが、立ち上げ時にruntime errorが出るようになって動作しなくなりました。 エラーメッセージ: microsoft visual c++ runtime library  runtime error! コントロールパネルの問題のレポートでは以下が記述されておりました。 製品:EMOBILE D02NE ユーティリティ 問題:動作が停止しました 問題の署名 問題イベント名: APPCRASH アプリケーション名: D02NEUTL.exe アプリケーションのバージョン: 1.0.0.0 アプリケーションのタイムスタンプ: 476b6153 障害モジュールの名前: MSJET40.DLL 障害モジュールのバージョン: 4.0.9704.0 障害モジュールのタイムスタンプ: 4713cc31 例外コード: 40000015 例外オフセット: 0012a2de OS バージョン: 6.0.6001.2.1.0.768.3 ロケール ID: 1041 追加情報 1: ce63 追加情報 2: 84f20a0b8f839bd5282a5f3c6eb44d6e 追加情報 3: 1d81 追加情報 4: 0f11a5524c1570ca17b8cdba95fdc4e2 EMOBILE D02NE ユーティリティとデータカードを別のPCにセットしたところ正常に動作しました。障害の起きたPCで再インストールをしても解消しませんでした。 障害モジュール:MSJET40.DLLを正常に動いているPCから移植しても結果は同じでした。 できれば再セットアップをしないで解決したいのですが、良い方法があったら教えてください。 また以下の事象も起こるようになりました。 ・NORTON360で修復ボタンに反応しない。 ・IEでサブ画面表示や、プルダウンメニューの表示ができない。 以上よろしくお願いいたします。

  • CLASSファイルの他UNIX上での動作について

    こんにちわ。早速なんですけど、教えて下さい。 以下のことを行った場合、 (1)javaソースをHP-UNIX上でコンパイル後、圧縮。 (2)windows2000にダウンロード後、CDに焼く。 (3)Solarisで解凍し、実行環境に投入。 で、Solarisで正常に動作するでしょうか? javaだから出来るような気もするんですけど、やっぱりリコンパイルは必要な気もして。 よろしくお願いします。

    • ベストアンサー
    • Java
  • HP-UXにてiconv変換できません。

    いつもお世話になっています。 当方、C言語初心者です。 環境 HP-UX 11.23 言語 C言語 他システムより接続された漢字コードに制御コードを付与し、JISコードに変更後、 JIS→SJISに変換するツールを開発しています。 たとえば 他システムより 0x3E3E 0x3B33(コードを調べると〔松山〕でした) 前後に制御コード付与すると 0x1B 0x24 0x42 0x3E3E 0x3B33 0x1B 0x28 0x4A JISで松山になります。 エディタで上記コードを読み込むと松山と表示されました。 ところが上記のJISを下記内容で実行させると、 入力値のコードがなんの変換もされず返却されました。 どこに不具合があって入力の内容(cvbuf)が出力の内容(ebuf)にそのまま返却されているのか調べることができませんでした。 何か見落としがあればご指摘のほど、宜しくお願い致します。 ※rlenをprintfしたところ正常返却されています。 ======================================================================= 呼び元は  cvkanj(0x3E3E 0x3B33の内容が入ったアドレス,2)  みないな感じです。 char *cvkanj(s, len) char *s; int *len; { char cvbuf[32768]; int rcd; staric char ebuf[32768] = {0}; static char ki[4] = { 0x1b, 0x24, 0x42, 0x00}; static char ko[4] = { 0x1b, 0x28, 0x4a, 0x00}; memcpy( cvbuf, ki, 3); memcpy( &cvbuf[3], s, len) memcpy( &cvbuf[len+3], ko, 3); cvbuf[len+6] = 0x00; rcd = convt(cvbuf, ebuf); return(&ebuf[0]); } int convt(pin, pout) char *pin; char *pout { iconv_t cd; size_t ilen; size_t olen; size_t rlen; ilen=strlen(pin); olen=32768; if ((cd = iconv_open("jis","sjis")) == (iconv_t)-1){ exit(-1); } rlen = iconv(cd, &pin, &ilen, &pout, &olen); iconv_close; return(0); }

  • Perl連想配列の使い方について

    はじめまして。 現在、業務で他人の書いたコード(Perl)を改造しているのですが、その作成者がいなくなってしまっております。 そのコードを見ると、なぜ、このような書き方が可能なのか、理解できないので、動作原理を教えていただけないでしょうか? 以下のようなコードです。 ==================================== my @arr = ( "一" , "ニ" , "三" , "四" ) ; my %data ; $data->{0} = \@arr ; $data{0}{test} = "テスト" ; print ${$data->{0}}[1] . "\n" ; print $data{0}{test} . "\n" ; ==================================== 出力はこのようになります。 ニ テスト ここからが質問なのですが、$data->{0}という書き方ができる理由が分からないのです。 $dataが例えば、 my %my_hash ; my $data = \%my_hash ; というように、ハッシュのリファレンスであるならば、$data->{0}という書き方も分かるのですが、定義した時点でリファレンスではない、$dataに、何故"->"の演算子が使えるのでしょうか? とはいえ、 ref $data ; の戻り値がHASHとなるのも確認しています。 これもどうしてそうなるのか、根本的な原理が分かっておりません。 どうか、このコードの動作原理を教えていただけないでしょうか。 抽象的な質問となっている気がしますが、宜しくお願いいたします。

    • ベストアンサー
    • Perl
  • perlからsystemコマンド呼ばれる時のシェルについて

    HP-UX/perl4 で作成したスクリプトを、Linux(Red Hat)/perl5 へ移植するに当たって、system関数の動作が異なり困っています。 HP-UX では ksh をシェルとして使用していたため、perl からのsysytem関数で実行するsystemコマンドも、kshで動作するものを使っていました。Linuxでもログインシェルをkshに設定しました。 ところが、HP-UXで使っていたprintコマンドが使用できず、以下のエラーメッセージが出ます。 sh: print: command not found シェルはkshを指定していても、perlからsystem関数やバッククウォート`` でシステムコマンドを実行するときは、shが使われるようなのです。 perl内の記述は以下のとおりです。 system("print 'a'"); "print"の前に"ksh "をつけたり、"print"を"echo"に変えると、正しく動作します。 移植するperlの本数が多いのと、print以外にもこの問題が起きるかもしれませんので、できれば perl 内からのシステムコマンド実行時にもログインシェルとおなじ ksh で動くようにしたいのですが、どのようにすればよいのでしょうか? よろしくお願いいたします。

  • UNIXマシンにWINDOWS用の外付けHDを使…

    UNIXマシンにWINDOWS用の外付けHDを使えますか? よろしくお願いいたします。 ヒューレットパッカード製 VISUALIZE B2000 OSはHP-UXです。 今手元にWINDOWS用のハードディスクがあるのですがこれをUNIXマシンにつないで使うことは可能でしょうか。 HDはI/Oデータ製の「HDCA-U1.0K」で本体側を見たところUSBで接続は可能のようです。 I/Oデータに今電話で問い合わせたところ「UNIX系のOSに関しては答えられない(情報がない)」とのことでした。 ※古い機種なのでヒューレットパッカードおよびCADメーカーのサポートは受けられません。 もし可能なら方法を教えて下さい。 よろしくお願いいたします。 他のHPでも質問したのですがどうも無理のようです。 でもしばらくは情報をお待ちしますので引き続きよろしくお願いいたします。

  • 文字コードについて

    仕事場のワークステーションがUNIX→Linuxに移行することが決まりました。 そこで現在使用しているUNIXのプログラムをLinuxにコピーしたのですが、文字コードがおかしいのか文字化けして動作しません。 動作としては プログラムを立ち上げる    ↓ 環境設定ファイルを読み込む    ↓ 上手く起動する 正常なら上記の動作ですが、環境設定ファイルが読み込めず停止してしまいます。 そこで環境設定ファイルを開くと文字化けしてました。 その後、今までのUNIX上での環境設定ファイルをlessで表示させ、 新たなLinuxマシンにviでコピー・ぺ-ストして保存したところ 正常に動作しました。 操作は別端末のTeraTaermで行っています。 これはLinuxマシンの文字コードがUTF-8のためEUCが認識できないからでしょうか? 行き詰ってますので、どうかお願いいたします。 Linuxの環境は Red Hat 8.0のエンタープライズ版です。

専門家に質問してみよう