调试MapServer

作者

Jeff McKenna

联系方式

jmckenna at gatewaygeomatics.com

最后更新

2019-06-15

介绍

在为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总是需要绝对路径,因为没有 Mapfile 可以使路径相对于。

stderr

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

stdout

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

windowsdebug

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

通过 Mapfile

建议的设置方法 MS_ERRORFILE 变量在 Mapfile 中, 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 参数在 Mapfile 的任何层中获取特定于层的调试信息,或者相反,在映射对象中设置一次以获取常规调试信息。使用的值 DEBUG 参数设置返回的信息类型,如下所示:

调试级别

0级

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

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

**级别1 **

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

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

**级别2 **

地图调整(调试2)

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

**级别3 **

详细调试(调试3)

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

**级别4 **

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

3级,更详细…

**级别5 **

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

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

Mapfile 示例:映射级别调试

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

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

Mapfile 示例:层级调试

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

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

ms_debuglevel :环境变量

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

设置后,该值将用作所有映射和层对象在 Mapfile 分析器加载时的默认调试级别值。此选项还为位于映射或层对象上下文之外的任何msdebug()调用设置调试级别,例如,为与加载映射之前的初始化相关的调试语句设置调试级别。如果在某些映射或图层对象的 Mapfile 中也指定了调试值,则本地值(在 Mapfile 中)优先于环境变量的值。

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

SetEnv MS_DEBUGLEVEL 5

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

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

MAPServer依赖于 GDAL library to access most data layers, so you may wish to turn on GDAL debugging, to hopefully get more information on how GDAL is accessing your data file. This could be very helpful for problems with accessing raster files and PostGIS tables. You can trigger this GDAL output by setting the CPL_DEBUG variable in your mapfile, within the MAP 对象,例如:

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

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

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

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

步骤5:测试 Mapfile

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

使用SIP2IMG

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

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

注解

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

注解

使用时 shp2img 要进行调试,层的状态应设置为“打开”或“默认”。如果层的状态设置为“关闭”,则必须另外将层名称传递给 shp2img 用“ -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 有问题, shp2img 应输出引起故障的 Mapfile 中的行号。下面告诉我们,我的 Mapfile 的第85行有问题:

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

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

使用mapserv cgi

测试 Mapfile 的另一种简便方法是在 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服务器日志,因此请通过在 Mapfile 中设置以下内容,确保将输出记录到文件中:

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

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

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

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

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

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 变量在 Mapfile 中, MAP 对象,例如:

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

     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)。

.