调试MapServer

作者

杰夫麦克纳

联系

jmckenna在gatewaygeomatics.com

最后更新

2021-04-16

介绍

在为Internet开发应用程序时,您将不可避免地遇到环境中的许多问题。本指南的目标是帮助您定位MapServer应用程序的问题。

启用MapServer调试的步骤

从MapServer 5.0开始,您可以控制MapServer返回给您的调试/日志信息的级别,还可以控制输出日志文件的位置。

在技术术语中,在MapServer代码的各个区域中都有msdebug()调用,这些调用生成的信息可能对应用程序的优化和故障排除很有用。

步骤1:设置ms_errorfile变量

这个 MS_ERRORFILE 变量用于指定来自MapServer的调试消息的输出。可以将以下值传递给 MS_ERRORFILE:

** [文件名] **

日志文件的完整路径和文件名,用于包含MapServer的调试消息。可以使用任何文件扩展名,但建议使用*.log*或*.txt*。如果文件不存在,将创建该文件。

从mapserver 6.0开始,可以通过config ms_errorfile指令传递具有相对路径的文件名,在这种情况下,该文件名是相对于mapfile位置的。请注意,通过环境变量设置ms_errorfile总是需要绝对路径,因为没有映射文件可以使路径相对于。

stderr

使用它可以将MapServer的调试消息发送到Web服务器的日志文件(即“标准错误”)。如果您使用的是Apache,那么调试消息将放在Apache中。 error_log 文件。如果您使用的是Microsoft IIS,则调试消息将发送到 stdout (即浏览器),因此不鼓励使用。对于IIS,建议将输出定向到文件。

stdout

使用它可以将mapserver的调试消息与mapserver的其余输出组合发送到标准输出(即浏览器)。

windowsdebug

使用它可以将MapServer的调试消息发送到Windows OutputDebugString API,允许使用外部程序(如SysInternals DebugView)显示调试输出。

通过映射文件

建议的设置方法 MS_ERRORFILE 变量在映射文件中, MAP 对象,例如:

MAP
  ...
  CONFIG "MS_ERRORFILE" "/ms4w/tmp/ms_error.txt"
  ...
  LAYER
    ...
  END
END

通过环境变量

您也可以设置 MS_ERRORFILE 变量作为系统上的环境变量。Apache用户可以在Apache的 httpd.conf 文件,例如:

SetEnv MS_ERRORFILE "/ms4w/tmp/ms_error.txt"

Windows用户也可以通过Windows系统属性设置环境变量;但请确保设置系统环境变量。

备注

如果两者都 MS_ERRORFILE 设置环境变量 CONFIG MS_ERRORFILE 也设置了,则config指令优先。

步骤2:设置调试级别

通过设置 DEBUG 中的参数 Mapfile . 你可以把 DEBUG 参数在映射文件的任何层中获取特定于层的调试信息,或者相反,在映射对象中设置一次以获取常规调试信息。使用的值 DEBUG 参数设置返回的信息类型,如下所示:

调试级别

0级

仅限错误(调试关闭或调试0)

在级别0中,只有mssterror()调用被记录到ms-erorfile。根本没有msdebug()输出。这是默认值,与mapserver 4.x中ms_错误文件的原始行为相对应。

**级别1 **

错误和通知(调试打开或调试1)

级别1包括来自级别0的所有输出加上msdebug()有关常见陷阱、失败断言或非致命错误情况的警告(例如,某些参数的值丢失或无效、tileindex中缺少形状文件、来自远程WMS/WFS服务器的超时错误等)。

**级别2 **

地图调整(调试2)

级别2包括级别1的所有输出,以及对优化映射文件和应用程序有用的通知和计时信息。这是建议的最低调试级别

**级别3 **

详细调试(调试3)

所有的2级加上一些调试输出,在排除诸如正在调用的WMS连接URL、数据库连接调用等问题时很有用。

**级别4 **

非常详细的调试(调试4)

3级,更详细…

**级别5 **

非常详细的调试(调试5)

级别4加上任何msdebug()输出,对开发人员可能比对用户更有用。

映射文件示例:映射级别调试

下面的示例是设置 DEBUG 地图级别的参数:

MAP
  ...
  CONFIG "MS_ERRORFILE" "/ms4w/tmp/ms_error.txt"
  DEBUG 5
  ...
  LAYER
    ...
  END
END

映射文件示例:层级调试

下面的示例是设置 DEBUG 层的参数:

MAP
  ...
  CONFIG "MS_ERRORFILE" "/ms4w/tmp/ms_error.txt"
  ...
  LAYER
    DEBUG 5
    ...
  END
END

ms_debuglevel环境变量

而不是设置 DEBUG 调试级别在每个映射文件中,也可以使用 MS_DEBUGLEVEL 环境变量。

小技巧

虽然可以设置MS_DEBUGLEVEL环境变量,但强烈建议您在映射文件中为映射、层或类对象设置DEBUG。

设置后,在映射文件解析器加载所有映射和层对象时,该值将用作它们的默认调试级别值。此选项还为位于map或Layer对象的上下文之外的任何msDebug()调用设置调试级别,例如,对于与加载map之前的初始化相关的调试语句。如果还在某些地图或层对象的映射文件中指定了调试值,则本地值(在映射文件中)优先于环境变量的值;来自地图或层对象上下文之外的调试信息不能通过在映射文件中关闭调试来关闭。

设置此选项( MS_DEBUGLEVEL )在调优应用程序时非常有用,例如,通过在映射加载之前启用计时/调试输出来捕获完整的进程初始化和映射加载时间。

Apache用户可以在Apache的 httpd.conf 文件,例如:

SetEnv MS_DEBUGLEVEL 5

Windows用户也可以通过Windows系统属性设置环境变量;但请确保设置系统环境变量。

步骤3:打开CPL_调试(可选)

MapServer依赖于 GDAL 库来访问大多数数据层,因此您可能希望打开GDAL调试,以获得有关GDAL如何访问您的数据文件的更多信息。这对解决有关访问栅格文件和PostGIS表的问题非常有帮助。属性可以触发此GDAL输出 CPL_DEBUG 映射文件中的变量,在 MAP 对象,例如:

MAP
  ...
  CONFIG "CPL_DEBUG" "ON"
  ...
  LAYER
    ...
  END
END

属性向该报表添加时间戳(每行上的日期/时间 CPL_TIMESTAMP 变量,例如:

MAP
  ...
  CONFIG "CPL_DEBUG" "ON"
  CONFIG "CPL_TIMESTAMP" "ON"
  ...
  LAYER
    ...
  END
END

备注

有关GDAL可能使用的变量的详细列表,请参阅 GDAL wiki 。主GDAL站点也有一个 list

步骤4:打开项目调试(可选)

MAPServer依赖于 PROJ 库来处理数据投影,因此您可能希望打开proj调试,希望从proj库中获得更多信息。您可以通过设置 PROJ_DEBUG 映射文件中的变量 MAP 对象,例如:

MAP
  ...
  CONFIG "CPL_DEBUG" "ON"
  CONFIG "PROJ_DEBUG" "ON"
  ...
  LAYER
    ...
  END
END

备注

您可以设置 "CPL_DEBUG" "PROJ" 限制返回给PROJ的信息(一般不是GDAL)

备注

有关可能使用的项目变量的完整列表,请参阅 official list

步骤5:测试映射文件

一旦你设置了 MS_ERRORFILEDEBUG 在映射文件中,现在应该测试映射文件并读取生成的日志文件。

使用SIP2IMG

测试映射文件的建议方法是使用mapserver命令行实用程序 Sp2IMG ,以验证映射文件是否创建了有效的映射图像。 Sp2IMG 应该包含在MapServer安装中( MS4W 用户需要执行 setenv.bat 在使用实用程序之前)。

您可以设置 DEBUG 通过 Sp2IMG 命令行调用的以下参数:

备注

如果你已经准备好了 MS_ERRORFILE 在映射文件中,您必须对此进行注释才能使用这些 Sp2IMG 选项

备注

在使用时 Sp2IMG 要进行调试,您的层的状态应设置为打开或默认。如果将该图层的状态设置为关闭,则还必须将该图层名传递给 Sp2IMG 通过使用“-l layername”语法

-all_debug

使用此设置可以设置映射对象和所有层的调试级别。这是建议使用的开关

shp2img -m spain.map -o test.png -all_debug 5

  msLoadMap(): 0.002s
  msDrawMap(): Layer 0 (spain provinces), 0.012s
  msDrawRasterLayerLow(orthophoto): entering.
  msDrawGDAL(): src=0,0,3540,2430, dst=188,48,1,1
  source raster PL (-793.394,-1712.627) for dst PL (188,48).
  msDrawGDAL(): red,green,blue,alpha bands = 1,2,3,0
  msDrawMap(): Layer 1 (orthophoto), 0.150s
  msDrawMap(): Layer 2 (urban areas), 0.004s
  msDrawMap(): Layer 3 (species at risk), 0.008s
  msDrawMap(): Layer 4 (populated places), 1.319s
  msDrawMap(): Drawing Label Cache, 0.014s
  msDrawMap() total time: 1.513s
  msSaveImage() total time: 0.039s
  msFreeMap(): freeing map at 0218C1A8.
  freeLayer(): freeing layer at 0218F5E0.
  freeLayer(): freeing layer at 030C33A0.
  freeLayer(): freeing layer at 030C3BC8.
  freeLayer(): freeing layer at 030C4948.
  freeLayer(): freeing layer at 030C7678.
  shp2img total time: 1.567s
MAPX调试

使用此设置仅为映射对象设置调试级别。

shp2img -m spain.map -o test.png -map_debug 5

  msDrawMap(): Layer 0 (spain provinces), 0.012s
  msDrawRasterLayerLow(orthophoto): entering.
  msDrawMap(): Layer 1 (orthophoto), 0.144s
  msDrawMap(): Layer 2 (urban areas), 0.004s
  msDrawMap(): Layer 3 (species at risk), 0.008s
  msDrawMap(): Layer 4 (populated places), 1.323s
  msDrawMap(): Drawing Label Cache, 0.013s
  msDrawMap() total time: 1.511s
  msSaveImage() total time: 0.039s
  msFreeMap(): freeing map at 0205C1A8.
-层调试

使用此设置仅为一个层对象设置调试级别。

shp2img -m spain.map -o test.png -layer_debug orthophoto 5

  msDrawRasterLayerLow(orthophoto): entering.
  msDrawGDAL(): src=0,0,3540,2430, dst=188,48,1,1
  source raster PL (-793.394,-1712.627) for dst PL (188,48).
  msDrawGDAL(): red,green,blue,alpha bands = 1,2,3,0
  msDrawMap(): Layer 1 (orthophoto), 0.151s
  freeLayer(): freeing layer at 02F23390.
设置CPLD调试

在命令行执行以下操作:

set CPL_DEBUG=ON

shp2img -m spain.map -o test.png -layer_debug orthophoto 5

  msDrawRasterLayerLow(orthophoto): entering.
  GDAL: GDALOpen(D:\ms4w\apps\spain\map/.\../data/ov172068_200904_c100u50x75c24n.jpg, this=0
  4059840) succeeds as JPEG.
  msDrawGDAL(): src=0,0,3540,2430, dst=188,48,1,1
  source raster PL (-793.394,-1712.627) for dst PL (188,48).
  msDrawGDAL(): red,green,blue,alpha bands = 1,2,3,0
  GDAL: GDALDefaultOverviews::OverviewScan()
  msDrawMap(): Layer 1 (orthophoto), 0.155s
  freeLayer(): freeing layer at 03113390.
  GDAL: GDALDeregister_GTiff() called.
SHP2IMG返回的读取错误

如果你的 Mapfile 有问题, Sp2IMG 应输出引起故障的映射文件中的行号。下面告诉我们,我的映射文件的第85行有问题:

getSymbol(): Symbol definition error. Parsing error near (truetype2):(line 85)

如果使用mapfile INCLUDEs ,可能很难找到这个行号,但大多数情况下行号是有用的。

使用mapserv cgi

测试映射文件的另一种简便方法是在 commandline 如:

mapserv -nh "QUERY_STRING=map=/ms4w/apps/spain/map/spain.map&mode=map"

ON_MISSING_DATA

如果使用平铺索引访问数据,还应了解MapServer 5.4中添加的配置设置,这些设置允许您告诉MapServer如何处理平铺索引中丢失的数据。请看 CONFIG 参数的 ON_MISSING_DATA 设置在 MAP 对象以获取更多信息。

提示

您可以通过对数据文件执行“ogrinfo-al”来检查tileindex中的属性。

步骤6:检查Web服务器日志

一旦您验证了mapfile没有问题,接下来您应该检查Web服务器日志文件,以获取任何可能帮助您缩小问题范围的相关信息。

阿帕奇

Unix用户通常会发现Apache的 error_log 文件的路径类似于:

/var/log/apache2/

Windows用户通常会在以下路径中找到Apache的日志文件:

C:\Program Files\Apache Group\Apache2\logs

用于Windows的MapServer( MS4W )用户可以在以下位置找到Apache的日志文件:

\ms4w\Apache\logs

微软IIS

可以通过以下方式找到IIS日志文件:

  1. 转到“开始”->“控制面板”->“管理工具”

  2. 打开Internet信息服务(IIS)管理器。

  3. 在左边的树下找到你的网站。

  4. 右键单击它并选择属性。

  5. 在“网站”选项卡上,您将在底部附近看到一个选项,显示“活动日志格式”。单击“属性”按钮。

    ../_images/iis-debug.png
  6. 在“常规属性”选项卡的底部,您将看到一个包含日志文件目录和日志文件名的框。完整日志路径由日志文件目录加上日志文件名的第一部分组成,例如:

    C:\WINDOWS\system32\LogFiles\W3SVC1\ex100507.log
    

您可能还需要检查Windows事件查看器日志,该日志位于:

  1. 转到“开始”->“控制面板”->“管理工具”

  2. 计算机管理

  3. 事件查看器

警告

如前所述,在IIS中,映射服务器 stderr 调试输出将返回到客户机,而不是路由到Web服务器日志,因此请通过在映射文件中设置以下内容,确保将输出记录到文件中:

CONFIG "MS_ERRORFILE" "/ms4w/tmp/ms_error.txt"

CGI错误-指定的CGI应用程序由于没有返回一组完整的HTTP头而行为错误

此错误通常是由于缺少dll文件造成的。您应该尝试在命令行执行“mapserv-v,以确保mapserver正确加载。

步骤7:验证应用程序设置

如果已验证MapServer通过 Sp2IMG ,您已经检查了MapServer日志文件,并且在Web服务器日志中没有发现任何问题,那么您应该将注意力集中在可能的应用程序配置问题上。”这里的“应用程序”是指如何在网页上显示地图图像,例如 OpenLayers .

步骤8:使用QGIS测试您的OGC服务

When configuring MapServer for OGC services (WMS, WFS, etc.) it sometimes happens that users of your services report map issues in a desktop GIS or online application, even though no errors, logs, or local shp2img tests give any hints; this is where the QGIS Network Logger can really help to get the exact problem request. For steps on how to implement the network logger see here.

小技巧

要获得准确的问题请求,请将您的MapServer服务添加为QGIS层,然后在Network Logger中右键单击该请求,并选择“Open URL”以在浏览器中查看完整的请求和生成的地图图像。

../_images/qgis-network-logger2.png

PHP图形脚本

如果在应用程序中使用php mapscript,以下是调试的一些重要注意事项:

1。确定你的 php.ini 文件配置为通过设置显示所有错误:

display_errors = On
  1. 要在php mapscript中启用调试,如果您使用的是mapserver 5.6.0或更高版本,请确保定义 ZEND_DEBUG 在PHP源中。

    如果使用的是MapServer<5.6.0,则:

    • 打开文件*/mapscript/php3/php_mapscript.c*

    • 更改以下内容:

      #define ZEND_DEBUG 0
      
      to
      
      #define ZEND_DEBUG 1
      

使用编译器调试工具调试MapServer

在gdb中运行mapserver(Linux/Unix)

节作者: Frank Warmerdam

使用符号调试信息生成

为了使用 GDB 在Linux上,但它确实确保在gdb中报告更有意义的信息。要启用完整的符号信息,请使用*--启用调试*配置开关。请注意,使用此开关将禁用优化,因此通常不应将其用于性能重要的生产构建。

./configure --enable-debug <other switches>
make clean
make

在调试器中运行

要运行mapserv或shp2img,请将可执行文件的名称作为“gdb”命令的参数。如果它不在路径中,则需要提供可执行文件的完整路径。

gdb shp2img
GNU gdb (GDB) 7.0-ubuntu
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /wrk/home/warmerda/mapserver/shp2img...done.
(gdb)

在“(gdb)”提示下,可以使用带有参数的run命令,这些参数通常会传递给mapserv或shp2img可执行文件。

(gdb) run -m test.map -o out.png
Starting program: /wrk/home/warmerda/mapserver/shp2img -m test.map -o out.png
[Thread debugging using libthread_db enabled]

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff67594a2 in JP2KAKDataset::Identify (poOpenInfo=0x0)
  at jp2kakdataset.cpp:962
962         if( poOpenInfo->nHeaderBytes < (int) sizeof(jp2_header) )
Current language:  auto
The current source language is "auto; currently c++".
(gdb)

如果程序崩溃,通常会得到一个类似上面的报告,指示崩溃发生的函数,以及一些关于原因的最少信息。请求回溯以查看哪些函数导致崩溃的函数通常很有用。为此,请使用“where”命令。

(gdb) where
#0  0x00007ffff67594a2 in JP2KAKDataset::Identify (poOpenInfo=0x0)
    at jp2kakdataset.cpp:962
#1  0x00007ffff67596d2 in JP2KAKDataset::Open (poOpenInfo=0x7fffffffb6f0)
    at jp2kakdataset.cpp:1025
#2  0x00007ffff6913339 in GDALOpen (
    pszFilename=0x83aa60 "/home/warmerda/data/jpeg2000/spaceimaging_16bit_rgb.jp
2", eAccess=GA_ReadOnly) at gdaldataset.cpp:2170
#3  0x00007ffff69136bf in GDALOpenShared (
    pszFilename=0x83aa60 "/home/warmerda/data/jpeg2000/spaceimaging_16bit_rgb.jp
2", eAccess=GA_ReadOnly) at gdaldataset.cpp:2282
#4  0x0000000000563c2d in msDrawRasterLayerLow (map=0x81e450, layer=0x839140,
    image=0x83af90, rb=0x0) at mapraster.c:566
#5  0x000000000048928f in msDrawRasterLayer (map=0x81e450, layer=0x839140,
    image=0x83af90) at mapdraw.c:1390
#6  0x0000000000486a48 in msDrawLayer (map=0x81e450, layer=0x839140,
    image=0x83af90) at mapdraw.c:806
#7  0x00000000004858fd in msDrawMap (map=0x81e450, querymap=0) at mapdraw.c:459
#8  0x0000000000446410 in main (argc=5, argv=0x7fffffffd918) at shp2img.c:300
(gdb)

检查发生崩溃的行中使用的变量也可能很有帮助。为此使用print命令。

(gdb) print poOpenInfo
$1 = (GDALOpenInfo *) 0x0

在本例中,我们看到程序崩溃,因为poopeninfo为空(零)。在bug报告中包含类似上述的回溯可以帮助开发人员更快地缩小问题范围,特别是在开发人员难以自我复制的情况下。

调试旧版本的MapServer(5.0之前)

  1. 确保mapserver是在调试模式下编译的(在UNIX上,这是通过*./configure--enable debug*启用的)。

    您可以通过在命令行中执行以下操作(查找“debug=msdebug”)来验证您的生成是在调试模式下编译的:

    ./mapserv -v
    
      MapServer version 4.10.2 OUTPUT=GIF OUTPUT=PNG OUTPUT=WBMP
      OUTPUT=SVG SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER
      SUPPORTS=WMS_CLIENT SUPPORTS=WCS_SERVER SUPPORTS=THREADS SUPPORTS=GEOS
      INPUT=EPPL7 INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE
      DEBUG=MSDEBUG
    
  2. 设置 MS_ERRORFILE 变量在映射文件中, MAP 对象,例如:

    MAP
      ...
      CONFIG "MS_ERRORFILE" "/ms4w/tmp/ms_error.txt"
      ...
      LAYER
        ...
      END
    END
    
  3. 如果你不使用 MS_ERRORFILE 变量,您可以在 WEB 映射文件的对象,例如:

     MAP
      ...
      WEB
        LOG "mapserver.log"
      END
      ...
      LAYER
        ...
      END
    END
    
  4. 指定 DEBUG ON 在地图对象中,或在图层对象中,例如:

     MAP
      ...
      WEB
        LOG "mapserver.log"
      END
      DEBUG ON
      ...
      LAYER
        ...
      END
    END
    
  5. 请注意,只有错误才会写入日志文件;对于Apache,所有调试输出都将转到stderr。 error_log 文件。如果使用的是Microsoft IIS,调试输出将路由到 stdout (即浏览器),因此请确保删除 DEBUG ON 语句(如果在生产服务器上使用IIS)。

.