文書の過去の版を表示しています。
pg_repack
ビルドできても例外エラー
2021年の質問:Windowsでpg_repackをビルドしても例外エラーになってしまう。
pg_repack binaries under windows
下記サイトは2018年のもので静的なpostgres.libを作成して動作したとの報告があったが、現在は postgres.lib が提供されており、上記サイトでも postgres.lib をリンクしても、例外エラーで動作しないことから問題は別物と考える。
調査
pg_repack のデバッグでは、set_pglocale_pgservice(argv[0], “pgscripts”); を実行すると例外エラーとなる。
vaccumedb のデバッグでは、set_pglocale_pgservice(argv[0], “pgscripts”); を使用していても正常に動作する。違いとしてvaccumedb では、postgres.lib をリンクしていない。
pg_repack以外で exe形式で postgres.lib をリンクしたものは他にない。
関数 | モジュール | ソース元 |
---|---|---|
set_pglocale_pgservice | libpgcommon.lib | |
setlocale(pgwin32_setlocale) | libpgport.lib | |
select(pgwin32_select) | postgres.lib | backend¥port¥win32¥socket.c |
pgwin32_dispatch_queued_signals | postgres.lib | backend¥port¥win32¥signal.c |
errstart | postgres.lib | backend\utils\error\elog.c |
pg_repack を pgwin32_selectで検索しても見つからないが、select で検索すると見つかる。
ret = select(max_fd + 1, &input_mask, NULL, NULL, &timeout);
- win32.port.h
#define setlocale(a,b) pgwin32_setlocale(a,b) #define select(n, r, w, e, timeout) pgwin32_select(n, r, w, e, timeout)
pg_hello を作成して postgres.lib をリンクしないで pg_repack.c のソースコードに徐々に近づけた。
そして、rebuild_indexes で pgwin32_select が参照している旨のLINKエラーのみになった。
そこで、pg_repack.c を、pg_hello.c に名前を変更してビルド、同様に rebuild_indexes で、pgwin32_select が参照している旨のLINKエラーのみになった。
下記のコードをコメントアウトすると、LINKエラーは出なくなる。
ret = select(max_fd + 1, &input_mask, NULL, NULL, &timeout);
select関数の参照先の違い
pg_repack の select関数 は、win32_port.h → socket.c の pgwin32_select関数 を参照している。
pgbench や pg_recvlogical の select関数 は、winSock2.h の select関数 を参照している。
select関数 を win32_port.h か winSock2.h を参照させる違いはどこにあるのか?
必要なobjファイルだけをリンク
socket.obj、singal.obj をリンクすると、7つの未解決エラーが出る。
1>socket.obj : error LNK2019: 未解決の外部シンボル errstart が関数 pgwin32_select で参照されました 1>signal.obj : error LNK2001: 外部シンボル errstart は未解決です 1>socket.obj : error LNK2019: 未解決の外部シンボル errfinish が関数 pgwin32_select で参照されました 1>signal.obj : error LNK2001: 外部シンボル errfinish は未解決です 1>socket.obj : error LNK2019: 未解決の外部シンボル errmsg_internal が関数 pgwin32_select で参照されました 1>signal.obj : error LNK2001: 外部シンボル errmsg_internal は未解決です 1>signal.obj : error LNK2019: 未解決の外部シンボル write_stderr が関数 pg_signal_thread で参照されました
このぐらいならと elog.obj を追加すると多くの未解決エラーが出る。同じように追加するとどんどん別のobjファイルから未解決エラーが出る。postgres.libとリンクするのと変わらなくなるため、この方法での解決はやめた。
関数名 | モジュール名 | オブジェクト名 |
---|---|---|
ExceptionalCondition | asset.c | assert.obj |
pg_codepage_to_encoding | chklocale.c | chklocale.obj |
MemoryContextStrdup | mcxt.c | mcxt.obj |
GetTopTransactionIdIfAny | xact.c | xact.obj |
GetMessageEncoding | mbutils.c | mbutils.obj |
pgwin32_message_to_UTF16 | mbutils.c | mbutils.obj |
pq_putmessage_v2 | pqcomm.c | pqcomm.obj |
pq_beginmessage | pdformat.c | pdformat.obj |
pq_endmessage | pqformat.c | pqformat.obj |
pq_sendstring | pqformat.c | pqformat.obj |
pq_send_ascii_string | pdformat.c | pdformat.obj |
pg_localtime | localtime.c | localtime.obj |
pg_strftime | strftime.c | strftime.obj |
ProcessInterrupts | postgres,c | postgres,obj |
GetBackendTypeDesc | miscinit.c | miscinit.obj |
pgstat_get_my_query_id | backend_status.c | backend_status.obj |
write_syslogger_file | syslogger.c | syslogger.obj |
proc_exit | ipc.c | ipc.obj |
MemoryContextReset | mcxt.c | mcxt.obj |
get_ps_display | ps_status.c | ps_status.obj |