I use the next code in my plugin (but with gdal_translate) to do that (to remove rows or columns of raster). In this case is specific for my raster of 791 rows and 1680 columns (adapt for your particular situation) to convert it in a raster of 790 rows and 1679 columns (to cut only one row and one column):
import os
rlayer = iface.activeLayer()
#raster layer
provider = rlayer.dataProvider()
input_raster_path = provider.dataSourceUri()
print input_raster_path
xsize = rlayer.rasterUnitsPerPixelX()
ysize = rlayer.rasterUnitsPerPixelY()
extent = rlayer.extent()
xmin_raster = extent.xMinimum()
ymax_raster = extent.yMaximum()
print xmin_raster, ymax_raster
n_rows = 790
n_columns = 1679
row_init = 1
column_init = 1
row_end = row_init + n_rows - 1
column_end = column_init + n_columns - 1
xmin = xmin_raster + (column_init - 1 ) * xsize
xmax = xmin_raster + (column_end) * xsize
ymin = ymax_raster - (row_end) * ysize
ymax = ymax_raster - (row_init - 1) * ysize
extent = " -projwin " + str(xmin) + " " + str(ymax) + " " + str(xmax) + " " + str(ymin) + " "
output_raster_path = "/home/zeito/pyqgis_data/my_clip_layer.tif"
cmd = "gdal_translate " + extent + input_raster_path + " " + output_raster_path
print cmd
os.system(cmd)
After running the code at the Python Console of QGIS, the cut is perfect; as it can be observed at the next image:
