Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

在 build_type 为 debug 的情况下,Windows 下编译出来的 dll 遇到中文会崩溃 #158

Closed
SageMik opened this issue Oct 16, 2024 · 23 comments · Fixed by #162
Closed

Comments

@SageMik
Copy link
Contributor

SageMik commented Oct 16, 2024

Bug 描述

我参考仓库里的 Github Actions,设置 cmakeBuildType: Debug 编译了 Debug 版本的 simple.dll,遇到了与 #104 相同的问题,只要有中文就会报错(Release 版本没有这个问题):

image

File: minkernel\crts\ucrt\src\appcrt\convert\isctype.cpp
Line: 36
Experssion: c >= -1 && c <= 255

根据这篇文章的说法:https://blog.csdn.net/chinaryan/article/details/91839813,是因为下面这个地方使用了isdigit这类函数,它们的底层实现用到了报错截图中的cpp文件;当遇到中文时,传入的字符有负数,因而导致断言失败:

static TokenCategory from_char(char c) {
if (std::isdigit(c)) {
return TokenCategory::DIGIT;
}
if (std::isspace(c) || std::iscntrl(c)) {
return TokenCategory::SPACE;
}
if (std::isalpha(c)) {
return TokenCategory::ASCII_ALPHABETIC;
}
return TokenCategory::OTHER;
}

而 Release 版本没有这个问题,是因为断言被优化掉了。

我把参数的类型修改为unsigned char后,就能正常在 Window 下运行:

static TokenCategory from_char(unsigned char c)

同时,在 Windows 下使用 Visual Studio 2022 编写如下用例,也会出现相同的报错:

#include <iostream>
using namespace std;

int main() {
	const char *c = "你好";
	cout << isdigit(c[0]) << endl; // 报错
	// cout << isdigit((unsigned char)c[0]) << endl; // 正常
}

上面这两种现象,大概率可以验证我前文的说法。不过我只在 Windows 下测试了一下这个修改方案,不知道会不会有其他影响。

希望大佬能排查验证,修复一下这个bug。

重现步骤

.load simple
select simple_query('你好');

环境信息

  • 操作系统:Windows 10 x64
@wangfenjin
Copy link
Owner

static TokenCategory from_char(unsigned char c)

你可以提个 PR 做这个改动,我理解影响不大

@wangfenjin
Copy link
Owner

@SageMik 或者在函数进来之后先根据这个文档说的,cast 成 unsigned char

https://en.cppreference.com/w/cpp/string/byte/isdigit

@wangfenjin
Copy link
Owner

这样下面的 isspace 那些函数也都安全了

@wangfenjin
Copy link
Owner

感谢

@xMuscleCodingx
Copy link

xMuscleCodingx commented Nov 23, 2024

static TokenCategory from_char(unsigned char c)

你可以提个 PR 做这个改动,我理解影响不大

不行,有bug,虽然我不懂C++,但是我今天把大佬你的项目fork了一份,然后把contrib下的pinyin.txt的换为了zdic.txt,使用同样的actions进行编译(test全部通过,一切正常),然后下载了dylib文件在m1 pro macbook用了,有以下情况:

  • 英文字母搜索的匹配不影响。
  • 中文搜索能匹配上但是simple_highlight返回结果是乱码。
  • 拼音字母的搜索搜不到,即完全没用。

作为对比:

  • 我之前在static TokenCategory from_char(char c)的时候(也就是这个时候#156),就在我本地m1 pro macbook上,也是更换了zdic.txt,成功编译,test全部通过,使用是一切正常的。
  • 今天我尝试了5次使用static TokenCategory from_char(unsigned char c)通过actions编译(每次都是test全部通过,编译一切正常)但下载到本地用就一直有上述问题,然后看到了这个issue我才意识到有这个改动,所以我尝试改回了static TokenCategory from_char(char c),结果就一切正常了。

@wangfenjin
Copy link
Owner

  • pinyin.txt 工作正常吗
  • zdic 和 pinyin txt 有什么区别,为什么要换?

@wangfenjin wangfenjin reopened this Nov 23, 2024
@SageMik
Copy link
Contributor Author

SageMik commented Nov 23, 2024

@xMuscleCodingx 我把 pinyin.txt 换成了 zdic.txt,Window 和 Mac mini M4 上通过 CMake 命令行编译,在我自己的 Flutter 示例上没有复现这个问题,可能需要你提供更多的信息,比如 fork 之后具体修改了什么,有没有出错示例和出错截图。
@wangfenjin 说到 pinyin.txt,我之前用的时候发现它好像有点太全了,汉字里面一些基本不常用的读音像古音、方言口音这种,它里面还有,比如输入q,会匹配到示(U+793A, qí)、客(U+5BA2, qià)这种。影响常用字的话还是有点破坏使用体验的,所以我觉得可以考虑常用读音的拼音文件。

@xMuscleCodingx
Copy link

  • pinyin.txt 工作正常吗
  • zdic 和 pinyin txt 有什么区别,为什么要换?

@wangfenjin @SageMik 打扰两位了

这是昨天使用zdic并去掉unsigned版本,这是今天使用原始pinyin.txt并加上unsigned的版本

  • 我今天尝试了原始的pinyin.txt,并加上unsigned,一样匹配异常。
  • 主要是原始的pinyin.txt太全,匹配效果不佳,例如"有"字,居然输入"w"也能匹配到,我查了发现pinyin.txt里面"有"字居然有三个读音,也可参考这里

相关截图:
搜索测试
有字

我改动的地方:

1、CMakeLists.txt

# 原本是两个架构都写进去
# if (APPLE)
#    set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE STRING "")
#    set(CMAKE_OSX_DEPLOYM ENT_TARGET "10.11" CACHE STRING "Minimum OS X deployment version")
# endif()

# 改为了只写入对应架构
if (APPLE)
    # 检查当前系统的架构
    execute_process(COMMAND uname -m OUTPUT_VARIABLE ARCHITECTURE OUTPUT_STRIP_TRAILING_WHITESPACE)
    message(STATUS "Detected architecture: ${ARCHITECTURE}")

    if (${ARCHITECTURE} STREQUAL "arm64")
        set(CMAKE_OSX_ARCHITECTURES "arm64" CACHE STRING "")
    else()
        set(CMAKE_OSX_ARCHITECTURES "x86_64" CACHE STRING "")
    endif()
    set(CMAKE_OSX_DEPLOYMENT_TARGET "10.11" CACHE STRING "Minimum OS X deployment version")
endif()

2、workflows的main.yml,就是区分了架构进行打包,根据这里macos-latest是arm的,macos-13是x86的。

#########

  MacOS:
    runs-on: ${{ matrix.os }}
    needs: Linux
    strategy:
      matrix:
        os: [macos-latest, macos-13]

#########

    - name: Package
      if: startsWith(github.ref, 'refs/tags/')
      run: |
        mkdir libsimple-osx-${{ matrix.os }}
        sudo xattr -r -d com.apple.quarantine src/libsimple.dylib
        cp -r src/libsimple.dylib test/dict libsimple-osx-${{ matrix.os }}/
        zip -r libsimple-osx-${{ matrix.os }}.zip libsimple-osx-${{ matrix.os }}
      working-directory: "${{ github.workspace }}/../../_temp/macos"
    - name: Release
      if: startsWith(github.ref, 'refs/tags/')
      uses: softprops/action-gh-release@v1
      with:
        draft: true
        files: ${{ github.workspace }}/../../_temp/macos/libsimple-osx-${{ matrix.os }}.zip
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

#########

检测架构1
检测架构2

@xMuscleCodingx
Copy link

xMuscleCodingx commented Nov 24, 2024

很奇怪,zdic并去掉unsigned版本,在m1 pro macbook上没问题,但我刚刚在x64 windows上尝试一下,居然用不了,报错如下:
[28324:1124/153657.696:ERROR:crashpad_client_win.cc(868)] not connected

使用原始pinyin.txt并加上unsigned的版本,在m1 pro macbook上使用异常,但是在x64 windows上,又能正常使用

@wangfenjin
Copy link
Owner

@SageMik 你说的常用读音的文件具体是哪个?可以提个 MR 把那个改了

@wangfenjin
Copy link
Owner

@SageMik @xMuscleCodingx 我本地试了下,确实加 unsigned 会有问题;我猜想原因是如果是 unicode ,转成 unsigned 之后会造成误判。

需要有个提交修复这个问题,大家可以想想看怎么弄

@SageMik
Copy link
Contributor Author

SageMik commented Nov 24, 2024

我试了下,zdic.txt 去掉 unsigned 在 Mac 上没问题,在 Windows 上也是崩溃,跟 @xMuscleCodingx 描述的一样;但 pinyin.txt 加上 unsigned ,我在 Mac M4 和 Windows 上能正常使用,不能复现这个问题,真是挺奇怪的。

这样子有好几种情况:

  1. pinyin.txt + char,最初的情况,Debug 模式 Windows 下遇到中文会报错;
  2. pinyin.txt + unsigned char,在 Mac M1 下乱码出错;
  3. zdic.txt + char,在 Windows 下报错;
  4. zdic.txt + unsigned char,在 Mac M1 下乱码出错。

如此无论去不去掉 unsigned 都有问题,感觉需要调试代码看看定位原因,不然可能还不好修复。我对 C++ 其实也不算熟悉,估计要靠 @wangfenjin 大佬看一看了。

至于拼音文件我其实没有具体试过其他的,只是觉得目前这个确实太全了。

@wangfenjin
Copy link
Owner

拼音的话看起来 kTGHZ2013.txt 是一个不错的候选

先放着吧,如果还有人反馈的话可以考虑把pinyin.txt 换个简单版,我之前没有多想这个问题

@wangfenjin
Copy link
Owner

@xMuscleCodingx 感谢反馈

@xMuscleCodingx
Copy link

真不会C++,这个现象也着实是太神奇了,还是得辛苦 @wangfenjin 大佬处理一下了,感谢大佬开源这个项目。

@wangfenjin
Copy link
Owner

很奇怪,zdic并去掉unsigned版本,在m1 pro macbook上没问题,但我刚刚在x64 windows上尝试一下,居然用不了,报错如下:
[28324:1124/153657.696:ERROR:crashpad_client_win.cc(868)] not connected

@xMuscleCodingx 这个我感觉不是代码的问题,应该是你本地的 sqlite 版本问题

@wangfenjin
Copy link
Owner

现在的情况我认为是,如果不用 unsigned 会导致 debug 版本 crash,这个可能是故意设计的,在 debug 阶段暴露更多问题

@SageMik
Copy link
Contributor Author

SageMik commented Nov 24, 2024

很奇怪,zdic并去掉unsigned版本,在m1 pro macbook上没问题,但我刚刚在x64 windows上尝试一下,居然用不了,报错如下:
[28324:1124/153657.696:ERROR:crashpad_client_win.cc(868)] not connected

@xMuscleCodingx 这个我感觉不是代码的问题,应该是你本地的 sqlite 版本问题

@wangfenjin 大概不是,因为这个我和 @xMuscleCodingx 的现象是一样的。

如果我用本地的 CMake 编译,无论是 unsinged char 还是 char ,在 Windows 上都没问题。

去掉 zdic.txt 里面的注释,用 Github Action 编译,无论是 unsinged char 还是 char,在 Windows 上也没有这个问题了。

看上去是注释里的偏僻字和不同的编译选项会对 simple 的解析造成影响。

可以用这里 zdic.txt 的各个版本试试:https://github.com/SageMik/simple/releases

@xMuscleCodingx 或许可以试试上面的 v4 (删除注释的 zdic.txt + unsigned char)libsimple-osx-x64.zip (里面其实是包含 x86_64 和 arm64 的),看看 M1 上有没有问题

@wangfenjin
Copy link
Owner

wangfenjin commented Nov 24, 2024

https://github.com/wangfenjin/simple/blob/master/contrib/README.md

拼音文件确实需要处理下,处理下的好处是编译出来的东西也会变小一点;可以用我这个 readme 文件里的命令处理

@xMuscleCodingx
Copy link

很奇怪,zdic并去掉unsigned版本,在m1 pro macbook上没问题,但我刚刚在x64 windows上尝试一下,居然用不了,报错如下:
[28324:1124/153657.696:ERROR:crashpad_client_win.cc(868)] not connected

@xMuscleCodingx 这个我感觉不是代码的问题,应该是你本地的 sqlite 版本问题

这个是我在electron中用better-sqlite3往fts表中插入数据时报的错
better-sqlite3自带了sqlite二进制,它里面的sqlite版本是3.41.2,是2023 年 3 月 22 日发布的版本,这个版本应该没问题吧

@xMuscleCodingx
Copy link

xMuscleCodingx commented Nov 24, 2024

很奇怪,zdic并去掉unsigned版本,在m1 pro macbook上没问题,但我刚刚在x64 windows上尝试一下,居然用不了,报错如下:
[28324:1124/153657.696:ERROR:crashpad_client_win.cc(868)] not connected

@xMuscleCodingx 这个我感觉不是代码的问题,应该是你本地的 sqlite 版本问题

@wangfenjin 大概不是,因为这个我和 @xMuscleCodingx 的现象是一样的。

如果我用本地的 CMake 编译,无论是 unsinged char 还是 char ,在 Windows 上都没问题。

去掉 zdic.txt 里面的注释,用 Github Action 编译,无论是 unsinged char 还是 char,在 Windows 上也没有这个问题了。

看上去是注释里的偏僻字和不同的编译选项会对 simple 的解析造成影响。

可以用这里 zdic.txt 的各个版本试试:https://github.com/SageMik/simple/releases

@xMuscleCodingx 或许可以试试上面的 v4 (删除注释的 zdic.txt + unsigned char)libsimple-osx-x64.zip (里面其实是包含 x86_64 和 arm64 的),看看 M1 上有没有问题

感谢!我刚在x64 windows上试了 v4 (删除注释的 zdic.txt + unsigned char) ,这个是正常的(还没有在m1 pro mac尝试)。
这么神奇吗,删除注释+ unsigned char,就在x64 windows正常了

@xMuscleCodingx
Copy link

很奇怪,zdic并去掉unsigned版本,在m1 pro macbook上没问题,但我刚刚在x64 windows上尝试一下,居然用不了,报错如下:
[28324:1124/153657.696:ERROR:crashpad_client_win.cc(868)] not connected

@xMuscleCodingx 这个我感觉不是代码的问题,应该是你本地的 sqlite 版本问题

@wangfenjin 大概不是,因为这个我和 @xMuscleCodingx 的现象是一样的。

如果我用本地的 CMake 编译,无论是 unsinged char 还是 char ,在 Windows 上都没问题。

去掉 zdic.txt 里面的注释,用 Github Action 编译,无论是 unsinged char 还是 char,在 Windows 上也没有这个问题了。

看上去是注释里的偏僻字和不同的编译选项会对 simple 的解析造成影响。

可以用这里 zdic.txt 的各个版本试试:https://github.com/SageMik/simple/releases

@xMuscleCodingx 或许可以试试上面的 v4 (删除注释的 zdic.txt + unsigned char)libsimple-osx-x64.zip (里面其实是包含 x86_64 和 arm64 的),看看 M1 上有没有问题

@SageMik windows上可以,m1 pro mac上还是乱码

@wangfenjin
Copy link
Owner

不用试 unsigned 那个改动了,肯定有问题的;试试 #162

zdic 需要处理下

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants